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 
34 namespace android {
35 
36 
37 const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
38 #ifdef GL_OES_compressed_ETC1_RGB8_texture
39         + 1
40 #endif
41         ;
42 
43 class EGLTextureObject;
44 class EGLSurfaceManager;
45 class EGLBufferObjectManager;
46 
47 namespace gl {
48 
49 struct ogles_context_t;
50 struct matrixx_t;
51 struct transform_t;
52 struct buffer_t;
53 
54 ogles_context_t* getGlContext();
55 
56 template<typename T>
swap(T & a,T & b)57 static inline void swap(T& a, T& b) {
58     T t(a); a = b; b = t;
59 }
60 template<typename T>
max(T a,T b)61 inline T max(T a, T b) {
62     return a<b ? b : a;
63 }
64 template<typename T>
max(T a,T b,T c)65 inline T max(T a, T b, T c) {
66     return max(a, max(b, c));
67 }
68 template<typename T>
min(T a,T b)69 inline T min(T a, T b) {
70     return a<b ? a : b;
71 }
72 template<typename T>
min(T a,T b,T c)73 inline T min(T a, T b, T c) {
74     return min(a, min(b, c));
75 }
76 template<typename T>
min(T a,T b,T c,T d)77 inline 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 
85 struct 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 
94 struct 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 
103 struct 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 
clearvertex_t156     inline void clear() {
157         flags = index = locked = mru = 0;
158     }
159 };
160 
161 struct point_size_t {
162     GGLcoord    size;
163     GLboolean   smooth;
164 };
165 
166 struct line_width_t {
167     GGLcoord    width;
168     GLboolean   smooth;
169 };
170 
171 struct polygon_offset_t {
172     GLfixed     factor;
173     GLfixed     units;
174     GLboolean   enable;
175 };
176 
177 // ----------------------------------------------------------------------------
178 // arrays
179 // ----------------------------------------------------------------------------
180 
181 struct 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();
elementarray_t195     inline const GLubyte* element(GLint i) const {
196         return (const GLubyte*)physical_pointer + i * stride;
197     }
198 };
199 
200 struct 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 
226 struct 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 
256 struct 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 
269 const unsigned int OGLES_MAX_CLIP_PLANES = 6;
270 
271 struct clip_plane_t {
272     vec4_t      equation;
273 };
274 
275 struct user_clip_planes_t {
276     clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
277     uint32_t        enable;
278 };
279 
280 // ----------------------------------------------------------------------------
281 // lighting
282 // ----------------------------------------------------------------------------
283 
284 const unsigned int OGLES_MAX_LIGHTS = 8;
285 
286 struct 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 
306 struct material_t {
307     vec4_t      ambient;
308     vec4_t      diffuse;
309     vec4_t      specular;
310     vec4_t      emission;
311     GLfixed     shininess;
312 };
313 
314 struct light_model_t {
315     vec4_t      ambient;
316     GLboolean   twoSide;
317 };
318 
319 struct color_material_t {
320     GLenum      face;
321     GLenum      mode;
322     GLboolean   enable;
323 };
324 
325 struct 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 
341 struct culling_t {
342     GLenum      cullFace;
343     GLenum      frontFace;
344     GLboolean   enable;
345 };
346 
347 // ----------------------------------------------------------------------------
348 // textures
349 // ----------------------------------------------------------------------------
350 
351 struct texture_unit_t {
352     GLuint              name;
353     EGLTextureObject*   texture;
354     uint8_t             dirty;
355 };
356 
357 struct 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 
371 struct matrixf_t;
372 
373 struct matrixx_t {
374     GLfixed m[16];
375     void load(const matrixf_t& rhs);
376 };
377 
378 struct matrix_stack_t;
379 
380 
381 struct matrixf_t {
382     void loadIdentity();
383     void load(const matrixf_t& rhs);
384 
editElementsmatrixf_t385     inline GLfloat* editElements() { return m; }
elementsmatrixf_t386     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 
396 private:
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 
407 enum {
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 
417 struct 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 
439 struct mvui_transform_t : public transform_t
440 {
441     void picker();
442 };
443 
444 struct 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();
topmatrix_stack_t468     matrixf_t& top() { return stack[depth]; }
topmatrix_stack_t469     const matrixf_t& top() const { return stack[depth]; }
top_opsmatrix_stack_t470     uint32_t top_ops() const { return ops[depth]; }
isRigidBodymatrix_stack_t471     inline bool isRigidBody() const {
472         return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
473     }
474 };
475 
476 struct vp_transform_t {
477     transform_t     transform;
478     matrixf_t       matrix;
479     GLfloat         zNear;
480     GLfloat         zFar;
481     void loadIdentity();
482 };
483 
484 struct 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 
519 struct 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 
540 struct 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 
areacompute_iterators_t565     GGLcoord area() const { return m_area; }
566 
567 private:
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
setGlThreadSpecific(ogles_context_t * value)584     inline void setGlThreadSpecific(ogles_context_t *value) {
585         __get_tls()[TLS_SLOT_OPENGL] = value;
586     }
getGlThreadSpecific()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;
setGlThreadSpecific(ogles_context_t * value)592     inline void setGlThreadSpecific(ogles_context_t *value) {
593         pthread_setspecific(gGLKey, value);
594     }
getGlThreadSpecific()595     inline ogles_context_t* getGlThreadSpecific() {
596         return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
597     }
598 #endif
599 
600 
601 struct 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 
608 struct 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 
getogles_context_t634     static inline ogles_context_t* get() {
635         return getGlThreadSpecific();
636     }
637 
638 };
639 
640 }; // namespace gl
641 }; // namespace android
642 
643 using namespace android::gl;
644 
645 #endif // ANDROID_OPENGLES_CONTEXT_H
646 
647