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 35 namespace android { 36 37 38 const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10 39 #ifdef GL_OES_compressed_ETC1_RGB8_texture 40 + 1 41 #endif 42 ; 43 44 class EGLTextureObject; 45 class EGLSurfaceManager; 46 class EGLBufferObjectManager; 47 48 namespace gl { 49 50 struct ogles_context_t; 51 struct matrixx_t; 52 struct transform_t; 53 struct buffer_t; 54 55 ogles_context_t* getGlContext(); 56 57 template<typename T> 58 static inline void swap(T& a, T& b) { 59 T t(a); a = b; b = t; 60 } 61 template<typename T> 62 inline T max(T a, T b) { 63 return a<b ? b : a; 64 } 65 template<typename T> 66 inline T max(T a, T b, T c) { 67 return max(a, max(b, c)); 68 } 69 template<typename T> 70 inline T min(T a, T b) { 71 return a<b ? a : b; 72 } 73 template<typename T> 74 inline T min(T a, T b, T c) { 75 return min(a, min(b, c)); 76 } 77 template<typename T> 78 inline 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 86 struct 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 95 struct 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 104 struct 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 162 struct point_size_t { 163 GGLcoord size; 164 GLboolean smooth; 165 }; 166 167 struct line_width_t { 168 GGLcoord width; 169 GLboolean smooth; 170 }; 171 172 struct polygon_offset_t { 173 GLfixed factor; 174 GLfixed units; 175 GLboolean enable; 176 }; 177 178 // ---------------------------------------------------------------------------- 179 // arrays 180 // ---------------------------------------------------------------------------- 181 182 struct 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 201 struct 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 227 struct 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 257 struct 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 270 const unsigned int OGLES_MAX_CLIP_PLANES = 6; 271 272 struct clip_plane_t { 273 vec4_t equation; 274 }; 275 276 struct user_clip_planes_t { 277 clip_plane_t plane[OGLES_MAX_CLIP_PLANES]; 278 uint32_t enable; 279 }; 280 281 // ---------------------------------------------------------------------------- 282 // lighting 283 // ---------------------------------------------------------------------------- 284 285 const unsigned int OGLES_MAX_LIGHTS = 8; 286 287 struct 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 307 struct material_t { 308 vec4_t ambient; 309 vec4_t diffuse; 310 vec4_t specular; 311 vec4_t emission; 312 GLfixed shininess; 313 }; 314 315 struct light_model_t { 316 vec4_t ambient; 317 GLboolean twoSide; 318 }; 319 320 struct color_material_t { 321 GLenum face; 322 GLenum mode; 323 GLboolean enable; 324 }; 325 326 struct 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 342 struct culling_t { 343 GLenum cullFace; 344 GLenum frontFace; 345 GLboolean enable; 346 }; 347 348 // ---------------------------------------------------------------------------- 349 // textures 350 // ---------------------------------------------------------------------------- 351 352 struct texture_unit_t { 353 GLuint name; 354 EGLTextureObject* texture; 355 uint8_t dirty; 356 }; 357 358 struct 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 372 struct matrixf_t; 373 374 struct matrixx_t { 375 GLfixed m[16]; 376 void load(const matrixf_t& rhs); 377 }; 378 379 struct matrix_stack_t; 380 381 382 struct 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 397 private: 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 408 enum { 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 418 struct 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 440 struct mvui_transform_t : public transform_t 441 { 442 void picker(); 443 }; 444 445 struct 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 477 struct vp_transform_t { 478 transform_t transform; 479 matrixf_t matrix; 480 GLfloat zNear; 481 GLfloat zFar; 482 void loadIdentity(); 483 }; 484 485 struct 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 520 struct 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 541 struct 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 568 private: 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 602 struct 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 609 struct 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 644 using namespace android::gl; 645 646 #endif // ANDROID_OPENGLES_CONTEXT_H 647 648