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