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