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    uint32_t        reserved1[4];
151
152    inline void clear() {
153        flags = index = locked = mru = 0;
154    }
155};
156
157struct point_size_t {
158    GGLcoord    size;
159    GLboolean   smooth;
160};
161
162struct line_width_t {
163    GGLcoord    width;
164    GLboolean   smooth;
165};
166
167struct polygon_offset_t {
168    GLfixed     factor;
169    GLfixed     units;
170    GLboolean   enable;
171};
172
173// ----------------------------------------------------------------------------
174// arrays
175// ----------------------------------------------------------------------------
176
177struct array_t {
178    typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
179    fetcher_t       fetch;
180    GLvoid const*   physical_pointer;
181    GLint           size;
182    GLsizei         stride;
183    GLvoid const*   pointer;
184    buffer_t const* bo;
185    uint16_t        type;
186    GLboolean       enable;
187    GLboolean       pad;
188    GLsizei         bounds;
189    void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
190    inline void resolve();
191    inline const GLubyte* element(GLint i) const {
192        return (const GLubyte*)physical_pointer + i * stride;
193    }
194};
195
196struct array_machine_t {
197    array_t         vertex;
198    array_t         normal;
199    array_t         color;
200    array_t         texture[GGL_TEXTURE_UNIT_COUNT];
201    uint8_t         activeTexture;
202    uint8_t         tmu;
203    uint16_t        cull;
204    uint32_t        flags;
205    GLenum          indicesType;
206    buffer_t const* array_buffer;
207    buffer_t const* element_array_buffer;
208
209    void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
210    void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
211
212    void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
213    void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
214    void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
215    void (*perspective)(ogles_context_t*c, vertex_t* v);
216    void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
217            GGLfixed t, const vertex_t* s, const vertex_t* p);
218    void (*clipEye)(ogles_context_t* c, vertex_t* nv,
219            GGLfixed t, const vertex_t* s, const vertex_t* p);
220};
221
222struct vertex_cache_t {
223    enum {
224        // must be at least 4
225        // 3 vertice for triangles
226        // or 2 + 2 for indexed triangles w/ cache contention
227        VERTEX_BUFFER_SIZE  = 8,
228        // must be a power of two and at least 3
229        VERTEX_CACHE_SIZE   = 64,   // 8 KB
230
231        INDEX_BITS      = 16,
232        INDEX_MASK      = ((1LU<<INDEX_BITS)-1),
233        INDEX_SEQ       = 1LU<<INDEX_BITS,
234    };
235    vertex_t*       vBuffer;
236    vertex_t*       vCache;
237    uint32_t        sequence;
238    void*           base;
239    uint32_t        total;
240    uint32_t        misses;
241    int64_t         startTime;
242    void init();
243    void uninit();
244    void clear();
245    void dump_stats(GLenum mode);
246};
247
248// ----------------------------------------------------------------------------
249// fog
250// ----------------------------------------------------------------------------
251
252struct fog_t {
253    GLfixed     density;
254    GLfixed     start;
255    GLfixed     end;
256    GLfixed     invEndMinusStart;
257    GLenum      mode;
258    GLfixed     (*fog)(ogles_context_t* c, GLfixed z);
259};
260
261// ----------------------------------------------------------------------------
262// user clip planes
263// ----------------------------------------------------------------------------
264
265const unsigned int OGLES_MAX_CLIP_PLANES = 6;
266
267struct clip_plane_t {
268    vec4_t      equation;
269};
270
271struct user_clip_planes_t {
272    clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
273    uint32_t        enable;
274};
275
276// ----------------------------------------------------------------------------
277// lighting
278// ----------------------------------------------------------------------------
279
280const unsigned int OGLES_MAX_LIGHTS = 8;
281
282struct light_t {
283    vec4_t      ambient;
284    vec4_t      diffuse;
285    vec4_t      specular;
286    vec4_t      implicitAmbient;
287    vec4_t      implicitDiffuse;
288    vec4_t      implicitSpecular;
289    vec4_t      position;       // position in eye space
290    vec4_t      objPosition;
291    vec4_t      normalizedObjPosition;
292    vec4_t      spotDir;
293    vec4_t      normalizedSpotDir;
294    GLfixed     spotExp;
295    GLfixed     spotCutoff;
296    GLfixed     spotCutoffCosine;
297    GLfixed     attenuation[3];
298    GLfixed     rConstAttenuation;
299    GLboolean   enable;
300};
301
302struct material_t {
303    vec4_t      ambient;
304    vec4_t      diffuse;
305    vec4_t      specular;
306    vec4_t      emission;
307    GLfixed     shininess;
308};
309
310struct light_model_t {
311    vec4_t      ambient;
312    GLboolean   twoSide;
313};
314
315struct color_material_t {
316    GLenum      face;
317    GLenum      mode;
318    GLboolean   enable;
319};
320
321struct lighting_t {
322    light_t             lights[OGLES_MAX_LIGHTS];
323    material_t          front;
324    light_model_t       lightModel;
325    color_material_t    colorMaterial;
326    vec4_t              implicitSceneEmissionAndAmbient;
327    vec4_t              objViewer;
328    uint32_t            enabledLights;
329    GLboolean           enable;
330    GLenum              shadeModel;
331    typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
332    void (*lightVertex)(ogles_context_t* c, vertex_t* v);
333    void (*lightTriangle)(ogles_context_t* c,
334            vertex_t* v0, vertex_t* v1, vertex_t* v2);
335};
336
337struct culling_t {
338    GLenum      cullFace;
339    GLenum      frontFace;
340    GLboolean   enable;
341};
342
343// ----------------------------------------------------------------------------
344// textures
345// ----------------------------------------------------------------------------
346
347struct texture_unit_t {
348    GLuint              name;
349    EGLTextureObject*   texture;
350    uint8_t             dirty;
351};
352
353struct texture_state_t
354{
355    texture_unit_t      tmu[GGL_TEXTURE_UNIT_COUNT];
356    int                 active;     // active tmu
357    EGLTextureObject*   defaultTexture;
358    GGLContext*         ggl;
359    uint8_t             packAlignment;
360    uint8_t             unpackAlignment;
361};
362
363// ----------------------------------------------------------------------------
364// transformation and matrices
365// ----------------------------------------------------------------------------
366
367struct matrixf_t;
368
369struct matrixx_t {
370    GLfixed m[16];
371    void load(const matrixf_t& rhs);
372};
373
374struct matrix_stack_t;
375
376
377struct matrixf_t {
378    void loadIdentity();
379    void load(const matrixf_t& rhs);
380
381    inline GLfloat* editElements() { return m; }
382    inline GLfloat const* elements() const { return m; }
383
384    void set(const GLfixed* rhs);
385    void set(const GLfloat* rhs);
386
387    static void multiply(matrixf_t& r,
388            const matrixf_t& lhs, const matrixf_t& rhs);
389
390    void dump(const char* what);
391
392private:
393    friend struct matrix_stack_t;
394    GLfloat     m[16];
395    void load(const GLfixed* rhs);
396    void load(const GLfloat* rhs);
397    void multiply(const matrixf_t& rhs);
398    void translate(GLfloat x, GLfloat y, GLfloat z);
399    void scale(GLfloat x, GLfloat y, GLfloat z);
400    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
401};
402
403enum {
404    OP_IDENTITY         = 0x00,
405    OP_TRANSLATE        = 0x01,
406    OP_UNIFORM_SCALE    = 0x02,
407    OP_SCALE            = 0x05,
408    OP_ROTATE           = 0x08,
409    OP_SKEW             = 0x10,
410    OP_ALL              = 0x1F
411};
412
413struct transform_t {
414    enum {
415        FLAGS_2D_PROJECTION = 0x1
416    };
417    matrixx_t       matrix;
418    uint32_t        flags;
419    uint32_t        ops;
420
421    union {
422        struct {
423            void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
424            void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
425            void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
426        };
427        void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
428    };
429
430    void loadIdentity();
431    void picker();
432    void dump(const char* what);
433};
434
435struct mvui_transform_t : public transform_t
436{
437    void picker();
438};
439
440struct matrix_stack_t {
441    enum {
442        DO_PICKER           = 0x1,
443        DO_FLOAT_TO_FIXED   = 0x2
444    };
445    transform_t     transform;
446    uint8_t         maxDepth;
447    uint8_t         depth;
448    uint8_t         dirty;
449    uint8_t         reserved;
450    matrixf_t       *stack;
451    uint8_t         *ops;
452    void init(int depth);
453    void uninit();
454    void loadIdentity();
455    void load(const GLfixed* rhs);
456    void load(const GLfloat* rhs);
457    void multiply(const matrixf_t& rhs);
458    void translate(GLfloat x, GLfloat y, GLfloat z);
459    void scale(GLfloat x, GLfloat y, GLfloat z);
460    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
461    GLint push();
462    GLint pop();
463    void validate();
464    matrixf_t& top() { return stack[depth]; }
465    const matrixf_t& top() const { return stack[depth]; }
466    uint32_t top_ops() const { return ops[depth]; }
467    inline bool isRigidBody() const {
468        return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
469    }
470};
471
472struct vp_transform_t {
473    transform_t     transform;
474    matrixf_t       matrix;
475    GLfloat         zNear;
476    GLfloat         zFar;
477    void loadIdentity();
478};
479
480struct transform_state_t {
481    enum {
482        MODELVIEW           = 0x01,
483        PROJECTION          = 0x02,
484        VIEWPORT            = 0x04,
485        TEXTURE             = 0x08,
486        MVUI                = 0x10,
487        MVIT                = 0x20,
488        MVP                 = 0x40,
489    };
490    matrix_stack_t      *current;
491    matrix_stack_t      modelview;
492    matrix_stack_t      projection;
493    matrix_stack_t      texture[GGL_TEXTURE_UNIT_COUNT];
494
495    // modelview * projection
496    transform_t         mvp     __attribute__((aligned(32)));
497    // viewport transformation
498    vp_transform_t      vpt     __attribute__((aligned(32)));
499    // same for 4-D vertices
500    transform_t         mvp4;
501    // full modelview inverse transpose
502    transform_t         mvit4;
503    // upper 3x3 of mv-inverse-transpose (for normals)
504    mvui_transform_t    mvui;
505
506    GLenum              matrixMode;
507    GLenum              rescaleNormals;
508    uint32_t            dirty;
509    void invalidate();
510    void update_mvp();
511    void update_mvit();
512    void update_mvui();
513};
514
515struct viewport_t {
516    GLint       x;
517    GLint       y;
518    GLsizei     w;
519    GLsizei     h;
520    struct {
521        GLint       x;
522        GLint       y;
523    } surfaceport;
524    struct {
525        GLint       x;
526        GLint       y;
527        GLsizei     w;
528        GLsizei     h;
529    } scissor;
530};
531
532// ----------------------------------------------------------------------------
533// Lerping
534// ----------------------------------------------------------------------------
535
536struct compute_iterators_t
537{
538    void initTriangle(
539            vertex_t const* v0,
540            vertex_t const* v1,
541            vertex_t const* v2);
542
543    void initLine(
544            vertex_t const* v0,
545            vertex_t const* v1);
546
547    inline void initLerp(vertex_t const* v0, uint32_t enables);
548
549    int iteratorsScale(int32_t it[3],
550            int32_t c0, int32_t c1, int32_t c2) const;
551
552    void iterators1616(GGLfixed it[3],
553            GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
554
555    void iterators0032(int32_t it[3],
556            int32_t c0, int32_t c1, int32_t c2) const;
557
558    void iterators0032(int64_t it[3],
559            int32_t c0, int32_t c1, int32_t c2) const;
560
561    GGLcoord area() const { return m_area; }
562
563private:
564    // don't change order of members here -- used by iterators.S
565    GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
566    GGLcoord m_x0, m_y0;
567    GGLcoord m_area;
568    uint8_t m_scale;
569    uint8_t m_area_scale;
570    uint8_t m_reserved[2];
571
572};
573
574// ----------------------------------------------------------------------------
575// state
576// ----------------------------------------------------------------------------
577
578#ifdef HAVE_ANDROID_OS
579    // We have a dedicated TLS slot in bionic
580    inline void setGlThreadSpecific(ogles_context_t *value) {
581        ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
582    }
583    inline ogles_context_t* getGlThreadSpecific() {
584        return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
585    }
586#else
587    extern pthread_key_t gGLKey;
588    inline void setGlThreadSpecific(ogles_context_t *value) {
589        pthread_setspecific(gGLKey, value);
590    }
591    inline ogles_context_t* getGlThreadSpecific() {
592        return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
593    }
594#endif
595
596
597struct prims_t {
598    typedef ogles_context_t* GL;
599    void (*renderPoint)(GL, vertex_t*);
600    void (*renderLine)(GL, vertex_t*, vertex_t*);
601    void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
602};
603
604struct ogles_context_t {
605    context_t               rasterizer;
606    array_machine_t         arrays         __attribute__((aligned(32)));
607    texture_state_t         textures;
608    transform_state_t       transforms;
609    vertex_cache_t          vc;
610    prims_t                 prims;
611    culling_t               cull;
612    lighting_t              lighting;
613    user_clip_planes_t      clipPlanes;
614    compute_iterators_t     lerp;           __attribute__((aligned(32)));
615    vertex_t                current;
616    vec4_t                  currentColorClamped;
617    vec3_t                  currentNormal;
618    viewport_t              viewport;
619    point_size_t            point;
620    line_width_t            line;
621    polygon_offset_t        polygonOffset;
622    fog_t                   fog;
623    uint32_t                perspective : 1;
624    uint32_t                transformTextures : 1;
625    EGLSurfaceManager*      surfaceManager;
626    EGLBufferObjectManager* bufferObjectManager;
627
628    GLenum                  error;
629
630    static inline ogles_context_t* get() {
631        return getGlThreadSpecific();
632    }
633
634};
635
636}; // namespace gl
637}; // namespace android
638
639using namespace android::gl;
640
641#endif // ANDROID_OPENGLES_CONTEXT_H
642
643