blob: 2d7fdcf5f1dcdd0608eef4dfc5605b4c12c46edc [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
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>
Mathias Agopiance51b3b2009-06-07 02:13:02 -070024#include <endian.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080026#include <pixelflinger/pixelflinger.h>
27#include <private/pixelflinger/ggl_fixed.h>
28
29namespace android {
30
31// ----------------------------------------------------------------------------
32
33#if BYTE_ORDER == LITTLE_ENDIAN
34
35inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
36 return v;
37}
38inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
39 return v;
40}
41
42#else
43
44inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
45 return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
46}
47inline 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
55const int GGL_DITHER_BITS = 6; // dither weights stored on 6 bits
56const int GGL_DITHER_ORDER_SHIFT= 3;
57const int GGL_DITHER_ORDER = (1<<GGL_DITHER_ORDER_SHIFT);
58const int GGL_DITHER_SIZE = GGL_DITHER_ORDER * GGL_DITHER_ORDER;
59const int GGL_DITHER_MASK = GGL_DITHER_ORDER-1;
60
61// ----------------------------------------------------------------------------
62
63const 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
88const 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
94inline GGLcolor gglFixedToIteratedColor(GGLfixed c) {
95 return (c << 8) - c;
96}
97
98// ----------------------------------------------------------------------------
99
100template<bool> struct CTA;
101template<> 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
111const int GGL_TEXTURE_UNIT_COUNT = 2;
112const int GGL_TMU_STATE = 0x00000001;
113const int GGL_CB_STATE = 0x00000002;
114const 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
131GGL_RESERVE_NEEDS( CB_FORMAT, 0, 6 )
132GGL_RESERVE_NEEDS( SHADE, 6, 1 )
133GGL_RESERVE_NEEDS( W, 7, 1 )
134GGL_RESERVE_NEEDS( BLEND_SRC, 8, 4 )
135GGL_RESERVE_NEEDS( BLEND_DST, 12, 4 )
136GGL_RESERVE_NEEDS( BLEND_SRCA, 16, 4 )
137GGL_RESERVE_NEEDS( BLEND_DSTA, 20, 4 )
138GGL_RESERVE_NEEDS( LOGIC_OP, 24, 4 )
139GGL_RESERVE_NEEDS( MASK_ARGB, 28, 4 )
140
141GGL_RESERVE_NEEDS( P_ALPHA_TEST, 0, 3 )
142GGL_RESERVE_NEEDS( P_AA, 3, 1 )
143GGL_RESERVE_NEEDS( P_DEPTH_TEST, 4, 3 )
144GGL_RESERVE_NEEDS( P_MASK_Z, 7, 1 )
145GGL_RESERVE_NEEDS( P_DITHER, 8, 1 )
146GGL_RESERVE_NEEDS( P_FOG, 9, 1 )
147GGL_RESERVE_NEEDS( P_RESERVED1, 10,22 )
148
149GGL_RESERVE_NEEDS( T_FORMAT, 0, 6 )
150GGL_RESERVE_NEEDS( T_RESERVED0, 6, 1 )
151GGL_RESERVE_NEEDS( T_POT, 7, 1 )
152GGL_RESERVE_NEEDS( T_S_WRAP, 8, 2 )
153GGL_RESERVE_NEEDS( T_T_WRAP, 10, 2 )
154GGL_RESERVE_NEEDS( T_ENV, 12, 3 )
155GGL_RESERVE_NEEDS( T_LINEAR, 15, 1 )
156
157const int GGL_NEEDS_WRAP_CLAMP_TO_EDGE = 0;
158const int GGL_NEEDS_WRAP_REPEAT = 1;
159const int GGL_NEEDS_WRAP_11 = 2;
160
161inline 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
169inline uint32_t ggl_blendfactor_to_needs(uint32_t b) {
170 if (b <= 1) return b;
171 return (b & 0xF)+2;
172}
173
174inline uint32_t ggl_needs_to_blendfactor(uint32_t n) {
175 if (n <= 1) return n;
176 return (n - 2) + 0x300;
177}
178
179inline 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
190inline 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
199enum {
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
217class needs_filter_t;
218struct 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
234inline int compare_type(const needs_t& lhs, const needs_t& rhs) {
235 return memcmp(&lhs, &rhs, sizeof(needs_t));
236}
237
238struct needs_filter_t {
239 needs_t value;
240 needs_t mask;
241};
242
243int 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
254struct context_t;
255class Assembly;
256
257struct 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
268struct mask_state_t {
269 uint8_t color;
270 uint8_t depth;
271 uint32_t stencil;
272};
273
274struct 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
287struct fog_state_t {
Mathias Agopianfa36f2c2010-02-16 21:01:12 -0800288 uint8_t color[4];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800289};
290
291struct logic_op_state_t {
292 uint16_t opcode;
293};
294
295struct alpha_test_state_t {
296 uint16_t func;
297 GGLcolor ref;
298};
299
300struct depth_test_state_t {
301 uint16_t func;
302 GGLclampx clearValue;
303};
304
305struct 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
316struct pixel_t {
317 uint32_t c[4];
318 uint8_t s[4];
319};
320
321struct 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
343struct 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
364struct 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
387struct 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
403struct raster_t {
404 GGLfixed x;
405 GGLfixed y;
406};
407
408struct 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
419struct 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
432struct 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
459struct 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
469struct 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
487struct 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
506struct 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
533void ggl_init_context(context_t* context);
534void ggl_uninit_context(context_t* context);
535void ggl_error(context_t* c, GGLenum error);
536int64_t ggl_system_time();
537
538// ----------------------------------------------------------------------------
539
540};
541
542#endif // ANDROID_GGL_CONTEXT_H
543