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 35struct android_native_buffer_t; 36 37namespace android { 38 39 40const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10 41#ifdef GL_OES_compressed_ETC1_RGB8_texture 42 + 1 43#endif 44 ; 45 46class EGLTextureObject; 47class EGLSurfaceManager; 48class EGLBufferObjectManager; 49 50namespace gl { 51 52struct ogles_context_t; 53struct matrixx_t; 54struct transform_t; 55struct buffer_t; 56 57ogles_context_t* getGlContext(); 58 59template<typename T> 60static inline void swap(T& a, T& b) { 61 T t(a); a = b; b = t; 62} 63template<typename T> 64inline T max(T a, T b) { 65 return a<b ? b : a; 66} 67template<typename T> 68inline T max(T a, T b, T c) { 69 return max(a, max(b, c)); 70} 71template<typename T> 72inline T min(T a, T b) { 73 return a<b ? a : b; 74} 75template<typename T> 76inline T min(T a, T b, T c) { 77 return min(a, min(b, c)); 78} 79template<typename T> 80inline 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 88struct 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 97struct 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 106struct 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 160struct point_size_t { 161 GGLcoord size; 162 GLboolean smooth; 163}; 164 165struct line_width_t { 166 GGLcoord width; 167 GLboolean smooth; 168}; 169 170struct polygon_offset_t { 171 GLfixed factor; 172 GLfixed units; 173 GLboolean enable; 174}; 175 176// ---------------------------------------------------------------------------- 177// arrays 178// ---------------------------------------------------------------------------- 179 180struct 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 199struct 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 225struct 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 255struct 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 268const unsigned int OGLES_MAX_CLIP_PLANES = 6; 269 270struct clip_plane_t { 271 vec4_t equation; 272}; 273 274struct user_clip_planes_t { 275 clip_plane_t plane[OGLES_MAX_CLIP_PLANES]; 276 uint32_t enable; 277}; 278 279// ---------------------------------------------------------------------------- 280// lighting 281// ---------------------------------------------------------------------------- 282 283const unsigned int OGLES_MAX_LIGHTS = 8; 284 285struct 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 305struct material_t { 306 vec4_t ambient; 307 vec4_t diffuse; 308 vec4_t specular; 309 vec4_t emission; 310 GLfixed shininess; 311}; 312 313struct light_model_t { 314 vec4_t ambient; 315 GLboolean twoSide; 316}; 317 318struct color_material_t { 319 GLenum face; 320 GLenum mode; 321 GLboolean enable; 322}; 323 324struct 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 340struct culling_t { 341 GLenum cullFace; 342 GLenum frontFace; 343 GLboolean enable; 344}; 345 346// ---------------------------------------------------------------------------- 347// textures 348// ---------------------------------------------------------------------------- 349 350struct texture_unit_t { 351 GLuint name; 352 EGLTextureObject* texture; 353 uint8_t dirty; 354}; 355 356struct 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 370struct matrixf_t; 371 372struct matrixx_t { 373 GLfixed m[16]; 374 void load(const matrixf_t& rhs); 375}; 376 377struct matrix_stack_t; 378 379 380struct 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 395private: 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 406enum { 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 416struct 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 438struct mvui_transform_t : public transform_t 439{ 440 void picker(); 441}; 442 443struct 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 475struct vp_transform_t { 476 transform_t transform; 477 matrixf_t matrix; 478 GLfloat zNear; 479 GLfloat zFar; 480 void loadIdentity(); 481}; 482 483struct 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 518struct 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 539struct 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 566private: 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 600struct 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 607struct 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 615struct 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