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 #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 #ifdef __LP64__ 151 uint32_t reserved1[2]; 152 #else 153 uint32_t reserved1[4]; 154 #endif 155 156 inline void clear() { 157 flags = index = locked = mru = 0; 158 } 159 }; 160 161 struct point_size_t { 162 GGLcoord size; 163 GLboolean smooth; 164 }; 165 166 struct line_width_t { 167 GGLcoord width; 168 GLboolean smooth; 169 }; 170 171 struct polygon_offset_t { 172 GLfixed factor; 173 GLfixed units; 174 GLboolean enable; 175 }; 176 177 // ---------------------------------------------------------------------------- 178 // arrays 179 // ---------------------------------------------------------------------------- 180 181 struct array_t { 182 typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*); 183 fetcher_t fetch; 184 GLvoid const* physical_pointer; 185 GLint size; 186 GLsizei stride; 187 GLvoid const* pointer; 188 buffer_t const* bo; 189 uint16_t type; 190 GLboolean enable; 191 GLboolean pad; 192 GLsizei bounds; 193 void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei); 194 inline void resolve(); 195 inline const GLubyte* element(GLint i) const { 196 return (const GLubyte*)physical_pointer + i * stride; 197 } 198 }; 199 200 struct array_machine_t { 201 array_t vertex; 202 array_t normal; 203 array_t color; 204 array_t texture[GGL_TEXTURE_UNIT_COUNT]; 205 uint8_t activeTexture; 206 uint8_t tmu; 207 uint16_t cull; 208 uint32_t flags; 209 GLenum indicesType; 210 buffer_t const* array_buffer; 211 buffer_t const* element_array_buffer; 212 213 void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei); 214 void (*compileElement)(ogles_context_t*, vertex_t*, GLint); 215 216 void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*); 217 void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*); 218 void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*); 219 void (*perspective)(ogles_context_t*c, vertex_t* v); 220 void (*clipVertex)(ogles_context_t* c, vertex_t* nv, 221 GGLfixed t, const vertex_t* s, const vertex_t* p); 222 void (*clipEye)(ogles_context_t* c, vertex_t* nv, 223 GGLfixed t, const vertex_t* s, const vertex_t* p); 224 }; 225 226 struct vertex_cache_t { 227 enum { 228 // must be at least 4 229 // 3 vertice for triangles 230 // or 2 + 2 for indexed triangles w/ cache contention 231 VERTEX_BUFFER_SIZE = 8, 232 // must be a power of two and at least 3 233 VERTEX_CACHE_SIZE = 64, // 8 KB 234 235 INDEX_BITS = 16, 236 INDEX_MASK = ((1LU<<INDEX_BITS)-1), 237 INDEX_SEQ = 1LU<<INDEX_BITS, 238 }; 239 vertex_t* vBuffer; 240 vertex_t* vCache; 241 uint32_t sequence; 242 void* base; 243 uint32_t total; 244 uint32_t misses; 245 int64_t startTime; 246 void init(); 247 void uninit(); 248 void clear(); 249 void dump_stats(GLenum mode); 250 }; 251 252 // ---------------------------------------------------------------------------- 253 // fog 254 // ---------------------------------------------------------------------------- 255 256 struct fog_t { 257 GLfixed density; 258 GLfixed start; 259 GLfixed end; 260 GLfixed invEndMinusStart; 261 GLenum mode; 262 GLfixed (*fog)(ogles_context_t* c, GLfixed z); 263 }; 264 265 // ---------------------------------------------------------------------------- 266 // user clip planes 267 // ---------------------------------------------------------------------------- 268 269 const unsigned int OGLES_MAX_CLIP_PLANES = 6; 270 271 struct clip_plane_t { 272 vec4_t equation; 273 }; 274 275 struct user_clip_planes_t { 276 clip_plane_t plane[OGLES_MAX_CLIP_PLANES]; 277 uint32_t enable; 278 }; 279 280 // ---------------------------------------------------------------------------- 281 // lighting 282 // ---------------------------------------------------------------------------- 283 284 const unsigned int OGLES_MAX_LIGHTS = 8; 285 286 struct light_t { 287 vec4_t ambient; 288 vec4_t diffuse; 289 vec4_t specular; 290 vec4_t implicitAmbient; 291 vec4_t implicitDiffuse; 292 vec4_t implicitSpecular; 293 vec4_t position; // position in eye space 294 vec4_t objPosition; 295 vec4_t normalizedObjPosition; 296 vec4_t spotDir; 297 vec4_t normalizedSpotDir; 298 GLfixed spotExp; 299 GLfixed spotCutoff; 300 GLfixed spotCutoffCosine; 301 GLfixed attenuation[3]; 302 GLfixed rConstAttenuation; 303 GLboolean enable; 304 }; 305 306 struct material_t { 307 vec4_t ambient; 308 vec4_t diffuse; 309 vec4_t specular; 310 vec4_t emission; 311 GLfixed shininess; 312 }; 313 314 struct light_model_t { 315 vec4_t ambient; 316 GLboolean twoSide; 317 }; 318 319 struct color_material_t { 320 GLenum face; 321 GLenum mode; 322 GLboolean enable; 323 }; 324 325 struct lighting_t { 326 light_t lights[OGLES_MAX_LIGHTS]; 327 material_t front; 328 light_model_t lightModel; 329 color_material_t colorMaterial; 330 vec4_t implicitSceneEmissionAndAmbient; 331 vec4_t objViewer; 332 uint32_t enabledLights; 333 GLboolean enable; 334 GLenum shadeModel; 335 typedef void (*light_fct_t)(ogles_context_t*, vertex_t*); 336 void (*lightVertex)(ogles_context_t* c, vertex_t* v); 337 void (*lightTriangle)(ogles_context_t* c, 338 vertex_t* v0, vertex_t* v1, vertex_t* v2); 339 }; 340 341 struct culling_t { 342 GLenum cullFace; 343 GLenum frontFace; 344 GLboolean enable; 345 }; 346 347 // ---------------------------------------------------------------------------- 348 // textures 349 // ---------------------------------------------------------------------------- 350 351 struct texture_unit_t { 352 GLuint name; 353 EGLTextureObject* texture; 354 uint8_t dirty; 355 }; 356 357 struct texture_state_t 358 { 359 texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT]; 360 int active; // active tmu 361 EGLTextureObject* defaultTexture; 362 GGLContext* ggl; 363 uint8_t packAlignment; 364 uint8_t unpackAlignment; 365 }; 366 367 // ---------------------------------------------------------------------------- 368 // transformation and matrices 369 // ---------------------------------------------------------------------------- 370 371 struct matrixf_t; 372 373 struct matrixx_t { 374 GLfixed m[16]; 375 void load(const matrixf_t& rhs); 376 }; 377 378 struct matrix_stack_t; 379 380 381 struct matrixf_t { 382 void loadIdentity(); 383 void load(const matrixf_t& rhs); 384 385 inline GLfloat* editElements() { return m; } 386 inline GLfloat const* elements() const { return m; } 387 388 void set(const GLfixed* rhs); 389 void set(const GLfloat* rhs); 390 391 static void multiply(matrixf_t& r, 392 const matrixf_t& lhs, const matrixf_t& rhs); 393 394 void dump(const char* what); 395 396 private: 397 friend struct matrix_stack_t; 398 GLfloat m[16]; 399 void load(const GLfixed* rhs); 400 void load(const GLfloat* rhs); 401 void multiply(const matrixf_t& rhs); 402 void translate(GLfloat x, GLfloat y, GLfloat z); 403 void scale(GLfloat x, GLfloat y, GLfloat z); 404 void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z); 405 }; 406 407 enum { 408 OP_IDENTITY = 0x00, 409 OP_TRANSLATE = 0x01, 410 OP_UNIFORM_SCALE = 0x02, 411 OP_SCALE = 0x05, 412 OP_ROTATE = 0x08, 413 OP_SKEW = 0x10, 414 OP_ALL = 0x1F 415 }; 416 417 struct transform_t { 418 enum { 419 FLAGS_2D_PROJECTION = 0x1 420 }; 421 matrixx_t matrix; 422 uint32_t flags; 423 uint32_t ops; 424 425 union { 426 struct { 427 void (*point2)(transform_t const* t, vec4_t*, vec4_t const*); 428 void (*point3)(transform_t const* t, vec4_t*, vec4_t const*); 429 void (*point4)(transform_t const* t, vec4_t*, vec4_t const*); 430 }; 431 void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*); 432 }; 433 434 void loadIdentity(); 435 void picker(); 436 void dump(const char* what); 437 }; 438 439 struct mvui_transform_t : public transform_t 440 { 441 void picker(); 442 }; 443 444 struct matrix_stack_t { 445 enum { 446 DO_PICKER = 0x1, 447 DO_FLOAT_TO_FIXED = 0x2 448 }; 449 transform_t transform; 450 uint8_t maxDepth; 451 uint8_t depth; 452 uint8_t dirty; 453 uint8_t reserved; 454 matrixf_t *stack; 455 uint8_t *ops; 456 void init(int depth); 457 void uninit(); 458 void loadIdentity(); 459 void load(const GLfixed* rhs); 460 void load(const GLfloat* rhs); 461 void multiply(const matrixf_t& rhs); 462 void translate(GLfloat x, GLfloat y, GLfloat z); 463 void scale(GLfloat x, GLfloat y, GLfloat z); 464 void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z); 465 GLint push(); 466 GLint pop(); 467 void validate(); 468 matrixf_t& top() { return stack[depth]; } 469 const matrixf_t& top() const { return stack[depth]; } 470 uint32_t top_ops() const { return ops[depth]; } 471 inline bool isRigidBody() const { 472 return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE)); 473 } 474 }; 475 476 struct vp_transform_t { 477 transform_t transform; 478 matrixf_t matrix; 479 GLfloat zNear; 480 GLfloat zFar; 481 void loadIdentity(); 482 }; 483 484 struct transform_state_t { 485 enum { 486 MODELVIEW = 0x01, 487 PROJECTION = 0x02, 488 VIEWPORT = 0x04, 489 TEXTURE = 0x08, 490 MVUI = 0x10, 491 MVIT = 0x20, 492 MVP = 0x40, 493 }; 494 matrix_stack_t *current; 495 matrix_stack_t modelview; 496 matrix_stack_t projection; 497 matrix_stack_t texture[GGL_TEXTURE_UNIT_COUNT]; 498 499 // modelview * projection 500 transform_t mvp __attribute__((aligned(32))); 501 // viewport transformation 502 vp_transform_t vpt __attribute__((aligned(32))); 503 // same for 4-D vertices 504 transform_t mvp4; 505 // full modelview inverse transpose 506 transform_t mvit4; 507 // upper 3x3 of mv-inverse-transpose (for normals) 508 mvui_transform_t mvui; 509 510 GLenum matrixMode; 511 GLenum rescaleNormals; 512 uint32_t dirty; 513 void invalidate(); 514 void update_mvp(); 515 void update_mvit(); 516 void update_mvui(); 517 }; 518 519 struct viewport_t { 520 GLint x; 521 GLint y; 522 GLsizei w; 523 GLsizei h; 524 struct { 525 GLint x; 526 GLint y; 527 } surfaceport; 528 struct { 529 GLint x; 530 GLint y; 531 GLsizei w; 532 GLsizei h; 533 } scissor; 534 }; 535 536 // ---------------------------------------------------------------------------- 537 // Lerping 538 // ---------------------------------------------------------------------------- 539 540 struct compute_iterators_t 541 { 542 void initTriangle( 543 vertex_t const* v0, 544 vertex_t const* v1, 545 vertex_t const* v2); 546 547 void initLine( 548 vertex_t const* v0, 549 vertex_t const* v1); 550 551 inline void initLerp(vertex_t const* v0, uint32_t enables); 552 553 int iteratorsScale(int32_t it[3], 554 int32_t c0, int32_t c1, int32_t c2) const; 555 556 void iterators1616(GGLfixed it[3], 557 GGLfixed c0, GGLfixed c1, GGLfixed c2) const; 558 559 void iterators0032(int32_t it[3], 560 int32_t c0, int32_t c1, int32_t c2) const; 561 562 void iterators0032(int64_t it[3], 563 int32_t c0, int32_t c1, int32_t c2) const; 564 565 GGLcoord area() const { return m_area; } 566 567 private: 568 // don't change order of members here -- used by iterators.S 569 GGLcoord m_dx01, m_dy10, m_dx20, m_dy02; 570 GGLcoord m_x0, m_y0; 571 GGLcoord m_area; 572 uint8_t m_scale; 573 uint8_t m_area_scale; 574 uint8_t m_reserved[2]; 575 576 }; 577 578 // ---------------------------------------------------------------------------- 579 // state 580 // ---------------------------------------------------------------------------- 581 582 #ifdef __ANDROID__ 583 // We have a dedicated TLS slot in bionic 584 inline void setGlThreadSpecific(ogles_context_t *value) { 585 __get_tls()[TLS_SLOT_OPENGL] = value; 586 } 587 inline ogles_context_t* getGlThreadSpecific() { 588 return static_cast<ogles_context_t*>(__get_tls()[TLS_SLOT_OPENGL]); 589 } 590 #else 591 extern pthread_key_t gGLKey; 592 inline void setGlThreadSpecific(ogles_context_t *value) { 593 pthread_setspecific(gGLKey, value); 594 } 595 inline ogles_context_t* getGlThreadSpecific() { 596 return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey)); 597 } 598 #endif 599 600 601 struct prims_t { 602 typedef ogles_context_t* GL; 603 void (*renderPoint)(GL, vertex_t*); 604 void (*renderLine)(GL, vertex_t*, vertex_t*); 605 void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*); 606 }; 607 608 struct 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; 631 632 GLenum error; 633 634 static inline ogles_context_t* get() { 635 return getGlThreadSpecific(); 636 } 637 638 }; 639 640 }; // namespace gl 641 }; // namespace android 642 643 using namespace android::gl; 644 645 #endif // ANDROID_OPENGLES_CONTEXT_H 646 647