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 "TextureSharedData.h"
     26 
     27 #include <GLES/gl.h>
     28 #include <GLES/glext.h>
     29 #include <GLES2/gl2.h>
     30 #include <GLES2/gl2ext.h>
     31 
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include "ErrorLog.h"
     35 #include "codec_defs.h"
     36 
     37 #include <vector>
     38 #include <map>
     39 #include <set>
     40 
     41 // Tracking framebuffer objects:
     42 // which framebuffer is bound,
     43 // and which texture names
     44 // are currently bound to which attachment points.
     45 struct FboProps {
     46     GLuint name;
     47     bool previouslyBound;
     48     std::vector<GLuint> colorAttachmenti_textures;
     49     GLuint depthAttachment_texture;
     50     GLuint stencilAttachment_texture;
     51     GLuint depthstencilAttachment_texture;
     52 
     53     std::vector<bool> colorAttachmenti_hasTex;
     54     bool depthAttachment_hasTexObj;
     55     bool stencilAttachment_hasTexObj;
     56     bool depthstencilAttachment_hasTexObj;
     57 
     58     std::vector<GLuint> colorAttachmenti_rbos;
     59     GLuint depthAttachment_rbo;
     60     GLuint stencilAttachment_rbo;
     61     GLuint depthstencilAttachment_rbo;
     62 
     63     std::vector<bool> colorAttachmenti_hasRbo;
     64     bool depthAttachment_hasRbo;
     65     bool stencilAttachment_hasRbo;
     66     bool depthstencilAttachment_hasRbo;
     67 };
     68 
     69 // Same for Rbo's
     70 struct RboProps {
     71     GLenum target;
     72     GLuint name;
     73     GLenum format;
     74     GLsizei multisamples;
     75     bool previouslyBound;
     76 };
     77 
     78 // Enum for describing whether a framebuffer attachment
     79 // is a texture or renderbuffer.
     80 enum FboAttachmentType {
     81     FBO_ATTACHMENT_RENDERBUFFER = 0,
     82     FBO_ATTACHMENT_TEXTURE = 1,
     83     FBO_ATTACHMENT_NONE = 2
     84 };
     85 
     86 // Tracking FBO format
     87 struct FboFormatInfo {
     88     FboAttachmentType type;
     89     GLenum rb_format;
     90     GLsizei rb_multisamples;
     91 
     92     GLint tex_internalformat;
     93     GLenum tex_format;
     94     GLenum tex_type;
     95     GLsizei tex_multisamples;
     96 };
     97 
     98 class GLClientState {
     99 public:
    100     typedef enum {
    101         VERTEX_LOCATION = 0,
    102         NORMAL_LOCATION = 1,
    103         COLOR_LOCATION = 2,
    104         POINTSIZE_LOCATION = 3,
    105         TEXCOORD0_LOCATION = 4,
    106         TEXCOORD1_LOCATION = 5,
    107         TEXCOORD2_LOCATION = 6,
    108         TEXCOORD3_LOCATION = 7,
    109         TEXCOORD4_LOCATION = 8,
    110         TEXCOORD5_LOCATION = 9,
    111         TEXCOORD6_LOCATION = 10,
    112         TEXCOORD7_LOCATION = 11,
    113         MATRIXINDEX_LOCATION = 12,
    114         WEIGHT_LOCATION = 13,
    115         LAST_LOCATION = 14
    116     } StateLocation;
    117 
    118     typedef struct {
    119         GLint enabled;
    120         GLint size;
    121         GLenum type;
    122         GLsizei stride;
    123         void *data;
    124         GLuint reloffset;
    125         GLuint bufferObject;
    126         GLenum glConst;
    127         unsigned int elementSize;
    128         bool enableDirty;  // true if any enable state has changed since last draw
    129         bool normalized;
    130         GLuint divisor;
    131         bool isInt;
    132         int bindingindex;
    133     } VertexAttribState;
    134 
    135     struct BufferBinding {
    136         GLintptr offset;
    137         GLintptr stride;
    138         GLintptr effectiveStride;
    139         GLsizeiptr size;
    140         GLuint buffer;
    141         GLuint divisor;
    142     };
    143 
    144     typedef std::vector<VertexAttribState> VertexAttribStateVector;
    145     typedef std::vector<BufferBinding> VertexAttribBindingVector;
    146 
    147     struct VAOState {
    148         VAOState(GLuint ibo, int nLoc, int nBindings) :
    149             element_array_buffer_binding(ibo),
    150             attribState(nLoc),
    151             bindingState(nBindings) { }
    152         VertexAttribStateVector attribState;
    153         VertexAttribBindingVector bindingState;
    154         GLuint element_array_buffer_binding;
    155     };
    156 
    157     typedef std::map<GLuint, VAOState> VAOStateMap;
    158     struct VAOStateRef {
    159         VAOStateRef() { }
    160         VAOStateRef(
    161                 VAOStateMap::iterator iter) : it(iter) { }
    162         VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; }
    163         BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; }
    164         VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; }
    165         const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; }
    166         GLuint vaoId() const { return it->first; }
    167         GLuint& iboId() { return it->second.element_array_buffer_binding; }
    168         VAOStateMap::iterator it;
    169     };
    170 
    171     typedef struct {
    172         int unpack_alignment;
    173 
    174         int unpack_row_length;
    175         int unpack_image_height;
    176         int unpack_skip_pixels;
    177         int unpack_skip_rows;
    178         int unpack_skip_images;
    179 
    180         int pack_alignment;
    181 
    182         int pack_row_length;
    183         int pack_skip_pixels;
    184         int pack_skip_rows;
    185     } PixelStoreState;
    186 
    187     enum {
    188         MAX_TEXTURE_UNITS = 256,
    189     };
    190 
    191 public:
    192     GLClientState();
    193     GLClientState(int majorVersion, int minorVersion);
    194     ~GLClientState();
    195     int nLocations() { return m_nLocations; }
    196     const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
    197     int setPixelStore(GLenum param, GLint value);
    198     GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); }
    199     const VertexAttribBindingVector& currentVertexBufferBindings() const {
    200         return m_currVaoState.bufferBindings_const();
    201     }
    202 
    203     GLuint currentArrayVbo() { return m_arrayBuffer; }
    204     GLuint currentIndexVbo() { return m_currVaoState.iboId(); }
    205     void enable(int location, int state);
    206     // Vertex array objects and vertex attributes
    207     void addVertexArrayObjects(GLsizei n, GLuint* arrays);
    208     void removeVertexArrayObjects(GLsizei n, const GLuint* arrays);
    209     void addVertexArrayObject(GLuint name);
    210     void removeVertexArrayObject(GLuint name);
    211     void setVertexArrayObject(GLuint vao);
    212     bool isVertexArrayObject(GLuint vao) const;
    213     void setVertexAttribState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt = false);
    214     void setVertexBindingDivisor(int bindingindex, GLuint divisor);
    215     const BufferBinding& getCurrAttributeBindingInfo(int attribindex);
    216     void setVertexAttribBinding(int attribindex, int bindingindex);
    217     void setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt = false);
    218     const VertexAttribState& getState(int location);
    219     const VertexAttribState& getStateAndEnableDirty(int location, bool *enableChanged);
    220     int getLocation(GLenum loc);
    221     void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
    222     int getActiveTexture() const { return m_activeTexture; }
    223     void setMaxVertexAttribs(int val) {
    224         m_maxVertexAttribs = val;
    225         m_maxVertexAttribsDirty = false;
    226     }
    227 
    228     void addBuffer(GLuint id);
    229     void removeBuffer(GLuint id);
    230     bool bufferIdExists(GLuint id) const;
    231     void unBindBuffer(GLuint id);
    232 
    233     int bindBuffer(GLenum target, GLuint id);
    234     void bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride);
    235     int getMaxIndexedBufferBindings(GLenum target) const;
    236 
    237     int getBuffer(GLenum target);
    238 
    239     size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
    240     size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
    241     size_t clearBufferNumElts(GLenum buffer) const;
    242     void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
    243 
    244     void setCurrentProgram(GLint program) { m_currentProgram = program; }
    245     void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; }
    246     GLint currentProgram() const { return m_currentProgram; }
    247     GLint currentShaderProgram() const { return m_currentShaderProgram; }
    248 
    249     struct UniformBlockInfoKey {
    250         GLuint program;
    251         GLuint uniformBlockIndex;
    252     };
    253     struct UniformBlockInfoKeyCompare {
    254         bool operator() (const UniformBlockInfoKey& a,
    255                          const UniformBlockInfoKey& b) const {
    256             if (a.program != b.program) return a.program < b.program;
    257             if (a.uniformBlockIndex != b.uniformBlockIndex) return a.uniformBlockIndex < b.uniformBlockIndex;
    258             return false;
    259         }
    260     };
    261     struct UniformBlockUniformInfo {
    262         size_t numActiveUniforms;
    263     };
    264 
    265     typedef std::map<UniformBlockInfoKey, UniformBlockUniformInfo, UniformBlockInfoKeyCompare> UniformBlockInfoMap;
    266     UniformBlockInfoMap m_uniformBlockInfoMap;
    267 
    268     void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
    269     size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
    270 
    271     typedef std::map<GLuint, GLuint> ProgramPipelineMap;
    272     typedef ProgramPipelineMap::iterator ProgramPipelineIterator;
    273     void associateProgramWithPipeline(GLuint program, GLuint pipeline);
    274     ProgramPipelineIterator programPipelineBegin();
    275     ProgramPipelineIterator programPipelineEnd();
    276 
    277     /* OES_EGL_image_external
    278      *
    279      * These functions manipulate GL state which interacts with the
    280      * OES_EGL_image_external extension, to support client-side emulation on
    281      * top of host implementations that don't have it.
    282      *
    283      * Most of these calls should only be used with TEXTURE_2D or
    284      * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
    285      * targets should bypass this. An exception is bindTexture(), which should
    286      * see all glBindTexture() calls for any target.
    287      */
    288 
    289     // glActiveTexture(GL_TEXTURE0 + i)
    290     // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
    291     GLenum setActiveTextureUnit(GLenum texture);
    292     GLenum getActiveTextureUnit() const;
    293 
    294     // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
    295     void enableTextureTarget(GLenum target);
    296 
    297     // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
    298     void disableTextureTarget(GLenum target);
    299 
    300     // Implements the target priority logic:
    301     // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
    302     // * Return GL_TEXTURE_2D if enabled, else
    303     // * Return the allDisabled value.
    304     // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
    305     // simpler; for other cases passing a recognizable enum like GL_ZERO or
    306     // GL_INVALID_ENUM is appropriate.
    307     GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
    308 
    309     // glBindTexture(GL_TEXTURE_*, ...)
    310     // Set the target binding of the active texture unit to texture. Returns
    311     // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
    312     // previously been bound to a different target. If firstUse is not NULL,
    313     // it is set to indicate whether this is the first use of the texture.
    314     // For accurate error detection, bindTexture should be called for *all*
    315     // targets, not just 2D and EXTERNAL_OES.
    316     GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
    317     void setBoundEGLImage(GLenum target, GLeglImageOES image);
    318 
    319     // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
    320     GLuint getBoundTexture(GLenum target) const;
    321     // Other publicly-visible texture queries
    322     GLenum queryTexLastBoundTarget(GLuint name) const;
    323     GLenum queryTexFormat(GLuint name) const;
    324     GLint queryTexInternalFormat(GLuint name) const;
    325     GLsizei queryTexWidth(GLsizei level, GLuint name) const;
    326     GLsizei queryTexHeight(GLsizei level, GLuint name) const;
    327     GLsizei queryTexDepth(GLsizei level, GLuint name) const;
    328     bool queryTexEGLImageBacked(GLuint name) const;
    329 
    330     // For AMD GPUs, it is easy for the emulator to segfault
    331     // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
    332     // and uses GL_LUMINANCE as internal format.
    333     // In particular, the segfault happens when negative components of
    334     // cube maps are defined before positive ones,
    335     // This procedure checks internal state to see if we have defined
    336     // the positive component of a cube map already. If not, it returns
    337     // which positive component needs to be defined first.
    338     // If there is no need for the extra definition, 0 is returned.
    339     GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level,
    340                                                      GLenum internalformat);
    341 
    342     // Tracks the format of the currently bound texture.
    343     // This is to pass dEQP tests for fbo completeness.
    344     void setBoundTextureInternalFormat(GLenum target, GLint format);
    345     void setBoundTextureFormat(GLenum target, GLenum format);
    346     void setBoundTextureType(GLenum target, GLenum type);
    347     void setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
    348     void setBoundTextureSamples(GLenum target, GLsizei samples);
    349 
    350     // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
    351     void setBoundTextureImmutableFormat(GLenum target);
    352     bool isBoundTextureImmutableFormat(GLenum target) const;
    353 
    354     // glDeleteTextures(...)
    355     // Remove references to the to-be-deleted textures.
    356     void deleteTextures(GLsizei n, const GLuint* textures);
    357 
    358     // Render buffer objects
    359     void addRenderbuffers(GLsizei n, GLuint* renderbuffers);
    360     void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers);
    361     bool usedRenderbufferName(GLuint name) const;
    362     void bindRenderbuffer(GLenum target, GLuint name);
    363     GLuint boundRenderbuffer() const;
    364     void setBoundRenderbufferFormat(GLenum format);
    365     void setBoundRenderbufferSamples(GLsizei samples);
    366 
    367     // Frame buffer objects
    368     void addFramebuffers(GLsizei n, GLuint* framebuffers);
    369     void removeFramebuffers(GLsizei n, const GLuint* framebuffers);
    370     bool usedFramebufferName(GLuint name) const;
    371     void bindFramebuffer(GLenum target, GLuint name);
    372     void setCheckFramebufferStatus(GLenum target, GLenum status);
    373     GLenum getCheckFramebufferStatus(GLenum target) const;
    374     GLuint boundFramebuffer(GLenum target) const;
    375 
    376     // Texture object -> FBO
    377     void attachTextureObject(GLenum target, GLenum attachment, GLuint texture);
    378     GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const;
    379 
    380     // RBO -> FBO
    381     void detachRbo(GLuint renderbuffer);
    382     void detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer);
    383     void attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer);
    384     GLuint getFboAttachmentRboId(GLenum target, GLenum attachment) const;
    385 
    386     // FBO attachments in general
    387     bool attachmentHasObject(GLenum target, GLenum attachment) const;
    388     GLuint objectOfAttachment(GLenum target, GLenum attachment) const;
    389 
    390     // Transform feedback state
    391     void setTransformFeedbackActiveUnpaused(bool activeUnpaused);
    392     bool getTransformFeedbackActiveUnpaused() const;
    393 
    394     void setTextureData(SharedTextureDataMap* sharedTexData);
    395     // set eglsurface property on default framebuffer
    396     // if coming from eglMakeCurrent
    397     void fromMakeCurrent();
    398     // set indexed buffer state.
    399     // We need to query the underlying OpenGL to get
    400     // accurate values for indexed buffers
    401     // and # render targets.
    402     void initFromCaps(
    403         int max_transform_feedback_separate_attribs,
    404         int max_uniform_buffer_bindings,
    405         int max_atomic_counter_buffer_bindings,
    406         int max_shader_storage_buffer_bindings,
    407         int max_vertex_attrib_bindings,
    408         int max_color_attachments,
    409         int max_draw_buffers);
    410     bool needsInitFromCaps() const;
    411 
    412     // Queries the format backing the current framebuffer.
    413     // Type differs depending on whether the attachment
    414     // is a texture or renderbuffer.
    415     void getBoundFramebufferFormat(
    416             GLenum target,
    417             GLenum attachment,
    418             FboFormatInfo* res_info) const;
    419     FboAttachmentType getBoundFramebufferAttachmentType(
    420             GLenum target,
    421             GLenum attachment) const;
    422     int getMaxColorAttachments() const;
    423     int getMaxDrawBuffers() const;
    424 private:
    425     void init();
    426     bool m_initialized;
    427     PixelStoreState m_pixelStore;
    428 
    429     std::set<GLuint> mBufferIds;
    430 
    431     // GL_ARRAY_BUFFER_BINDING is separate from VAO state
    432     GLuint m_arrayBuffer;
    433     VAOStateMap m_vaoMap;
    434     VAOStateRef m_currVaoState;
    435 
    436     // Other buffer id's, other targets
    437     GLuint m_copyReadBuffer;
    438     GLuint m_copyWriteBuffer;
    439 
    440     GLuint m_pixelPackBuffer;
    441     GLuint m_pixelUnpackBuffer;
    442 
    443     GLuint m_transformFeedbackBuffer;
    444     GLuint m_uniformBuffer;
    445 
    446     GLuint m_atomicCounterBuffer;
    447     GLuint m_dispatchIndirectBuffer;
    448     GLuint m_drawIndirectBuffer;
    449     GLuint m_shaderStorageBuffer;
    450 
    451     bool m_transformFeedbackActiveUnpaused;
    452 
    453     int m_max_transform_feedback_separate_attribs;
    454     int m_max_uniform_buffer_bindings;
    455     int m_max_atomic_counter_buffer_bindings;
    456     int m_max_shader_storage_buffer_bindings;
    457     int m_max_vertex_attrib_bindings;
    458     std::vector<BufferBinding> m_indexedTransformFeedbackBuffers;
    459     std::vector<BufferBinding> m_indexedUniformBuffers;
    460     std::vector<BufferBinding> m_indexedAtomicCounterBuffers;
    461     std::vector<BufferBinding> m_indexedShaderStorageBuffers;
    462 
    463     int m_glesMajorVersion;
    464     int m_glesMinorVersion;
    465     int m_maxVertexAttribs;
    466     bool m_maxVertexAttribsDirty;
    467     int m_nLocations;
    468     int m_activeTexture;
    469     GLint m_currentProgram;
    470     GLint m_currentShaderProgram;
    471     ProgramPipelineMap m_programPipelines;
    472 
    473     enum TextureTarget {
    474         TEXTURE_2D = 0,
    475         TEXTURE_EXTERNAL = 1,
    476         TEXTURE_CUBE_MAP = 2,
    477         TEXTURE_2D_ARRAY = 3,
    478         TEXTURE_3D = 4,
    479         TEXTURE_2D_MULTISAMPLE = 5,
    480         TEXTURE_TARGET_COUNT
    481     };
    482     struct TextureUnit {
    483         unsigned int enables;
    484         GLuint texture[TEXTURE_TARGET_COUNT];
    485     };
    486     struct TextureState {
    487         TextureUnit unit[MAX_TEXTURE_UNITS];
    488         TextureUnit* activeUnit;
    489         // Initialized from shared group.
    490         SharedTextureDataMap* textureRecs;
    491     };
    492     TextureState m_tex;
    493 
    494     // State tracking of cube map definitions.
    495     // Currently used only for driver workarounds
    496     // when using GL_LUMINANCE and defining cube maps with
    497     // glCopyTexImage2D.
    498     struct CubeMapDef {
    499         GLuint id;
    500         GLenum target;
    501         GLint level;
    502         GLenum internalformat;
    503     };
    504     struct CubeMapDefCompare {
    505         bool operator() (const CubeMapDef& a,
    506                          const CubeMapDef& b) const {
    507             if (a.id != b.id) return a.id < b.id;
    508             if (a.target != b.target) return a.target < b.target;
    509             if (a.level != b.level) return a.level < b.level;
    510             if (a.internalformat != b.internalformat)
    511                 return a.internalformat < b.internalformat;
    512             return false;
    513         }
    514     };
    515     std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs;
    516     void writeCopyTexImageState(GLenum target, GLint level,
    517                                 GLenum internalformat);
    518     GLenum copyTexImageNeededTarget(GLenum target, GLint level,
    519                                     GLenum internalformat);
    520 
    521     int m_max_color_attachments;
    522     int m_max_draw_buffers;
    523     struct RboState {
    524         GLuint boundRenderbuffer;
    525         size_t boundRenderbufferIndex;
    526         std::vector<RboProps> rboData;
    527     };
    528     RboState mRboState;
    529     void addFreshRenderbuffer(GLuint name);
    530     void setBoundRenderbufferIndex();
    531     size_t getRboIndex(GLuint name) const;
    532     RboProps& boundRboProps();
    533     const RboProps& boundRboProps_const() const;
    534 
    535     struct FboState {
    536         GLuint boundDrawFramebuffer;
    537         GLuint boundReadFramebuffer;
    538         size_t boundFramebufferIndex;
    539         std::map<GLuint, FboProps> fboData;
    540         GLenum drawFboCheckStatus;
    541         GLenum readFboCheckStatus;
    542     };
    543     FboState mFboState;
    544     void addFreshFramebuffer(GLuint name);
    545     FboProps& boundFboProps(GLenum target);
    546     const FboProps& boundFboProps_const(GLenum target) const;
    547 
    548     // Querying framebuffer format
    549     GLenum queryRboFormat(GLuint name) const;
    550     GLsizei queryRboSamples(GLuint name) const;
    551     GLenum queryTexType(GLuint name) const;
    552     GLsizei queryTexSamples(GLuint name) const;
    553 
    554     static int compareTexId(const void* pid, const void* prec);
    555     TextureRec* addTextureRec(GLuint id, GLenum target);
    556     TextureRec* getTextureRec(GLuint id) const;
    557 
    558 public:
    559     void getClientStatePointer(GLenum pname, GLvoid** params);
    560 
    561     template <class T>
    562     int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
    563     {
    564         bool handled = true;
    565         const VertexAttribState& vertexAttrib = getState(index);
    566         const BufferBinding& vertexAttribBufferBinding =
    567             m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex];
    568 
    569         switch(param) {
    570 #define GL_VERTEX_ATTRIB_BINDING 0x82D4
    571         case GL_VERTEX_ATTRIB_BINDING:
    572             *ptr = (T)vertexAttrib.bindingindex;
    573             break;
    574 #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
    575         case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
    576             *ptr = (T)vertexAttrib.reloffset;
    577             break;
    578         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
    579             *ptr = (T)(vertexAttribBufferBinding.buffer);
    580             break;
    581         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
    582             *ptr = (T)(vertexAttrib.enabled);
    583             break;
    584 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
    585         case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
    586             *ptr = (T)(vertexAttrib.isInt);
    587             break;
    588         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
    589             *ptr = (T)(vertexAttrib.size);
    590             break;
    591         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
    592             *ptr = (T)(vertexAttribBufferBinding.stride);
    593             break;
    594         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
    595             *ptr = (T)(vertexAttrib.type);
    596             break;
    597         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
    598             *ptr = (T)(vertexAttrib.normalized);
    599             break;
    600         case GL_CURRENT_VERTEX_ATTRIB:
    601             handled = false;
    602             break;
    603         default:
    604             handled = false;
    605             ERR("unknown vertex-attrib parameter param %d\n", param);
    606         }
    607         return handled;
    608     }
    609 
    610     template <class T>
    611     bool getClientStateParameter(GLenum param, T* out)
    612     {
    613         bool isClientStateParam = false;
    614         switch (param) {
    615         case GL_CLIENT_ACTIVE_TEXTURE: {
    616             GLint tex = getActiveTexture() + GL_TEXTURE0;
    617             *out = tex;
    618             isClientStateParam = true;
    619             break;
    620             }
    621         case GL_VERTEX_ARRAY_SIZE: {
    622             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
    623             *out = state.size;
    624             isClientStateParam = true;
    625             break;
    626             }
    627         case GL_VERTEX_ARRAY_TYPE: {
    628             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
    629             *out = state.type;
    630             isClientStateParam = true;
    631             break;
    632             }
    633         case GL_VERTEX_ARRAY_STRIDE: {
    634             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
    635             *out = state.stride;
    636             isClientStateParam = true;
    637             break;
    638             }
    639         case GL_COLOR_ARRAY_SIZE: {
    640             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
    641             *out = state.size;
    642             isClientStateParam = true;
    643             break;
    644             }
    645         case GL_COLOR_ARRAY_TYPE: {
    646             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
    647             *out = state.type;
    648             isClientStateParam = true;
    649             break;
    650             }
    651         case GL_COLOR_ARRAY_STRIDE: {
    652             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
    653             *out = state.stride;
    654             isClientStateParam = true;
    655             break;
    656             }
    657         case GL_NORMAL_ARRAY_TYPE: {
    658             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
    659             *out = state.type;
    660             isClientStateParam = true;
    661             break;
    662             }
    663         case GL_NORMAL_ARRAY_STRIDE: {
    664             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
    665             *out = state.stride;
    666             isClientStateParam = true;
    667             break;
    668             }
    669         case GL_TEXTURE_COORD_ARRAY_SIZE: {
    670             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    671             *out = state.size;
    672             isClientStateParam = true;
    673             break;
    674             }
    675         case GL_TEXTURE_COORD_ARRAY_TYPE: {
    676             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    677             *out = state.type;
    678             isClientStateParam = true;
    679             break;
    680             }
    681         case GL_TEXTURE_COORD_ARRAY_STRIDE: {
    682             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
    683             *out = state.stride;
    684             isClientStateParam = true;
    685             break;
    686             }
    687         case GL_POINT_SIZE_ARRAY_TYPE_OES: {
    688             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
    689             *out = state.type;
    690             isClientStateParam = true;
    691             break;
    692             }
    693         case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
    694             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
    695             *out = state.stride;
    696             isClientStateParam = true;
    697             break;
    698             }
    699         case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
    700             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
    701             *out = state.size;
    702             isClientStateParam = true;
    703             break;
    704             }
    705         case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
    706             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
    707             *out = state.type;
    708             isClientStateParam = true;
    709             break;
    710             }
    711         case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
    712             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
    713             *out = state.stride;
    714             isClientStateParam = true;
    715             break;
    716             }
    717         case GL_WEIGHT_ARRAY_SIZE_OES: {
    718             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
    719             *out = state.size;
    720             isClientStateParam = true;
    721             break;
    722             }
    723         case GL_WEIGHT_ARRAY_TYPE_OES: {
    724             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
    725             *out = state.type;
    726             isClientStateParam = true;
    727             break;
    728             }
    729         case GL_WEIGHT_ARRAY_STRIDE_OES: {
    730             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
    731             *out = state.stride;
    732             isClientStateParam = true;
    733             break;
    734             }
    735         case GL_VERTEX_ARRAY_BUFFER_BINDING: {
    736             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
    737             *out = state.bufferObject;
    738             isClientStateParam = true;
    739             break;
    740             }
    741         case GL_NORMAL_ARRAY_BUFFER_BINDING: {
    742             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
    743             *out = state.bufferObject;
    744             isClientStateParam = true;
    745             break;
    746             }
    747         case GL_COLOR_ARRAY_BUFFER_BINDING: {
    748             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
    749             *out = state.bufferObject;
    750             isClientStateParam = true;
    751             break;
    752             }
    753         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
    754             const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
    755             *out = state.bufferObject;
    756             isClientStateParam = true;
    757             break;
    758             }
    759         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
    760             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
    761             *out = state.bufferObject;
    762             isClientStateParam = true;
    763             break;
    764             }
    765         case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
    766             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
    767             *out = state.bufferObject;
    768             isClientStateParam = true;
    769             break;
    770             }
    771         case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
    772             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
    773             *out = state.bufferObject;
    774             isClientStateParam = true;
    775             break;
    776             }
    777         case GL_ARRAY_BUFFER_BINDING: {
    778             int buffer = getBuffer(GL_ARRAY_BUFFER);
    779             *out = buffer;
    780             isClientStateParam = true;
    781             break;
    782             }
    783         case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
    784             int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
    785             *out = buffer;
    786             isClientStateParam = true;
    787             break;
    788             }
    789         case GL_MAX_VERTEX_ATTRIBS: {
    790             if (m_maxVertexAttribsDirty) {
    791                 isClientStateParam = false;
    792             } else {
    793                 *out = m_maxVertexAttribs;
    794                 isClientStateParam = true;
    795             }
    796             break;
    797         }
    798         }
    799         return isClientStateParam;
    800     }
    801 
    802 };
    803 #endif
    804