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 uint32_t reserved1[4];
151
clearvertex_t152 inline void clear() {
153 flags = index = locked = mru = 0;
154 }
155 };
156
157 struct point_size_t {
158 GGLcoord size;
159 GLboolean smooth;
160 };
161
162 struct line_width_t {
163 GGLcoord width;
164 GLboolean smooth;
165 };
166
167 struct polygon_offset_t {
168 GLfixed factor;
169 GLfixed units;
170 GLboolean enable;
171 };
172
173 // ----------------------------------------------------------------------------
174 // arrays
175 // ----------------------------------------------------------------------------
176
177 struct 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();
elementarray_t191 inline const GLubyte* element(GLint i) const {
192 return (const GLubyte*)physical_pointer + i * stride;
193 }
194 };
195
196 struct 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
222 struct 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
252 struct 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
265 const unsigned int OGLES_MAX_CLIP_PLANES = 6;
266
267 struct clip_plane_t {
268 vec4_t equation;
269 };
270
271 struct user_clip_planes_t {
272 clip_plane_t plane[OGLES_MAX_CLIP_PLANES];
273 uint32_t enable;
274 };
275
276 // ----------------------------------------------------------------------------
277 // lighting
278 // ----------------------------------------------------------------------------
279
280 const unsigned int OGLES_MAX_LIGHTS = 8;
281
282 struct 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
302 struct material_t {
303 vec4_t ambient;
304 vec4_t diffuse;
305 vec4_t specular;
306 vec4_t emission;
307 GLfixed shininess;
308 };
309
310 struct light_model_t {
311 vec4_t ambient;
312 GLboolean twoSide;
313 };
314
315 struct color_material_t {
316 GLenum face;
317 GLenum mode;
318 GLboolean enable;
319 };
320
321 struct 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
337 struct culling_t {
338 GLenum cullFace;
339 GLenum frontFace;
340 GLboolean enable;
341 };
342
343 // ----------------------------------------------------------------------------
344 // textures
345 // ----------------------------------------------------------------------------
346
347 struct texture_unit_t {
348 GLuint name;
349 EGLTextureObject* texture;
350 uint8_t dirty;
351 };
352
353 struct 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
367 struct matrixf_t;
368
369 struct matrixx_t {
370 GLfixed m[16];
371 void load(const matrixf_t& rhs);
372 };
373
374 struct matrix_stack_t;
375
376
377 struct matrixf_t {
378 void loadIdentity();
379 void load(const matrixf_t& rhs);
380
editElementsmatrixf_t381 inline GLfloat* editElements() { return m; }
elementsmatrixf_t382 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
392 private:
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
403 enum {
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
413 struct 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
435 struct mvui_transform_t : public transform_t
436 {
437 void picker();
438 };
439
440 struct 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();
topmatrix_stack_t464 matrixf_t& top() { return stack[depth]; }
topmatrix_stack_t465 const matrixf_t& top() const { return stack[depth]; }
top_opsmatrix_stack_t466 uint32_t top_ops() const { return ops[depth]; }
isRigidBodymatrix_stack_t467 inline bool isRigidBody() const {
468 return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
469 }
470 };
471
472 struct vp_transform_t {
473 transform_t transform;
474 matrixf_t matrix;
475 GLfloat zNear;
476 GLfloat zFar;
477 void loadIdentity();
478 };
479
480 struct 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
515 struct 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
536 struct 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
areacompute_iterators_t561 GGLcoord area() const { return m_area; }
562
563 private:
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
setGlThreadSpecific(ogles_context_t * value)580 inline void setGlThreadSpecific(ogles_context_t *value) {
581 ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
582 }
getGlThreadSpecific()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;
setGlThreadSpecific(ogles_context_t * value)588 inline void setGlThreadSpecific(ogles_context_t *value) {
589 pthread_setspecific(gGLKey, value);
590 }
getGlThreadSpecific()591 inline ogles_context_t* getGlThreadSpecific() {
592 return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
593 }
594 #endif
595
596
597 struct 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
604 struct 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
getogles_context_t630 static inline ogles_context_t* get() {
631 return getGlThreadSpecific();
632 }
633
634 };
635
636 }; // namespace gl
637 }; // namespace android
638
639 using namespace android::gl;
640
641 #endif // ANDROID_OPENGLES_CONTEXT_H
642
643