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