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