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