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 #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 HAVE_ANDROID_OS
    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