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