context.h revision 444839b842798497cfa326204285a4f2ca2362af
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_OPENGLES_CONTEXT_H
18#define ANDROID_OPENGLES_CONTEXT_H
19
20#include <stdint.h>
21#include <stddef.h>
22#include <sys/types.h>
23#include <pthread.h>
24#ifdef HAVE_ANDROID_OS
25#include <bionic_tls.h>
26#endif
27
28#include <private/pixelflinger/ggl_context.h>
29#include <hardware/gralloc.h>
30
31#include <GLES/gl.h>
32#include <GLES/glext.h>
33
34namespace android {
35
36
37const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
38#ifdef GL_OES_compressed_ETC1_RGB8_texture
39        + 1
40#endif
41        ;
42
43class EGLTextureObject;
44class EGLSurfaceManager;
45class EGLBufferObjectManager;
46
47namespace gl {
48
49struct ogles_context_t;
50struct matrixx_t;
51struct transform_t;
52struct buffer_t;
53
54ogles_context_t* getGlContext();
55
56template<typename T>
57static inline void swap(T& a, T& b) {
58    T t(a); a = b; b = t;
59}
60template<typename T>
61inline T max(T a, T b) {
62    return a<b ? b : a;
63}
64template<typename T>
65inline T max(T a, T b, T c) {
66    return max(a, max(b, c));
67}
68template<typename T>
69inline T min(T a, T b) {
70    return a<b ? a : b;
71}
72template<typename T>
73inline T min(T a, T b, T c) {
74    return min(a, min(b, c));
75}
76template<typename T>
77inline T min(T a, T b, T c, T d) {
78    return min(min(a,b), min(c,d));
79}
80
81// ----------------------------------------------------------------------------
82// vertices
83// ----------------------------------------------------------------------------
84
85struct vec3_t {
86    union {
87        struct { GLfixed x, y, z; };
88        struct { GLfixed r, g, b; };
89        struct { GLfixed S, T, R; };
90        GLfixed v[3];
91    };
92};
93
94struct vec4_t {
95    union {
96        struct { GLfixed x, y, z, w; };
97        struct { GLfixed r, g, b, a; };
98        struct { GLfixed S, T, R, Q; };
99        GLfixed v[4];
100    };
101};
102
103struct vertex_t {
104    enum {
105        // these constant matter for our clipping
106        CLIP_L          = 0x0001,   // clipping flags
107        CLIP_R          = 0x0002,
108        CLIP_B          = 0x0004,
109        CLIP_T          = 0x0008,
110        CLIP_N          = 0x0010,
111        CLIP_F          = 0x0020,
112
113        EYE             = 0x0040,
114        RESERVED        = 0x0080,
115
116        USER_CLIP_0     = 0x0100,   // user clipping flags
117        USER_CLIP_1     = 0x0200,
118        USER_CLIP_2     = 0x0400,
119        USER_CLIP_3     = 0x0800,
120        USER_CLIP_4     = 0x1000,
121        USER_CLIP_5     = 0x2000,
122
123        LIT             = 0x4000,   // lighting has been applied
124        TT              = 0x8000,   // texture coords transformed
125
126        FRUSTUM_CLIP_ALL= 0x003F,
127        USER_CLIP_ALL   = 0x3F00,
128        CLIP_ALL        = 0x3F3F,
129    };
130
131    // the fields below are arranged to minimize d-cache usage
132    // we group together, by cache-line, the fields most likely to be used
133
134    union {
135    vec4_t          obj;
136    vec4_t          eye;
137    };
138    vec4_t          clip;
139
140    uint32_t        flags;
141    size_t          index;  // cache tag, and vertex index
142    GLfixed         fog;
143    uint8_t         locked;
144    uint8_t         mru;
145    uint8_t         reserved[2];
146    vec4_t          window;
147
148    vec4_t          color;
149    vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
150#ifdef __LP64__
151    uint32_t        reserved1[2];
152#else
153    uint32_t        reserved1[4];
154#endif
155
156    inline void clear() {
157        flags = index = locked = mru = 0;
158    }
159};
160
161struct point_size_t {
162    GGLcoord    size;
163    GLboolean   smooth;
164};
165
166struct line_width_t {
167    GGLcoord    width;
168    GLboolean   smooth;
169};
170
171struct polygon_offset_t {
172    GLfixed     factor;
173    GLfixed     units;
174    GLboolean   enable;
175};
176
177// ----------------------------------------------------------------------------
178// arrays
179// ----------------------------------------------------------------------------
180
181struct array_t {
182    typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
183    fetcher_t       fetch;
184    GLvoid const*   physical_pointer;
185    GLint           size;
186    GLsizei         stride;
187    GLvoid const*   pointer;
188    buffer_t const* bo;
189    uint16_t        type;
190    GLboolean       enable;
191    GLboolean       pad;
192    GLsizei         bounds;
193    void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
194    inline void resolve();
195    inline const GLubyte* element(GLint i) const {
196        return (const GLubyte*)physical_pointer + i * stride;
197    }
198};
199
200struct array_machine_t {
201    array_t         vertex;
202    array_t         normal;
203    array_t         color;
204    array_t         texture[GGL_TEXTURE_UNIT_COUNT];
205    uint8_t         activeTexture;
206    uint8_t         tmu;
207    uint16_t        cull;
208    uint32_t        flags;
209    GLenum          indicesType;
210    buffer_t const* array_buffer;
211    buffer_t const* element_array_buffer;
212
213    void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
214    void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
215
216    void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
217    void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
218    void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
219    void (*perspective)(ogles_context_t*c, vertex_t* v);
220    void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
221            GGLfixed t, const vertex_t* s, const vertex_t* p);
222    void (*clipEye)(ogles_context_t* c, vertex_t* nv,
223            GGLfixed t, const vertex_t* s, const vertex_t* p);
224};
225
226struct vertex_cache_t {
227    enum {
228        // must be at least 4
229        // 3 vertice for triangles
230        // or 2 + 2 for indexed triangles w/ cache contention
231        VERTEX_BUFFER_SIZE  = 8,
232        // must be a power of two and at least 3
233        VERTEX_CACHE_SIZE   = 64,   // 8 KB
234
235        INDEX_BITS      = 16,
236        INDEX_MASK      = ((1LU<<INDEX_BITS)-1),
237        INDEX_SEQ       = 1LU<<INDEX_BITS,
238    };
239    vertex_t*       vBuffer;
240    vertex_t*       vCache;
241    uint32_t        sequence;
242    void*           base;
243    uint32_t        total;
244    uint32_t        misses;
245    int64_t         startTime;
246    void init();
247    void uninit();
248    void clear();
249    void dump_stats(GLenum mode);
250};
251
252// ----------------------------------------------------------------------------
253// fog
254// ----------------------------------------------------------------------------
255
256struct fog_t {
257    GLfixed     density;
258    GLfixed     start;
259    GLfixed     end;
260    GLfixed     invEndMinusStart;
261    GLenum      mode;
262    GLfixed     (*fog)(ogles_context_t* c, GLfixed z);
263};
264
265// ----------------------------------------------------------------------------
266// user clip planes
267// ----------------------------------------------------------------------------
268
269const unsigned int OGLES_MAX_CLIP_PLANES = 6;
270
271struct clip_plane_t {
272    vec4_t      equation;
273};
274
275struct user_clip_planes_t {
276    clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
277    uint32_t        enable;
278};
279
280// ----------------------------------------------------------------------------
281// lighting
282// ----------------------------------------------------------------------------
283
284const unsigned int OGLES_MAX_LIGHTS = 8;
285
286struct light_t {
287    vec4_t      ambient;
288    vec4_t      diffuse;
289    vec4_t      specular;
290    vec4_t      implicitAmbient;
291    vec4_t      implicitDiffuse;
292    vec4_t      implicitSpecular;
293    vec4_t      position;       // position in eye space
294    vec4_t      objPosition;
295    vec4_t      normalizedObjPosition;
296    vec4_t      spotDir;
297    vec4_t      normalizedSpotDir;
298    GLfixed     spotExp;
299    GLfixed     spotCutoff;
300    GLfixed     spotCutoffCosine;
301    GLfixed     attenuation[3];
302    GLfixed     rConstAttenuation;
303    GLboolean   enable;
304};
305
306struct material_t {
307    vec4_t      ambient;
308    vec4_t      diffuse;
309    vec4_t      specular;
310    vec4_t      emission;
311    GLfixed     shininess;
312};
313
314struct light_model_t {
315    vec4_t      ambient;
316    GLboolean   twoSide;
317};
318
319struct color_material_t {
320    GLenum      face;
321    GLenum      mode;
322    GLboolean   enable;
323};
324
325struct lighting_t {
326    light_t             lights[OGLES_MAX_LIGHTS];
327    material_t          front;
328    light_model_t       lightModel;
329    color_material_t    colorMaterial;
330    vec4_t              implicitSceneEmissionAndAmbient;
331    vec4_t              objViewer;
332    uint32_t            enabledLights;
333    GLboolean           enable;
334    GLenum              shadeModel;
335    typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
336    void (*lightVertex)(ogles_context_t* c, vertex_t* v);
337    void (*lightTriangle)(ogles_context_t* c,
338            vertex_t* v0, vertex_t* v1, vertex_t* v2);
339};
340
341struct culling_t {
342    GLenum      cullFace;
343    GLenum      frontFace;
344    GLboolean   enable;
345};
346
347// ----------------------------------------------------------------------------
348// textures
349// ----------------------------------------------------------------------------
350
351struct texture_unit_t {
352    GLuint              name;
353    EGLTextureObject*   texture;
354    uint8_t             dirty;
355};
356
357struct texture_state_t
358{
359    texture_unit_t      tmu[GGL_TEXTURE_UNIT_COUNT];
360    int                 active;     // active tmu
361    EGLTextureObject*   defaultTexture;
362    GGLContext*         ggl;
363    uint8_t             packAlignment;
364    uint8_t             unpackAlignment;
365};
366
367// ----------------------------------------------------------------------------
368// transformation and matrices
369// ----------------------------------------------------------------------------
370
371struct matrixf_t;
372
373struct matrixx_t {
374    GLfixed m[16];
375    void load(const matrixf_t& rhs);
376};
377
378struct matrix_stack_t;
379
380
381struct matrixf_t {
382    void loadIdentity();
383    void load(const matrixf_t& rhs);
384
385    inline GLfloat* editElements() { return m; }
386    inline GLfloat const* elements() const { return m; }
387
388    void set(const GLfixed* rhs);
389    void set(const GLfloat* rhs);
390
391    static void multiply(matrixf_t& r,
392            const matrixf_t& lhs, const matrixf_t& rhs);
393
394    void dump(const char* what);
395
396private:
397    friend struct matrix_stack_t;
398    GLfloat     m[16];
399    void load(const GLfixed* rhs);
400    void load(const GLfloat* rhs);
401    void multiply(const matrixf_t& rhs);
402    void translate(GLfloat x, GLfloat y, GLfloat z);
403    void scale(GLfloat x, GLfloat y, GLfloat z);
404    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
405};
406
407enum {
408    OP_IDENTITY         = 0x00,
409    OP_TRANSLATE        = 0x01,
410    OP_UNIFORM_SCALE    = 0x02,
411    OP_SCALE            = 0x05,
412    OP_ROTATE           = 0x08,
413    OP_SKEW             = 0x10,
414    OP_ALL              = 0x1F
415};
416
417struct transform_t {
418    enum {
419        FLAGS_2D_PROJECTION = 0x1
420    };
421    matrixx_t       matrix;
422    uint32_t        flags;
423    uint32_t        ops;
424
425    union {
426        struct {
427            void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
428            void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
429            void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
430        };
431        void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
432    };
433
434    void loadIdentity();
435    void picker();
436    void dump(const char* what);
437};
438
439struct mvui_transform_t : public transform_t
440{
441    void picker();
442};
443
444struct matrix_stack_t {
445    enum {
446        DO_PICKER           = 0x1,
447        DO_FLOAT_TO_FIXED   = 0x2
448    };
449    transform_t     transform;
450    uint8_t         maxDepth;
451    uint8_t         depth;
452    uint8_t         dirty;
453    uint8_t         reserved;
454    matrixf_t       *stack;
455    uint8_t         *ops;
456    void init(int depth);
457    void uninit();
458    void loadIdentity();
459    void load(const GLfixed* rhs);
460    void load(const GLfloat* rhs);
461    void multiply(const matrixf_t& rhs);
462    void translate(GLfloat x, GLfloat y, GLfloat z);
463    void scale(GLfloat x, GLfloat y, GLfloat z);
464    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
465    GLint push();
466    GLint pop();
467    void validate();
468    matrixf_t& top() { return stack[depth]; }
469    const matrixf_t& top() const { return stack[depth]; }
470    uint32_t top_ops() const { return ops[depth]; }
471    inline bool isRigidBody() const {
472        return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
473    }
474};
475
476struct vp_transform_t {
477    transform_t     transform;
478    matrixf_t       matrix;
479    GLfloat         zNear;
480    GLfloat         zFar;
481    void loadIdentity();
482};
483
484struct transform_state_t {
485    enum {
486        MODELVIEW           = 0x01,
487        PROJECTION          = 0x02,
488        VIEWPORT            = 0x04,
489        TEXTURE             = 0x08,
490        MVUI                = 0x10,
491        MVIT                = 0x20,
492        MVP                 = 0x40,
493    };
494    matrix_stack_t      *current;
495    matrix_stack_t      modelview;
496    matrix_stack_t      projection;
497    matrix_stack_t      texture[GGL_TEXTURE_UNIT_COUNT];
498
499    // modelview * projection
500    transform_t         mvp     __attribute__((aligned(32)));
501    // viewport transformation
502    vp_transform_t      vpt     __attribute__((aligned(32)));
503    // same for 4-D vertices
504    transform_t         mvp4;
505    // full modelview inverse transpose
506    transform_t         mvit4;
507    // upper 3x3 of mv-inverse-transpose (for normals)
508    mvui_transform_t    mvui;
509
510    GLenum              matrixMode;
511    GLenum              rescaleNormals;
512    uint32_t            dirty;
513    void invalidate();
514    void update_mvp();
515    void update_mvit();
516    void update_mvui();
517};
518
519struct viewport_t {
520    GLint       x;
521    GLint       y;
522    GLsizei     w;
523    GLsizei     h;
524    struct {
525        GLint       x;
526        GLint       y;
527    } surfaceport;
528    struct {
529        GLint       x;
530        GLint       y;
531        GLsizei     w;
532        GLsizei     h;
533    } scissor;
534};
535
536// ----------------------------------------------------------------------------
537// Lerping
538// ----------------------------------------------------------------------------
539
540struct compute_iterators_t
541{
542    void initTriangle(
543            vertex_t const* v0,
544            vertex_t const* v1,
545            vertex_t const* v2);
546
547    void initLine(
548            vertex_t const* v0,
549            vertex_t const* v1);
550
551    inline void initLerp(vertex_t const* v0, uint32_t enables);
552
553    int iteratorsScale(int32_t it[3],
554            int32_t c0, int32_t c1, int32_t c2) const;
555
556    void iterators1616(GGLfixed it[3],
557            GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
558
559    void iterators0032(int32_t it[3],
560            int32_t c0, int32_t c1, int32_t c2) const;
561
562    void iterators0032(int64_t it[3],
563            int32_t c0, int32_t c1, int32_t c2) const;
564
565    GGLcoord area() const { return m_area; }
566
567private:
568    // don't change order of members here -- used by iterators.S
569    GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
570    GGLcoord m_x0, m_y0;
571    GGLcoord m_area;
572    uint8_t m_scale;
573    uint8_t m_area_scale;
574    uint8_t m_reserved[2];
575
576};
577
578// ----------------------------------------------------------------------------
579// state
580// ----------------------------------------------------------------------------
581
582#ifdef HAVE_ANDROID_OS
583    // We have a dedicated TLS slot in bionic
584    inline void setGlThreadSpecific(ogles_context_t *value) {
585        __get_tls()[TLS_SLOT_OPENGL] = value;
586    }
587    inline ogles_context_t* getGlThreadSpecific() {
588        return static_cast<ogles_context_t*>(__get_tls()[TLS_SLOT_OPENGL]);
589    }
590#else
591    extern pthread_key_t gGLKey;
592    inline void setGlThreadSpecific(ogles_context_t *value) {
593        pthread_setspecific(gGLKey, value);
594    }
595    inline ogles_context_t* getGlThreadSpecific() {
596        return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
597    }
598#endif
599
600
601struct prims_t {
602    typedef ogles_context_t* GL;
603    void (*renderPoint)(GL, vertex_t*);
604    void (*renderLine)(GL, vertex_t*, vertex_t*);
605    void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
606};
607
608struct ogles_context_t {
609    context_t               rasterizer;
610    array_machine_t         arrays         __attribute__((aligned(32)));
611    texture_state_t         textures;
612    transform_state_t       transforms;
613    vertex_cache_t          vc;
614    prims_t                 prims;
615    culling_t               cull;
616    lighting_t              lighting;
617    user_clip_planes_t      clipPlanes;
618    compute_iterators_t     lerp;           __attribute__((aligned(32)));
619    vertex_t                current;
620    vec4_t                  currentColorClamped;
621    vec3_t                  currentNormal;
622    viewport_t              viewport;
623    point_size_t            point;
624    line_width_t            line;
625    polygon_offset_t        polygonOffset;
626    fog_t                   fog;
627    uint32_t                perspective : 1;
628    uint32_t                transformTextures : 1;
629    EGLSurfaceManager*      surfaceManager;
630    EGLBufferObjectManager* bufferObjectManager;
631
632    GLenum                  error;
633
634    static inline ogles_context_t* get() {
635        return getGlThreadSpecific();
636    }
637
638};
639
640}; // namespace gl
641}; // namespace android
642
643using namespace android::gl;
644
645#endif // ANDROID_OPENGLES_CONTEXT_H
646
647