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