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