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