blob: d23f43568e15e4698aaef3865df97424129cb147 [file] [log] [blame]
Mathias Agopian864d2af2012-02-25 19:52:53 -08001/*
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 */
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080016
Mathias Agopian864d2af2012-02-25 19:52:53 -080017#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>
Elliott Hughes6071da72015-08-12 15:27:47 -070024#ifdef __ANDROID__
Mathias Agopian864d2af2012-02-25 19:52:53 -080025#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
34namespace android {
35
36
37const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
38#ifdef GL_OES_compressed_ETC1_RGB8_texture
39 + 1
40#endif
41 ;
42
43class EGLTextureObject;
44class EGLSurfaceManager;
45class EGLBufferObjectManager;
46
47namespace gl {
48
49struct ogles_context_t;
50struct matrixx_t;
51struct transform_t;
52struct buffer_t;
53
54ogles_context_t* getGlContext();
55
56template<typename T>
57static inline void swap(T& a, T& b) {
58 T t(a); a = b; b = t;
59}
60template<typename T>
61inline T max(T a, T b) {
62 return a<b ? b : a;
63}
64template<typename T>
65inline T max(T a, T b, T c) {
66 return max(a, max(b, c));
67}
68template<typename T>
69inline T min(T a, T b) {
70 return a<b ? a : b;
71}
72template<typename T>
73inline T min(T a, T b, T c) {
74 return min(a, min(b, c));
75}
76template<typename T>
77inline 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
85struct 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
94struct 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
103struct 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];
Colin Cross444839b2014-01-24 14:35:39 -0800150#ifdef __LP64__
151 uint32_t reserved1[2];
152#else
Mathias Agopian864d2af2012-02-25 19:52:53 -0800153 uint32_t reserved1[4];
Colin Cross444839b2014-01-24 14:35:39 -0800154#endif
Mathias Agopian864d2af2012-02-25 19:52:53 -0800155
156 inline void clear() {
157 flags = index = locked = mru = 0;
158 }
159};
160
161struct point_size_t {
162 GGLcoord size;
163 GLboolean smooth;
164};
165
166struct line_width_t {
167 GGLcoord width;
168 GLboolean smooth;
169};
170
171struct polygon_offset_t {
172 GLfixed factor;
173 GLfixed units;
174 GLboolean enable;
175};
176
177// ----------------------------------------------------------------------------
178// arrays
179// ----------------------------------------------------------------------------
180
181struct 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();
195 inline const GLubyte* element(GLint i) const {
196 return (const GLubyte*)physical_pointer + i * stride;
197 }
198};
199
200struct 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
226struct 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
256struct 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
269const unsigned int OGLES_MAX_CLIP_PLANES = 6;
270
271struct clip_plane_t {
272 vec4_t equation;
273};
274
275struct user_clip_planes_t {
276 clip_plane_t plane[OGLES_MAX_CLIP_PLANES];
277 uint32_t enable;
278};
279
280// ----------------------------------------------------------------------------
281// lighting
282// ----------------------------------------------------------------------------
283
284const unsigned int OGLES_MAX_LIGHTS = 8;
285
286struct 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
306struct material_t {
307 vec4_t ambient;
308 vec4_t diffuse;
309 vec4_t specular;
310 vec4_t emission;
311 GLfixed shininess;
312};
313
314struct light_model_t {
315 vec4_t ambient;
316 GLboolean twoSide;
317};
318
319struct color_material_t {
320 GLenum face;
321 GLenum mode;
322 GLboolean enable;
323};
324
325struct 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
341struct culling_t {
342 GLenum cullFace;
343 GLenum frontFace;
344 GLboolean enable;
345};
346
347// ----------------------------------------------------------------------------
348// textures
349// ----------------------------------------------------------------------------
350
351struct texture_unit_t {
352 GLuint name;
353 EGLTextureObject* texture;
354 uint8_t dirty;
355};
356
357struct 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
371struct matrixf_t;
372
373struct matrixx_t {
374 GLfixed m[16];
375 void load(const matrixf_t& rhs);
376};
377
378struct matrix_stack_t;
379
380
381struct matrixf_t {
382 void loadIdentity();
383 void load(const matrixf_t& rhs);
384
385 inline GLfloat* editElements() { return m; }
386 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
396private:
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
407enum {
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
417struct 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
439struct mvui_transform_t : public transform_t
440{
441 void picker();
442};
443
444struct 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();
468 matrixf_t& top() { return stack[depth]; }
469 const matrixf_t& top() const { return stack[depth]; }
470 uint32_t top_ops() const { return ops[depth]; }
471 inline bool isRigidBody() const {
472 return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
473 }
474};
475
476struct vp_transform_t {
477 transform_t transform;
478 matrixf_t matrix;
479 GLfloat zNear;
480 GLfloat zFar;
481 void loadIdentity();
482};
483
484struct 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
519struct 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
540struct 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
565 GGLcoord area() const { return m_area; }
566
567private:
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
Elliott Hughes6071da72015-08-12 15:27:47 -0700582#ifdef __ANDROID__
Mathias Agopian864d2af2012-02-25 19:52:53 -0800583 // We have a dedicated TLS slot in bionic
584 inline void setGlThreadSpecific(ogles_context_t *value) {
Colin Cross444839b2014-01-24 14:35:39 -0800585 __get_tls()[TLS_SLOT_OPENGL] = value;
Mathias Agopian864d2af2012-02-25 19:52:53 -0800586 }
587 inline ogles_context_t* getGlThreadSpecific() {
Colin Cross444839b2014-01-24 14:35:39 -0800588 return static_cast<ogles_context_t*>(__get_tls()[TLS_SLOT_OPENGL]);
Mathias Agopian864d2af2012-02-25 19:52:53 -0800589 }
590#else
591 extern pthread_key_t gGLKey;
592 inline void setGlThreadSpecific(ogles_context_t *value) {
593 pthread_setspecific(gGLKey, value);
594 }
595 inline ogles_context_t* getGlThreadSpecific() {
596 return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
597 }
598#endif
599
600
601struct 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
608struct 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
634 static inline ogles_context_t* get() {
635 return getGlThreadSpecific();
636 }
637
638};
639
640}; // namespace gl
641}; // namespace android
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800642
643using namespace android::gl;
Mathias Agopian864d2af2012-02-25 19:52:53 -0800644
645#endif // ANDROID_OPENGLES_CONTEXT_H
646