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