Home | History | Annotate | Download | only in OpenglCodecCommon
      1 /*
      2 * Copyright (C) 2011 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 #ifndef _GL_CLIENT_STATE_H_
     17 #define _GL_CLIENT_STATE_H_
     18 
     19 #define GL_API
     20 #ifndef ANDROID
     21 #define GL_APIENTRY
     22 #define GL_APIENTRYP
     23 #endif
     24 
     25 #include <GLES/gl.h>
     26 #include <GLES/glext.h>
     27 #include <GLES2/gl2.h>
     28 #include <GLES2/gl2ext.h>
     29 
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include "ErrorLog.h"
     33 #include "codec_defs.h"
     34 
     35 class GLClientState {
     36 public:
     37     typedef enum {
     38         VERTEX_LOCATION = 0,
     39         NORMAL_LOCATION = 1,
     40         COLOR_LOCATION = 2,
     41         POINTSIZE_LOCATION = 3,
     42         TEXCOORD0_LOCATION = 4,
     43         TEXCOORD1_LOCATION = 5,
     44         TEXCOORD2_LOCATION = 6,
     45         TEXCOORD3_LOCATION = 7,
     46         TEXCOORD4_LOCATION = 8,
     47         TEXCOORD5_LOCATION = 9,
     48         TEXCOORD6_LOCATION = 10,
     49         TEXCOORD7_LOCATION = 11,
     50         MATRIXINDEX_LOCATION = 12,
     51         WEIGHT_LOCATION = 13,
     52         LAST_LOCATION = 14
     53     } StateLocation;
     54 
     55     typedef struct {
     56         GLint enabled;
     57         GLint size;
     58         GLenum type;
     59         GLsizei stride;
     60         void *data;
     61         GLuint bufferObject;
     62         GLenum glConst;
     63         unsigned int elementSize;
     64         bool enableDirty;  // true if any enable state has changed since last draw
     65         bool normalized;
     66     } VertexAttribState;
     67 
     68     typedef struct {
     69         int unpack_alignment;
     70         int pack_alignment;
     71     } PixelStoreState;
     72 
     73     enum {
     74         MAX_TEXTURE_UNITS = 32,
     75     };
     76 
     77 public:
     78     GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
     79     ~GLClientState();
     80     int nLocations() { return m_nLocations; }
     81     const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
     82     int setPixelStore(GLenum param, GLint value);
     83     GLuint currentArrayVbo() { return m_currentArrayVbo; }
     84     GLuint currentIndexVbo() { return m_currentIndexVbo; }
     85     void enable(int location, int state);
     86     void setState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
     87     void setBufferObject(int location, GLuint id);
     88     const VertexAttribState  *getState(int location);
     89     const VertexAttribState  *getStateAndEnableDirty(int location, bool *enableChanged);
     90     int getLocation(GLenum loc);
     91     void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
     92     int getActiveTexture() const { return m_activeTexture; }
     93 
     94     int bindBuffer(GLenum target, GLuint id)
     95     {
     96         int err = 0;
     97         switch(target) {
     98         case GL_ARRAY_BUFFER:
     99             m_currentArrayVbo = id;
    100             break;
    101         case GL_ELEMENT_ARRAY_BUFFER:
    102             m_currentIndexVbo = id;
    103             break;
    104         default:
    105             err = -1;
    106         }
    107         return err;
    108     }
    109 
    110     int getBuffer(GLenum target)
    111     {
    112       int ret=0;
    113       switch (target) {
    114       case GL_ARRAY_BUFFER:
    115           ret = m_currentArrayVbo;
    116           break;
    117       case GL_ELEMENT_ARRAY_BUFFER:
    118           ret = m_currentIndexVbo;
    119           break;
    120       default:
    121           ret = -1;
    122       }
    123       return ret;
    124     }
    125     size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;
    126 
    127     void setCurrentProgram(GLint program) { m_currentProgram = program; }
    128     GLint currentProgram() const { return m_currentProgram; }
    129 
    130     /* OES_EGL_image_external
    131      *
    132      * These functions manipulate GL state which interacts with the
    133      * OES_EGL_image_external extension, to support client-side emulation on
    134      * top of host implementations that don't have it.
    135      *
    136      * Most of these calls should only be used with TEXTURE_2D or
    137      * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
    138      * targets should bypass this. An exception is bindTexture(), which should
    139      * see all glBindTexture() calls for any target.
    140      */
    141 
    142     // glActiveTexture(GL_TEXTURE0 + i)
    143     // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
    144     GLenum setActiveTextureUnit(GLenum texture);
    145 
    146     // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
    147     void enableTextureTarget(GLenum target);
    148 
    149     // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
    150     void disableTextureTarget(GLenum target);
    151 
    152     // Implements the target priority logic:
    153     // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
    154     // * Return GL_TEXTURE_2D if enabled, else
    155     // * Return the allDisabled value.
    156     // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
    157     // simpler; for other cases passing a recognizable enum like GL_ZERO or
    158     // GL_INVALID_ENUM is appropriate.
    159     GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
    160 
    161     // glBindTexture(GL_TEXTURE_*, ...)
    162     // Set the target binding of the active texture unit to texture. Returns
    163     // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
    164     // previously been bound to a different target. If firstUse is not NULL,
    165     // it is set to indicate whether this is the first use of the texture.
    166     // For accurate error detection, bindTexture should be called for *all*
    167     // targets, not just 2D and EXTERNAL_OES.
    168     GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
    169 
    170     // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
    171     GLuint getBoundTexture(GLenum target) const;
    172 
    173     // glDeleteTextures(...)
    174     // Remove references to the to-be-deleted textures.
    175     void deleteTextures(GLsizei n, const GLuint* textures);
    176 
    177 private:
    178     PixelStoreState m_pixelStore;
    179     VertexAttribState *m_states;
    180     int m_nLocations;
    181     GLuint m_currentArrayVbo;
    182     GLuint m_currentIndexVbo;
    183     int m_activeTexture;
    184     GLint m_currentProgram;
    185 
    186     bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
    187 
    188     enum TextureTarget {
    189         TEXTURE_2D = 0,
    190         TEXTURE_EXTERNAL = 1,
    191         TEXTURE_TARGET_COUNT
    192     };
    193     struct TextureUnit {
    194         unsigned int enables;
    195         GLuint texture[TEXTURE_TARGET_COUNT];
    196     };
    197     struct TextureRec {
    198         GLuint id;
    199         GLenum target;
    200     };
    201     struct TextureState {
    202         TextureUnit unit[MAX_TEXTURE_UNITS];
    203         TextureUnit* activeUnit;
    204         TextureRec* textures;
    205         GLuint numTextures;
    206         GLuint allocTextures;
    207     };
    208     TextureState m_tex;
    209 
    210     static int compareTexId(const void* pid, const void* prec);
    211     TextureRec* addTextureRec(GLuint id, GLenum target);
    212 
    213 public:
    214     void getClientStatePointer(GLenum pname, GLvoid** params);
    215 
    216     template <class T>
    217     int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
    218     {
    219         bool handled = true;
    220         const VertexAttribState *vertexAttrib = getState(index);
    221         if (vertexAttrib == NULL) {
    222             ERR("getVeterxAttriParameter for non existant index %d\n", index);
    223             // set gl error;
    224             return handled;
    225         }
    226 
    227         switch(param) {
    228         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
    229             *ptr = (T)(vertexAttrib->bufferObject);
    230             break;
    231         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
    232             *ptr = (T)(vertexAttrib->enabled);
    233             break;
    234         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
    235             *ptr = (T)(vertexAttrib->size);
    236             break;
    237         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
    238             *ptr = (T)(vertexAttrib->stride);
    239             break;
    240         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
    241             *ptr = (T)(vertexAttrib->type);
    242             break;
    243         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
    244             *ptr = (T)(vertexAttrib->normalized);
    245             break;
    246         case GL_CURRENT_VERTEX_ATTRIB:
    247             handled = false;
    248             break;
    249         default:
    250             handled = false;
    251             ERR("unknown vertex-attrib parameter param %d\n", param);
    252         }
    253         return handled;
    254     }
    255 
    256     template <class T>
    257     bool getClientStateParameter(GLenum param, T* ptr)
    258     {
    259         bool isClientStateParam = false;
    260         switch (param) {
    261         case GL_CLIENT_ACTIVE_TEXTURE: {
    262             GLint tex = getActiveTexture() + GL_TEXTURE0;
    263             *ptr = tex;
    264             isClientStateParam = true;
    265             break;
    266             }
    267         case GL_VERTEX_ARRAY_SIZE: {
    268             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    269             *ptr = state->size;
    270             isClientStateParam = true;
    271             break;
    272             }
    273         case GL_VERTEX_ARRAY_TYPE: {
    274             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    275             *ptr = state->type;
    276             isClientStateParam = true;
    277             break;
    278             }
    279         case GL_VERTEX_ARRAY_STRIDE: {
    280             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    281             *ptr = state->stride;
    282             isClientStateParam = true;
    283             break;
    284             }
    285         case GL_COLOR_ARRAY_SIZE: {
    286             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    287             *ptr = state->size;
    288             isClientStateParam = true;
    289             break;
    290             }
    291         case GL_COLOR_ARRAY_TYPE: {
    292             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    293             *ptr = state->type;
    294             isClientStateParam = true;
    295             break;
    296             }
    297         case GL_COLOR_ARRAY_STRIDE: {
    298             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    299             *ptr = state->stride;
    300             isClientStateParam = true;
    301             break;
    302             }
    303         case GL_NORMAL_ARRAY_TYPE: {
    304             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    305             *ptr = state->type;
    306             isClientStateParam = true;
    307             break;
    308             }
    309         case GL_NORMAL_ARRAY_STRIDE: {
    310             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    311             *ptr = state->stride;
    312             isClientStateParam = true;
    313             break;
    314             }
    315         case GL_TEXTURE_COORD_ARRAY_SIZE: {
    316             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    317             *ptr = state->size;
    318             isClientStateParam = true;
    319             break;
    320             }
    321         case GL_TEXTURE_COORD_ARRAY_TYPE: {
    322             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    323             *ptr = state->type;
    324             isClientStateParam = true;
    325             break;
    326             }
    327         case GL_TEXTURE_COORD_ARRAY_STRIDE: {
    328             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    329             *ptr = state->stride;
    330             isClientStateParam = true;
    331             break;
    332             }
    333         case GL_POINT_SIZE_ARRAY_TYPE_OES: {
    334             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    335             *ptr = state->type;
    336             isClientStateParam = true;
    337             break;
    338             }
    339         case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
    340             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    341             *ptr = state->stride;
    342             isClientStateParam = true;
    343             break;
    344             }
    345         case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
    346             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    347             *ptr = state->size;
    348             isClientStateParam = true;
    349             break;
    350             }
    351         case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
    352             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    353             *ptr = state->type;
    354             isClientStateParam = true;
    355             break;
    356             }
    357         case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
    358             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    359             *ptr = state->stride;
    360             isClientStateParam = true;
    361             break;
    362             }
    363         case GL_WEIGHT_ARRAY_SIZE_OES: {
    364             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    365             *ptr = state->size;
    366             isClientStateParam = true;
    367             break;
    368             }
    369         case GL_WEIGHT_ARRAY_TYPE_OES: {
    370             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    371             *ptr = state->type;
    372             isClientStateParam = true;
    373             break;
    374             }
    375         case GL_WEIGHT_ARRAY_STRIDE_OES: {
    376             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    377             *ptr = state->stride;
    378             isClientStateParam = true;
    379             break;
    380             }
    381         case GL_VERTEX_ARRAY_BUFFER_BINDING: {
    382             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    383             *ptr = state->bufferObject;
    384             isClientStateParam = true;
    385             break;
    386             }
    387         case GL_NORMAL_ARRAY_BUFFER_BINDING: {
    388             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    389             *ptr = state->bufferObject;
    390             isClientStateParam = true;
    391             break;
    392             }
    393         case GL_COLOR_ARRAY_BUFFER_BINDING: {
    394             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    395             *ptr = state->bufferObject;
    396             isClientStateParam = true;
    397             break;
    398             }
    399         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
    400             const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
    401             *ptr = state->bufferObject;
    402             isClientStateParam = true;
    403             break;
    404             }
    405         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
    406             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    407             *ptr = state->bufferObject;
    408             isClientStateParam = true;
    409             break;
    410             }
    411         case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
    412             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    413             *ptr = state->bufferObject;
    414             isClientStateParam = true;
    415             break;
    416             }
    417         case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
    418             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    419             *ptr = state->bufferObject;
    420             isClientStateParam = true;
    421             break;
    422             }
    423         case GL_ARRAY_BUFFER_BINDING: {
    424             int buffer = getBuffer(GL_ARRAY_BUFFER);
    425             *ptr = buffer;
    426             isClientStateParam = true;
    427             break;
    428             }
    429         case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
    430             int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
    431             *ptr = buffer;
    432             isClientStateParam = true;
    433             break;
    434             }
    435         }
    436         return isClientStateParam;
    437     }
    438 
    439 };
    440 #endif
    441