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