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