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     GLenum getActiveTextureUnit() const;
    146 
    147     // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
    148     void enableTextureTarget(GLenum target);
    149 
    150     // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
    151     void disableTextureTarget(GLenum target);
    152 
    153     // Implements the target priority logic:
    154     // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
    155     // * Return GL_TEXTURE_2D if enabled, else
    156     // * Return the allDisabled value.
    157     // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
    158     // simpler; for other cases passing a recognizable enum like GL_ZERO or
    159     // GL_INVALID_ENUM is appropriate.
    160     GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
    161 
    162     // glBindTexture(GL_TEXTURE_*, ...)
    163     // Set the target binding of the active texture unit to texture. Returns
    164     // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
    165     // previously been bound to a different target. If firstUse is not NULL,
    166     // it is set to indicate whether this is the first use of the texture.
    167     // For accurate error detection, bindTexture should be called for *all*
    168     // targets, not just 2D and EXTERNAL_OES.
    169     GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
    170 
    171     // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
    172     GLuint getBoundTexture(GLenum target) const;
    173 
    174     // glDeleteTextures(...)
    175     // Remove references to the to-be-deleted textures.
    176     void deleteTextures(GLsizei n, const GLuint* textures);
    177 
    178 private:
    179     PixelStoreState m_pixelStore;
    180     VertexAttribState *m_states;
    181     int m_nLocations;
    182     GLuint m_currentArrayVbo;
    183     GLuint m_currentIndexVbo;
    184     int m_activeTexture;
    185     GLint m_currentProgram;
    186 
    187     bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
    188 
    189     enum TextureTarget {
    190         TEXTURE_2D = 0,
    191         TEXTURE_EXTERNAL = 1,
    192         TEXTURE_TARGET_COUNT
    193     };
    194     struct TextureUnit {
    195         unsigned int enables;
    196         GLuint texture[TEXTURE_TARGET_COUNT];
    197     };
    198     struct TextureRec {
    199         GLuint id;
    200         GLenum target;
    201     };
    202     struct TextureState {
    203         TextureUnit unit[MAX_TEXTURE_UNITS];
    204         TextureUnit* activeUnit;
    205         TextureRec* textures;
    206         GLuint numTextures;
    207         GLuint allocTextures;
    208     };
    209     TextureState m_tex;
    210 
    211     static int compareTexId(const void* pid, const void* prec);
    212     TextureRec* addTextureRec(GLuint id, GLenum target);
    213 
    214 public:
    215     void getClientStatePointer(GLenum pname, GLvoid** params);
    216 
    217     template <class T>
    218     int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
    219     {
    220         bool handled = true;
    221         const VertexAttribState *vertexAttrib = getState(index);
    222         if (vertexAttrib == NULL) {
    223             ERR("getVeterxAttriParameter for non existant index %d\n", index);
    224             // set gl error;
    225             return handled;
    226         }
    227 
    228         switch(param) {
    229         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
    230             *ptr = (T)(vertexAttrib->bufferObject);
    231             break;
    232         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
    233             *ptr = (T)(vertexAttrib->enabled);
    234             break;
    235         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
    236             *ptr = (T)(vertexAttrib->size);
    237             break;
    238         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
    239             *ptr = (T)(vertexAttrib->stride);
    240             break;
    241         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
    242             *ptr = (T)(vertexAttrib->type);
    243             break;
    244         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
    245             *ptr = (T)(vertexAttrib->normalized);
    246             break;
    247         case GL_CURRENT_VERTEX_ATTRIB:
    248             handled = false;
    249             break;
    250         default:
    251             handled = false;
    252             ERR("unknown vertex-attrib parameter param %d\n", param);
    253         }
    254         return handled;
    255     }
    256 
    257     template <class T>
    258     bool getClientStateParameter(GLenum param, T* ptr)
    259     {
    260         bool isClientStateParam = false;
    261         switch (param) {
    262         case GL_CLIENT_ACTIVE_TEXTURE: {
    263             GLint tex = getActiveTexture() + GL_TEXTURE0;
    264             *ptr = tex;
    265             isClientStateParam = true;
    266             break;
    267             }
    268         case GL_VERTEX_ARRAY_SIZE: {
    269             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    270             *ptr = state->size;
    271             isClientStateParam = true;
    272             break;
    273             }
    274         case GL_VERTEX_ARRAY_TYPE: {
    275             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    276             *ptr = state->type;
    277             isClientStateParam = true;
    278             break;
    279             }
    280         case GL_VERTEX_ARRAY_STRIDE: {
    281             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    282             *ptr = state->stride;
    283             isClientStateParam = true;
    284             break;
    285             }
    286         case GL_COLOR_ARRAY_SIZE: {
    287             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    288             *ptr = state->size;
    289             isClientStateParam = true;
    290             break;
    291             }
    292         case GL_COLOR_ARRAY_TYPE: {
    293             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    294             *ptr = state->type;
    295             isClientStateParam = true;
    296             break;
    297             }
    298         case GL_COLOR_ARRAY_STRIDE: {
    299             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    300             *ptr = state->stride;
    301             isClientStateParam = true;
    302             break;
    303             }
    304         case GL_NORMAL_ARRAY_TYPE: {
    305             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    306             *ptr = state->type;
    307             isClientStateParam = true;
    308             break;
    309             }
    310         case GL_NORMAL_ARRAY_STRIDE: {
    311             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    312             *ptr = state->stride;
    313             isClientStateParam = true;
    314             break;
    315             }
    316         case GL_TEXTURE_COORD_ARRAY_SIZE: {
    317             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    318             *ptr = state->size;
    319             isClientStateParam = true;
    320             break;
    321             }
    322         case GL_TEXTURE_COORD_ARRAY_TYPE: {
    323             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    324             *ptr = state->type;
    325             isClientStateParam = true;
    326             break;
    327             }
    328         case GL_TEXTURE_COORD_ARRAY_STRIDE: {
    329             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    330             *ptr = state->stride;
    331             isClientStateParam = true;
    332             break;
    333             }
    334         case GL_POINT_SIZE_ARRAY_TYPE_OES: {
    335             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    336             *ptr = state->type;
    337             isClientStateParam = true;
    338             break;
    339             }
    340         case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
    341             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    342             *ptr = state->stride;
    343             isClientStateParam = true;
    344             break;
    345             }
    346         case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
    347             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    348             *ptr = state->size;
    349             isClientStateParam = true;
    350             break;
    351             }
    352         case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
    353             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    354             *ptr = state->type;
    355             isClientStateParam = true;
    356             break;
    357             }
    358         case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
    359             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    360             *ptr = state->stride;
    361             isClientStateParam = true;
    362             break;
    363             }
    364         case GL_WEIGHT_ARRAY_SIZE_OES: {
    365             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    366             *ptr = state->size;
    367             isClientStateParam = true;
    368             break;
    369             }
    370         case GL_WEIGHT_ARRAY_TYPE_OES: {
    371             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    372             *ptr = state->type;
    373             isClientStateParam = true;
    374             break;
    375             }
    376         case GL_WEIGHT_ARRAY_STRIDE_OES: {
    377             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    378             *ptr = state->stride;
    379             isClientStateParam = true;
    380             break;
    381             }
    382         case GL_VERTEX_ARRAY_BUFFER_BINDING: {
    383             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
    384             *ptr = state->bufferObject;
    385             isClientStateParam = true;
    386             break;
    387             }
    388         case GL_NORMAL_ARRAY_BUFFER_BINDING: {
    389             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
    390             *ptr = state->bufferObject;
    391             isClientStateParam = true;
    392             break;
    393             }
    394         case GL_COLOR_ARRAY_BUFFER_BINDING: {
    395             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
    396             *ptr = state->bufferObject;
    397             isClientStateParam = true;
    398             break;
    399             }
    400         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
    401             const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
    402             *ptr = state->bufferObject;
    403             isClientStateParam = true;
    404             break;
    405             }
    406         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
    407             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
    408             *ptr = state->bufferObject;
    409             isClientStateParam = true;
    410             break;
    411             }
    412         case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
    413             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
    414             *ptr = state->bufferObject;
    415             isClientStateParam = true;
    416             break;
    417             }
    418         case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
    419             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
    420             *ptr = state->bufferObject;
    421             isClientStateParam = true;
    422             break;
    423             }
    424         case GL_ARRAY_BUFFER_BINDING: {
    425             int buffer = getBuffer(GL_ARRAY_BUFFER);
    426             *ptr = buffer;
    427             isClientStateParam = true;
    428             break;
    429             }
    430         case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
    431             int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
    432             *ptr = buffer;
    433             isClientStateParam = true;
    434             break;
    435             }
    436         }
    437         return isClientStateParam;
    438     }
    439 
    440 };
    441 #endif
    442