1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_GGL_CONTEXT_H
18 #define ANDROID_GGL_CONTEXT_H
19
20 #include <stdint.h>
21 #include <stddef.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <endian.h>
25
26 #include <pixelflinger/pixelflinger.h>
27 #include <private/pixelflinger/ggl_fixed.h>
28
29 namespace android {
30
31 // ----------------------------------------------------------------------------
32
33 #if BYTE_ORDER == LITTLE_ENDIAN
34
GGL_RGBA_TO_HOST(uint32_t v)35 inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
36 return v;
37 }
GGL_HOST_TO_RGBA(uint32_t v)38 inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
39 return v;
40 }
41
42 #else
43
44 inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
45 return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
46 }
47 inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
48 return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
49 }
50
51 #endif
52
53 // ----------------------------------------------------------------------------
54
55 const int GGL_DITHER_BITS = 6; // dither weights stored on 6 bits
56 const int GGL_DITHER_ORDER_SHIFT= 3;
57 const int GGL_DITHER_ORDER = (1<<GGL_DITHER_ORDER_SHIFT);
58 const int GGL_DITHER_SIZE = GGL_DITHER_ORDER * GGL_DITHER_ORDER;
59 const int GGL_DITHER_MASK = GGL_DITHER_ORDER-1;
60
61 // ----------------------------------------------------------------------------
62
63 const int GGL_SUBPIXEL_BITS = 4;
64
65 // TRI_FRACTION_BITS defines the number of bits we want to use
66 // for the sub-pixel coordinates during the edge stepping, the
67 // value shouldn't be more than 7, or bad things are going to
68 // happen when drawing large triangles (8 doesn't work because
69 // 32 bit muls will loose the sign bit)
70
71 #define TRI_FRACTION_BITS (GGL_SUBPIXEL_BITS)
72 #define TRI_ONE (1 << TRI_FRACTION_BITS)
73 #define TRI_HALF (1 << (TRI_FRACTION_BITS-1))
74 #define TRI_FROM_INT(x) ((x) << TRI_FRACTION_BITS)
75 #define TRI_FRAC(x) ((x) & (TRI_ONE-1))
76 #define TRI_FLOOR(x) ((x) & ~(TRI_ONE-1))
77 #define TRI_CEIL(x) (((x) + (TRI_ONE-1)) & ~(TRI_ONE-1))
78 #define TRI_ROUND(x) (((x) + TRI_HALF ) & ~(TRI_ONE-1))
79
80 #define TRI_ROUDNING (1 << (16 - TRI_FRACTION_BITS - 1))
81 #define TRI_FROM_FIXED(x) (((x)+TRI_ROUDNING) >> (16-TRI_FRACTION_BITS))
82
83 #define TRI_SNAP_NEXT_HALF(x) (TRI_CEIL((x)+TRI_HALF) - TRI_HALF)
84 #define TRI_SNAP_PREV_HALF(x) (TRI_CEIL((x)-TRI_HALF) - TRI_HALF)
85
86 // ----------------------------------------------------------------------------
87
88 const int GGL_COLOR_BITS = 24;
89
90 // To maintain 8-bits color chanels, with a maximum GGLSurface
91 // size of 4096 and GGL_SUBPIXEL_BITS=4, we need 8 + 12 + 4 = 24 bits
92 // for encoding the color iterators
93
gglFixedToIteratedColor(GGLfixed c)94 inline GGLcolor gglFixedToIteratedColor(GGLfixed c) {
95 return (c << 8) - c;
96 }
97
98 // ----------------------------------------------------------------------------
99
100 template<bool> struct CTA;
101 template<> struct CTA<true> { };
102
103 #define GGL_CONTEXT(con, c) context_t *con = static_cast<context_t *>(c)
104 #define GGL_OFFSETOF(field) int(&(((context_t*)0)->field))
105 #define GGL_INIT_PROC(p, f) p.f = ggl_ ## f;
106 #define GGL_BETWEEN(x, L, H) (uint32_t((x)-(L)) <= ((H)-(L)))
107
108 #define ggl_likely(x) __builtin_expect(!!(x), 1)
109 #define ggl_unlikely(x) __builtin_expect(!!(x), 0)
110
111 const int GGL_TEXTURE_UNIT_COUNT = 2;
112 const int GGL_TMU_STATE = 0x00000001;
113 const int GGL_CB_STATE = 0x00000002;
114 const int GGL_PIXEL_PIPELINE_STATE = 0x00000004;
115
116 // ----------------------------------------------------------------------------
117
118 #define GGL_RESERVE_NEEDS(name, l, s) \
119 const uint32_t GGL_NEEDS_##name##_MASK = (((1LU<<(s))-1)<<l); \
120 const uint32_t GGL_NEEDS_##name##_SHIFT = (l);
121
122 #define GGL_BUILD_NEEDS(val, name) \
123 (((val)<<(GGL_NEEDS_##name##_SHIFT)) & GGL_NEEDS_##name##_MASK)
124
125 #define GGL_READ_NEEDS(name, n) \
126 (uint32_t(n & GGL_NEEDS_##name##_MASK) >> GGL_NEEDS_##name##_SHIFT)
127
128 #define GGL_NEED_MASK(name) (uint32_t(GGL_NEEDS_##name##_MASK))
129 #define GGL_NEED(name, val) GGL_BUILD_NEEDS(val, name)
130
131 GGL_RESERVE_NEEDS( CB_FORMAT, 0, 6 )
132 GGL_RESERVE_NEEDS( SHADE, 6, 1 )
133 GGL_RESERVE_NEEDS( W, 7, 1 )
134 GGL_RESERVE_NEEDS( BLEND_SRC, 8, 4 )
135 GGL_RESERVE_NEEDS( BLEND_DST, 12, 4 )
136 GGL_RESERVE_NEEDS( BLEND_SRCA, 16, 4 )
137 GGL_RESERVE_NEEDS( BLEND_DSTA, 20, 4 )
138 GGL_RESERVE_NEEDS( LOGIC_OP, 24, 4 )
139 GGL_RESERVE_NEEDS( MASK_ARGB, 28, 4 )
140
141 GGL_RESERVE_NEEDS( P_ALPHA_TEST, 0, 3 )
142 GGL_RESERVE_NEEDS( P_AA, 3, 1 )
143 GGL_RESERVE_NEEDS( P_DEPTH_TEST, 4, 3 )
144 GGL_RESERVE_NEEDS( P_MASK_Z, 7, 1 )
145 GGL_RESERVE_NEEDS( P_DITHER, 8, 1 )
146 GGL_RESERVE_NEEDS( P_FOG, 9, 1 )
147 GGL_RESERVE_NEEDS( P_RESERVED1, 10,22 )
148
149 GGL_RESERVE_NEEDS( T_FORMAT, 0, 6 )
150 GGL_RESERVE_NEEDS( T_RESERVED0, 6, 1 )
151 GGL_RESERVE_NEEDS( T_POT, 7, 1 )
152 GGL_RESERVE_NEEDS( T_S_WRAP, 8, 2 )
153 GGL_RESERVE_NEEDS( T_T_WRAP, 10, 2 )
154 GGL_RESERVE_NEEDS( T_ENV, 12, 3 )
155 GGL_RESERVE_NEEDS( T_LINEAR, 15, 1 )
156
157 const int GGL_NEEDS_WRAP_CLAMP_TO_EDGE = 0;
158 const int GGL_NEEDS_WRAP_REPEAT = 1;
159 const int GGL_NEEDS_WRAP_11 = 2;
160
161 inline uint32_t ggl_wrap_to_needs(uint32_t e) {
162 switch (e) {
163 case GGL_CLAMP: return GGL_NEEDS_WRAP_CLAMP_TO_EDGE;
164 case GGL_REPEAT: return GGL_NEEDS_WRAP_REPEAT;
165 }
166 return 0;
167 }
168
169 inline uint32_t ggl_blendfactor_to_needs(uint32_t b) {
170 if (b <= 1) return b;
171 return (b & 0xF)+2;
172 }
173
174 inline uint32_t ggl_needs_to_blendfactor(uint32_t n) {
175 if (n <= 1) return n;
176 return (n - 2) + 0x300;
177 }
178
179 inline uint32_t ggl_env_to_needs(uint32_t e) {
180 switch (e) {
181 case GGL_REPLACE: return 0;
182 case GGL_MODULATE: return 1;
183 case GGL_DECAL: return 2;
184 case GGL_BLEND: return 3;
185 case GGL_ADD: return 4;
186 }
187 return 0;
188 }
189
190 inline uint32_t ggl_needs_to_env(uint32_t n) {
191 const uint32_t envs[] = { GGL_REPLACE, GGL_MODULATE,
192 GGL_DECAL, GGL_BLEND, GGL_ADD };
193 return envs[n];
194
195 }
196
197 // ----------------------------------------------------------------------------
198
199 enum {
200 GGL_ENABLE_BLENDING = 0x00000001,
201 GGL_ENABLE_SMOOTH = 0x00000002,
202 GGL_ENABLE_AA = 0x00000004,
203 GGL_ENABLE_LOGIC_OP = 0x00000008,
204 GGL_ENABLE_ALPHA_TEST = 0x00000010,
205 GGL_ENABLE_SCISSOR_TEST = 0x00000020,
206 GGL_ENABLE_TMUS = 0x00000040,
207 GGL_ENABLE_DEPTH_TEST = 0x00000080,
208 GGL_ENABLE_STENCIL_TEST = 0x00000100,
209 GGL_ENABLE_W = 0x00000200,
210 GGL_ENABLE_DITHER = 0x00000400,
211 GGL_ENABLE_FOG = 0x00000800,
212 GGL_ENABLE_POINT_AA_NICE= 0x00001000
213 };
214
215 // ----------------------------------------------------------------------------
216
217 class needs_filter_t;
218 struct needs_t {
219 inline int match(const needs_filter_t& filter);
220 inline bool operator == (const needs_t& rhs) const {
221 return (n==rhs.n) &&
222 (p==rhs.p) &&
223 (t[0]==rhs.t[0]) &&
224 (t[1]==rhs.t[1]);
225 }
226 inline bool operator != (const needs_t& rhs) const {
227 return !operator == (rhs);
228 }
229 uint32_t n;
230 uint32_t p;
231 uint32_t t[GGL_TEXTURE_UNIT_COUNT];
232 };
233
234 inline int compare_type(const needs_t& lhs, const needs_t& rhs) {
235 return memcmp(&lhs, &rhs, sizeof(needs_t));
236 }
237
238 struct needs_filter_t {
239 needs_t value;
240 needs_t mask;
241 };
242
243 int needs_t::match(const needs_filter_t& filter) {
244 uint32_t result =
245 ((filter.value.n ^ n) & filter.mask.n) |
246 ((filter.value.p ^ p) & filter.mask.p) |
247 ((filter.value.t[0] ^ t[0]) & filter.mask.t[0]) |
248 ((filter.value.t[1] ^ t[1]) & filter.mask.t[1]);
249 return (result == 0);
250 }
251
252 // ----------------------------------------------------------------------------
253
254 struct context_t;
255 class Assembly;
256
257 struct blend_state_t {
258 uint32_t src;
259 uint32_t dst;
260 uint32_t src_alpha;
261 uint32_t dst_alpha;
262 uint8_t reserved;
263 uint8_t alpha_separate;
264 uint8_t operation;
265 uint8_t equation;
266 };
267
268 struct mask_state_t {
269 uint8_t color;
270 uint8_t depth;
271 uint32_t stencil;
272 };
273
274 struct clear_state_t {
275 GGLclampx r;
276 GGLclampx g;
277 GGLclampx b;
278 GGLclampx a;
279 GGLclampx depth;
280 GGLint stencil;
281 uint32_t colorPacked;
282 uint32_t depthPacked;
283 uint32_t stencilPacked;
284 uint32_t dirty;
285 };
286
287 struct fog_state_t {
288 uint8_t color[4];
289 };
290
291 struct logic_op_state_t {
292 uint16_t opcode;
293 };
294
295 struct alpha_test_state_t {
296 uint16_t func;
297 GGLcolor ref;
298 };
299
300 struct depth_test_state_t {
301 uint16_t func;
302 GGLclampx clearValue;
303 };
304
305 struct scissor_t {
306 uint32_t user_left;
307 uint32_t user_right;
308 uint32_t user_top;
309 uint32_t user_bottom;
310 uint32_t left;
311 uint32_t right;
312 uint32_t top;
313 uint32_t bottom;
314 };
315
316 struct pixel_t {
317 uint32_t c[4];
318 uint8_t s[4];
319 };
320
321 struct surface_t {
322 union {
323 GGLSurface s;
324 struct {
325 uint32_t reserved;
326 uint32_t width;
327 uint32_t height;
328 int32_t stride;
329 uint8_t* data;
330 uint8_t format;
331 uint8_t dirty;
332 uint8_t pad[2];
333 };
334 };
335 void (*read) (const surface_t* s, context_t* c,
336 uint32_t x, uint32_t y, pixel_t* pixel);
337 void (*write)(const surface_t* s, context_t* c,
338 uint32_t x, uint32_t y, const pixel_t* pixel);
339 };
340
341 // ----------------------------------------------------------------------------
342
343 struct texture_shade_t {
344 union {
345 struct {
346 int32_t is0;
347 int32_t idsdx;
348 int32_t idsdy;
349 int sscale;
350 int32_t it0;
351 int32_t idtdx;
352 int32_t idtdy;
353 int tscale;
354 };
355 struct {
356 int32_t v;
357 int32_t dx;
358 int32_t dy;
359 int scale;
360 } st[2];
361 };
362 };
363
364 struct texture_iterators_t {
365 // these are not encoded in the same way than in the
366 // texture_shade_t structure
367 union {
368 struct {
369 GGLfixed ydsdy;
370 GGLfixed dsdx;
371 GGLfixed dsdy;
372 int sscale;
373 GGLfixed ydtdy;
374 GGLfixed dtdx;
375 GGLfixed dtdy;
376 int tscale;
377 };
378 struct {
379 GGLfixed ydvdy;
380 GGLfixed dvdx;
381 GGLfixed dvdy;
382 int scale;
383 } st[2];
384 };
385 };
386
387 struct texture_t {
388 surface_t surface;
389 texture_iterators_t iterators;
390 texture_shade_t shade;
391 uint32_t s_coord;
392 uint32_t t_coord;
393 uint16_t s_wrap;
394 uint16_t t_wrap;
395 uint16_t min_filter;
396 uint16_t mag_filter;
397 uint16_t env;
398 uint8_t env_color[4];
399 uint8_t enable;
400 uint8_t dirty;
401 };
402
403 struct raster_t {
404 GGLfixed x;
405 GGLfixed y;
406 };
407
408 struct framebuffer_t {
409 surface_t color;
410 surface_t read;
411 surface_t depth;
412 surface_t stencil;
413 int16_t *coverage;
414 size_t coverageBufferSize;
415 };
416
417 // ----------------------------------------------------------------------------
418
419 struct iterators_t {
420 int32_t xl;
421 int32_t xr;
422 int32_t y;
423 GGLcolor ydady;
424 GGLcolor ydrdy;
425 GGLcolor ydgdy;
426 GGLcolor ydbdy;
427 GGLfixed ydzdy;
428 GGLfixed ydwdy;
429 GGLfixed ydfdy;
430 };
431
432 struct shade_t {
433 GGLcolor a0;
434 GGLcolor dadx;
435 GGLcolor dady;
436 GGLcolor r0;
437 GGLcolor drdx;
438 GGLcolor drdy;
439 GGLcolor g0;
440 GGLcolor dgdx;
441 GGLcolor dgdy;
442 GGLcolor b0;
443 GGLcolor dbdx;
444 GGLcolor dbdy;
445 uint32_t z0;
446 GGLfixed32 dzdx;
447 GGLfixed32 dzdy;
448 GGLfixed w0;
449 GGLfixed dwdx;
450 GGLfixed dwdy;
451 uint32_t f0;
452 GGLfixed dfdx;
453 GGLfixed dfdy;
454 };
455
456 // these are used in the generated code
457 // we use this mirror structure to improve
458 // data locality in the pixel pipeline
459 struct generated_tex_vars_t {
460 uint32_t width;
461 uint32_t height;
462 uint32_t stride;
463 int32_t data;
464 int32_t dsdx;
465 int32_t dtdx;
466 int32_t spill[2];
467 };
468
469 struct generated_vars_t {
470 struct {
471 int32_t c;
472 int32_t dx;
473 } argb[4];
474 int32_t aref;
475 int32_t dzdx;
476 int32_t zbase;
477 int32_t f;
478 int32_t dfdx;
479 int32_t spill[3];
480 generated_tex_vars_t texture[GGL_TEXTURE_UNIT_COUNT];
481 int32_t rt;
482 int32_t lb;
483 };
484
485 // ----------------------------------------------------------------------------
486
487 struct state_t {
488 framebuffer_t buffers;
489 texture_t texture[GGL_TEXTURE_UNIT_COUNT];
490 scissor_t scissor;
491 raster_t raster;
492 blend_state_t blend;
493 alpha_test_state_t alpha_test;
494 depth_test_state_t depth_test;
495 mask_state_t mask;
496 clear_state_t clear;
497 fog_state_t fog;
498 logic_op_state_t logic_op;
499 uint32_t enables;
500 uint32_t enabled_tmu;
501 needs_t needs;
502 };
503
504 // ----------------------------------------------------------------------------
505
506 struct context_t {
507 GGLContext procs;
508 state_t state;
509 shade_t shade;
510 iterators_t iterators;
511 generated_vars_t generated_vars __attribute__((aligned(32)));
512 uint8_t ditherMatrix[GGL_DITHER_SIZE] __attribute__((aligned(32)));
513 uint32_t packed;
514 uint32_t packed8888;
515 const GGLFormat* formats;
516 uint32_t dirty;
517 texture_t* activeTMU;
518 uint32_t activeTMUIndex;
519
520 void (*init_y)(context_t* c, int32_t y);
521 void (*step_y)(context_t* c);
522 void (*scanline)(context_t* c);
523 void (*span)(context_t* c);
524 void (*rect)(context_t* c, size_t yc);
525
526 void* base;
527 Assembly* scanline_as;
528 GGLenum error;
529 };
530
531 // ----------------------------------------------------------------------------
532
533 void ggl_init_context(context_t* context);
534 void ggl_uninit_context(context_t* context);
535 void ggl_error(context_t* c, GGLenum error);
536 int64_t ggl_system_time();
537
538 // ----------------------------------------------------------------------------
539
540 };
541
542 #endif // ANDROID_GGL_CONTEXT_H
543
544