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