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