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