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