Home | History | Annotate | Download | only in libagl
      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