blob: 6b1fa770281d6031a990c99aec43f5e685579921 [file] [log] [blame]
The Android Open Source Project9066cfe2009-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>
Mathias Agopian350d6512009-06-10 16:01:54 -070029#include <hardware/gralloc.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31#include <GLES/gl.h>
32#include <GLES/glext.h>
33
34namespace android {
35
Mathias Agopiand1f73a22010-02-01 18:24:52 -080036
37const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
38#ifdef GL_OES_compressed_ETC1_RGB8_texture
39 + 1
40#endif
41 ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43class EGLTextureObject;
44class EGLSurfaceManager;
45class EGLBufferObjectManager;
46
47namespace gl {
Mathias Agopian1473f462009-04-10 14:24:30 -070048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049struct 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 {
Mathias Agopian1473f462009-04-10 14:24:30 -0700105 // these constant matter for our clipping
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 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,
Mathias Agopian1473f462009-04-10 14:24:30 -0700115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 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 };
Mathias Agopian1473f462009-04-10 14:24:30 -0700130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 // 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;
Mathias Agopian1473f462009-04-10 14:24:30 -0700139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 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 uint32_t reserved1[4];
Mathias Agopian1473f462009-04-10 14:24:30 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 inline void clear() {
153 flags = index = locked = mru = 0;
154 }
155};
156
157struct point_size_t {
158 GGLcoord size;
159 GLboolean smooth;
160};
161
162struct line_width_t {
163 GGLcoord width;
164 GLboolean smooth;
165};
166
167struct polygon_offset_t {
168 GLfixed factor;
169 GLfixed units;
170 GLboolean enable;
171};
172
173// ----------------------------------------------------------------------------
174// arrays
175// ----------------------------------------------------------------------------
176
177struct array_t {
178 typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
179 fetcher_t fetch;
180 GLvoid const* physical_pointer;
181 GLint size;
182 GLsizei stride;
183 GLvoid const* pointer;
184 buffer_t const* bo;
185 uint16_t type;
186 GLboolean enable;
187 GLboolean pad;
188 GLsizei bounds;
189 void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
190 inline void resolve();
191 inline const GLubyte* element(GLint i) const {
192 return (const GLubyte*)physical_pointer + i * stride;
193 }
194};
195
196struct array_machine_t {
197 array_t vertex;
198 array_t normal;
199 array_t color;
200 array_t texture[GGL_TEXTURE_UNIT_COUNT];
201 uint8_t activeTexture;
202 uint8_t tmu;
203 uint16_t cull;
204 uint32_t flags;
205 GLenum indicesType;
206 buffer_t const* array_buffer;
207 buffer_t const* element_array_buffer;
Mathias Agopian1473f462009-04-10 14:24:30 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
210 void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
211
212 void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
213 void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
214 void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
215 void (*perspective)(ogles_context_t*c, vertex_t* v);
216 void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
217 GGLfixed t, const vertex_t* s, const vertex_t* p);
218 void (*clipEye)(ogles_context_t* c, vertex_t* nv,
219 GGLfixed t, const vertex_t* s, const vertex_t* p);
220};
221
222struct vertex_cache_t {
223 enum {
224 // must be at least 4
225 // 3 vertice for triangles
226 // or 2 + 2 for indexed triangles w/ cache contention
227 VERTEX_BUFFER_SIZE = 8,
228 // must be a power of two and at least 3
229 VERTEX_CACHE_SIZE = 64, // 8 KB
230
231 INDEX_BITS = 16,
232 INDEX_MASK = ((1LU<<INDEX_BITS)-1),
233 INDEX_SEQ = 1LU<<INDEX_BITS,
234 };
235 vertex_t* vBuffer;
236 vertex_t* vCache;
237 uint32_t sequence;
238 void* base;
239 uint32_t total;
240 uint32_t misses;
241 int64_t startTime;
242 void init();
243 void uninit();
244 void clear();
245 void dump_stats(GLenum mode);
246};
247
248// ----------------------------------------------------------------------------
249// fog
250// ----------------------------------------------------------------------------
251
252struct fog_t {
253 GLfixed density;
254 GLfixed start;
255 GLfixed end;
256 GLfixed invEndMinusStart;
257 GLenum mode;
258 GLfixed (*fog)(ogles_context_t* c, GLfixed z);
259};
260
261// ----------------------------------------------------------------------------
262// user clip planes
263// ----------------------------------------------------------------------------
264
265const unsigned int OGLES_MAX_CLIP_PLANES = 6;
266
267struct clip_plane_t {
268 vec4_t equation;
269};
270
271struct user_clip_planes_t {
272 clip_plane_t plane[OGLES_MAX_CLIP_PLANES];
273 uint32_t enable;
274};
275
276// ----------------------------------------------------------------------------
277// lighting
278// ----------------------------------------------------------------------------
279
280const unsigned int OGLES_MAX_LIGHTS = 8;
281
282struct light_t {
283 vec4_t ambient;
284 vec4_t diffuse;
285 vec4_t specular;
286 vec4_t implicitAmbient;
287 vec4_t implicitDiffuse;
288 vec4_t implicitSpecular;
289 vec4_t position; // position in eye space
290 vec4_t objPosition;
291 vec4_t normalizedObjPosition;
292 vec4_t spotDir;
293 vec4_t normalizedSpotDir;
294 GLfixed spotExp;
295 GLfixed spotCutoff;
296 GLfixed spotCutoffCosine;
297 GLfixed attenuation[3];
298 GLfixed rConstAttenuation;
299 GLboolean enable;
300};
301
302struct material_t {
303 vec4_t ambient;
304 vec4_t diffuse;
305 vec4_t specular;
306 vec4_t emission;
307 GLfixed shininess;
308};
309
310struct light_model_t {
311 vec4_t ambient;
312 GLboolean twoSide;
313};
314
315struct color_material_t {
316 GLenum face;
317 GLenum mode;
318 GLboolean enable;
319};
320
321struct lighting_t {
322 light_t lights[OGLES_MAX_LIGHTS];
323 material_t front;
324 light_model_t lightModel;
325 color_material_t colorMaterial;
Mathias Agopiane304bdd2010-02-02 18:48:15 -0800326 vec4_t implicitSceneEmissionAndAmbient;
327 vec4_t objViewer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 uint32_t enabledLights;
329 GLboolean enable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 GLenum shadeModel;
331 typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
332 void (*lightVertex)(ogles_context_t* c, vertex_t* v);
333 void (*lightTriangle)(ogles_context_t* c,
334 vertex_t* v0, vertex_t* v1, vertex_t* v2);
335};
336
337struct culling_t {
338 GLenum cullFace;
339 GLenum frontFace;
340 GLboolean enable;
341};
342
343// ----------------------------------------------------------------------------
344// textures
345// ----------------------------------------------------------------------------
346
347struct texture_unit_t {
348 GLuint name;
349 EGLTextureObject* texture;
350 uint8_t dirty;
351};
352
353struct texture_state_t
354{
355 texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
356 int active; // active tmu
357 EGLTextureObject* defaultTexture;
358 GGLContext* ggl;
359 uint8_t packAlignment;
360 uint8_t unpackAlignment;
361};
362
363// ----------------------------------------------------------------------------
364// transformation and matrices
365// ----------------------------------------------------------------------------
366
367struct matrixf_t;
368
369struct matrixx_t {
370 GLfixed m[16];
371 void load(const matrixf_t& rhs);
372};
373
374struct matrix_stack_t;
375
376
377struct matrixf_t {
378 void loadIdentity();
379 void load(const matrixf_t& rhs);
380
381 inline GLfloat* editElements() { return m; }
382 inline GLfloat const* elements() const { return m; }
383
384 void set(const GLfixed* rhs);
385 void set(const GLfloat* rhs);
386
387 static void multiply(matrixf_t& r,
388 const matrixf_t& lhs, const matrixf_t& rhs);
389
390 void dump(const char* what);
391
392private:
393 friend struct matrix_stack_t;
394 GLfloat m[16];
395 void load(const GLfixed* rhs);
396 void load(const GLfloat* rhs);
397 void multiply(const matrixf_t& rhs);
398 void translate(GLfloat x, GLfloat y, GLfloat z);
399 void scale(GLfloat x, GLfloat y, GLfloat z);
400 void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
401};
402
403enum {
404 OP_IDENTITY = 0x00,
405 OP_TRANSLATE = 0x01,
406 OP_UNIFORM_SCALE = 0x02,
407 OP_SCALE = 0x05,
408 OP_ROTATE = 0x08,
409 OP_SKEW = 0x10,
410 OP_ALL = 0x1F
411};
412
413struct transform_t {
414 enum {
415 FLAGS_2D_PROJECTION = 0x1
416 };
417 matrixx_t matrix;
418 uint32_t flags;
419 uint32_t ops;
Mathias Agopian1473f462009-04-10 14:24:30 -0700420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 union {
422 struct {
423 void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
424 void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
425 void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
426 };
427 void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
428 };
429
430 void loadIdentity();
431 void picker();
432 void dump(const char* what);
433};
434
435struct mvui_transform_t : public transform_t
436{
437 void picker();
438};
439
440struct matrix_stack_t {
441 enum {
442 DO_PICKER = 0x1,
443 DO_FLOAT_TO_FIXED = 0x2
444 };
445 transform_t transform;
446 uint8_t maxDepth;
447 uint8_t depth;
448 uint8_t dirty;
449 uint8_t reserved;
450 matrixf_t *stack;
451 uint8_t *ops;
452 void init(int depth);
453 void uninit();
454 void loadIdentity();
455 void load(const GLfixed* rhs);
456 void load(const GLfloat* rhs);
457 void multiply(const matrixf_t& rhs);
458 void translate(GLfloat x, GLfloat y, GLfloat z);
459 void scale(GLfloat x, GLfloat y, GLfloat z);
460 void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
461 GLint push();
462 GLint pop();
463 void validate();
464 matrixf_t& top() { return stack[depth]; }
465 const matrixf_t& top() const { return stack[depth]; }
Mathias Agopianaaf4b6b2009-06-22 18:04:45 -0700466 uint32_t top_ops() const { return ops[depth]; }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 inline bool isRigidBody() const {
468 return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
469 }
470};
471
472struct vp_transform_t {
473 transform_t transform;
474 matrixf_t matrix;
475 GLfloat zNear;
476 GLfloat zFar;
477 void loadIdentity();
478};
479
480struct transform_state_t {
481 enum {
482 MODELVIEW = 0x01,
483 PROJECTION = 0x02,
484 VIEWPORT = 0x04,
485 TEXTURE = 0x08,
486 MVUI = 0x10,
487 MVIT = 0x20,
488 MVP = 0x40,
489 };
490 matrix_stack_t *current;
491 matrix_stack_t modelview;
492 matrix_stack_t projection;
493 matrix_stack_t texture[GGL_TEXTURE_UNIT_COUNT];
494
495 // modelview * projection
496 transform_t mvp __attribute__((aligned(32)));
497 // viewport transformation
498 vp_transform_t vpt __attribute__((aligned(32)));
499 // same for 4-D vertices
500 transform_t mvp4;
501 // full modelview inverse transpose
502 transform_t mvit4;
503 // upper 3x3 of mv-inverse-transpose (for normals)
504 mvui_transform_t mvui;
505
506 GLenum matrixMode;
507 GLenum rescaleNormals;
508 uint32_t dirty;
509 void invalidate();
510 void update_mvp();
511 void update_mvit();
512 void update_mvui();
513};
514
515struct viewport_t {
516 GLint x;
517 GLint y;
518 GLsizei w;
Mathias Agopian1473f462009-04-10 14:24:30 -0700519 GLsizei h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 struct {
521 GLint x;
522 GLint y;
Mathias Agopian1473f462009-04-10 14:24:30 -0700523 } surfaceport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 struct {
525 GLint x;
526 GLint y;
527 GLsizei w;
Mathias Agopian1473f462009-04-10 14:24:30 -0700528 GLsizei h;
529 } scissor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530};
531
532// ----------------------------------------------------------------------------
533// Lerping
534// ----------------------------------------------------------------------------
535
536struct compute_iterators_t
537{
538 void initTriangle(
539 vertex_t const* v0,
540 vertex_t const* v1,
541 vertex_t const* v2);
542
543 void initLine(
544 vertex_t const* v0,
545 vertex_t const* v1);
546
547 inline void initLerp(vertex_t const* v0, uint32_t enables);
548
549 int iteratorsScale(int32_t it[3],
550 int32_t c0, int32_t c1, int32_t c2) const;
551
552 void iterators1616(GGLfixed it[3],
553 GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
554
555 void iterators0032(int32_t it[3],
556 int32_t c0, int32_t c1, int32_t c2) const;
557
558 void iterators0032(int64_t it[3],
559 int32_t c0, int32_t c1, int32_t c2) const;
560
561 GGLcoord area() const { return m_area; }
562
563private:
564 // don't change order of members here -- used by iterators.S
565 GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
566 GGLcoord m_x0, m_y0;
567 GGLcoord m_area;
568 uint8_t m_scale;
569 uint8_t m_area_scale;
570 uint8_t m_reserved[2];
571
572};
573
574// ----------------------------------------------------------------------------
575// state
576// ----------------------------------------------------------------------------
577
578#ifdef HAVE_ANDROID_OS
579 // We have a dedicated TLS slot in bionic
580 inline void setGlThreadSpecific(ogles_context_t *value) {
581 ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
582 }
583 inline ogles_context_t* getGlThreadSpecific() {
584 return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
585 }
586#else
587 extern pthread_key_t gGLKey;
588 inline void setGlThreadSpecific(ogles_context_t *value) {
589 pthread_setspecific(gGLKey, value);
590 }
591 inline ogles_context_t* getGlThreadSpecific() {
592 return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
593 }
594#endif
595
596
597struct prims_t {
598 typedef ogles_context_t* GL;
599 void (*renderPoint)(GL, vertex_t*);
600 void (*renderLine)(GL, vertex_t*, vertex_t*);
601 void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
602};
603
604struct ogles_context_t {
605 context_t rasterizer;
606 array_machine_t arrays __attribute__((aligned(32)));
607 texture_state_t textures;
608 transform_state_t transforms;
609 vertex_cache_t vc;
610 prims_t prims;
611 culling_t cull;
612 lighting_t lighting;
613 user_clip_planes_t clipPlanes;
614 compute_iterators_t lerp; __attribute__((aligned(32)));
615 vertex_t current;
616 vec4_t currentColorClamped;
617 vec3_t currentNormal;
618 viewport_t viewport;
619 point_size_t point;
620 line_width_t line;
621 polygon_offset_t polygonOffset;
622 fog_t fog;
623 uint32_t perspective : 1;
624 uint32_t transformTextures : 1;
625 EGLSurfaceManager* surfaceManager;
626 EGLBufferObjectManager* bufferObjectManager;
Mathias Agopian1473f462009-04-10 14:24:30 -0700627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 GLenum error;
629
630 static inline ogles_context_t* get() {
631 return getGlThreadSpecific();
632 }
633
634};
635
636}; // namespace gl
637}; // namespace android
638
639#endif // ANDROID_OPENGLES_CONTEXT_H
640