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 HAVE_ANDROID_OS 25 #include <bionic_tls.h> 26 #endif 27 28 #include <private/pixelflinger/ggl_context.h> 29 #include <hardware/gralloc.h> 30 31 #include <GLES/gl.h> 32 #include <GLES/glext.h> 33 34 namespace android { 35 36 37 const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10 38 #ifdef GL_OES_compressed_ETC1_RGB8_texture 39 + 1 40 #endif 41 ; 42 43 class EGLTextureObject; 44 class EGLSurfaceManager; 45 class EGLBufferObjectManager; 46 47 namespace gl { 48 49 struct ogles_context_t; 50 struct matrixx_t; 51 struct transform_t; 52 struct buffer_t; 53 54 ogles_context_t* getGlContext(); 55 56 template<typename T> 57 static inline void swap(T& a, T& b) { 58 T t(a); a = b; b = t; 59 } 60 template<typename T> 61 inline T max(T a, T b) { 62 return a<b ? b : a; 63 } 64 template<typename T> 65 inline T max(T a, T b, T c) { 66 return max(a, max(b, c)); 67 } 68 template<typename T> 69 inline T min(T a, T b) { 70 return a<b ? a : b; 71 } 72 template<typename T> 73 inline T min(T a, T b, T c) { 74 return min(a, min(b, c)); 75 } 76 template<typename T> 77 inline 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 85 struct 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 94 struct 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 103 struct vertex_t { 104 enum { 105 // these constant matter for our clipping 106 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, 115 116 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 }; 130 131 // 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; 139 140 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]; 151 152 inline void clear() { 153 flags = index = locked = mru = 0; 154 } 155 }; 156 157 struct point_size_t { 158 GGLcoord size; 159 GLboolean smooth; 160 }; 161 162 struct line_width_t { 163 GGLcoord width; 164 GLboolean smooth; 165 }; 166 167 struct polygon_offset_t { 168 GLfixed factor; 169 GLfixed units; 170 GLboolean enable; 171 }; 172 173 // ---------------------------------------------------------------------------- 174 // arrays 175 // ---------------------------------------------------------------------------- 176 177 struct 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 196 struct 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; 208 209 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 222 struct 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 252 struct 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 265 const unsigned int OGLES_MAX_CLIP_PLANES = 6; 266 267 struct clip_plane_t { 268 vec4_t equation; 269 }; 270 271 struct user_clip_planes_t { 272 clip_plane_t plane[OGLES_MAX_CLIP_PLANES]; 273 uint32_t enable; 274 }; 275 276 // ---------------------------------------------------------------------------- 277 // lighting 278 // ---------------------------------------------------------------------------- 279 280 const unsigned int OGLES_MAX_LIGHTS = 8; 281 282 struct 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 302 struct material_t { 303 vec4_t ambient; 304 vec4_t diffuse; 305 vec4_t specular; 306 vec4_t emission; 307 GLfixed shininess; 308 }; 309 310 struct light_model_t { 311 vec4_t ambient; 312 GLboolean twoSide; 313 }; 314 315 struct color_material_t { 316 GLenum face; 317 GLenum mode; 318 GLboolean enable; 319 }; 320 321 struct lighting_t { 322 light_t lights[OGLES_MAX_LIGHTS]; 323 material_t front; 324 light_model_t lightModel; 325 color_material_t colorMaterial; 326 vec4_t implicitSceneEmissionAndAmbient; 327 vec4_t objViewer; 328 uint32_t enabledLights; 329 GLboolean enable; 330 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 337 struct culling_t { 338 GLenum cullFace; 339 GLenum frontFace; 340 GLboolean enable; 341 }; 342 343 // ---------------------------------------------------------------------------- 344 // textures 345 // ---------------------------------------------------------------------------- 346 347 struct texture_unit_t { 348 GLuint name; 349 EGLTextureObject* texture; 350 uint8_t dirty; 351 }; 352 353 struct 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 367 struct matrixf_t; 368 369 struct matrixx_t { 370 GLfixed m[16]; 371 void load(const matrixf_t& rhs); 372 }; 373 374 struct matrix_stack_t; 375 376 377 struct 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 392 private: 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 403 enum { 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 413 struct transform_t { 414 enum { 415 FLAGS_2D_PROJECTION = 0x1 416 }; 417 matrixx_t matrix; 418 uint32_t flags; 419 uint32_t ops; 420 421 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 435 struct mvui_transform_t : public transform_t 436 { 437 void picker(); 438 }; 439 440 struct 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]; } 466 uint32_t top_ops() const { return ops[depth]; } 467 inline bool isRigidBody() const { 468 return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE)); 469 } 470 }; 471 472 struct vp_transform_t { 473 transform_t transform; 474 matrixf_t matrix; 475 GLfloat zNear; 476 GLfloat zFar; 477 void loadIdentity(); 478 }; 479 480 struct 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 515 struct viewport_t { 516 GLint x; 517 GLint y; 518 GLsizei w; 519 GLsizei h; 520 struct { 521 GLint x; 522 GLint y; 523 } surfaceport; 524 struct { 525 GLint x; 526 GLint y; 527 GLsizei w; 528 GLsizei h; 529 } scissor; 530 }; 531 532 // ---------------------------------------------------------------------------- 533 // Lerping 534 // ---------------------------------------------------------------------------- 535 536 struct 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 563 private: 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 597 struct 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 604 struct 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; 627 628 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 using namespace android::gl; 640 641 #endif // ANDROID_OPENGLES_CONTEXT_H 642 643