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