OSDN Git Service

e1fb64dce8a83a0f5603e5af94569376fd395cec
[android-x86/device-generic-goldfish-opengl.git] / shared / OpenglCodecCommon / GLClientState.h
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     GLenum target;
47     GLuint name;
48     bool previouslyBound;
49     GLuint colorAttachment0_texture;
50     GLuint depthAttachment_texture;
51     GLuint stencilAttachment_texture;
52
53     bool colorAttachment0_hasTexObj;
54     bool depthAttachment_hasTexObj;
55     bool stencilAttachment_hasTexObj;
56
57     GLuint colorAttachment0_rbo;
58     GLuint depthAttachment_rbo;
59     GLuint stencilAttachment_rbo;
60
61     bool colorAttachment0_hasRbo;
62     bool depthAttachment_hasRbo;
63     bool stencilAttachment_hasRbo;
64 };
65
66 // Same for Rbo's
67 struct RboProps {
68     GLenum target;
69     GLuint name;
70     GLenum format;
71     bool previouslyBound;
72 };
73
74 // Enum for describing whether a framebuffer attachment
75 // is a texture or renderbuffer.
76 enum FboAttachmentType {
77     FBO_ATTACHMENT_RENDERBUFFER = 0,
78     FBO_ATTACHMENT_TEXTURE = 1,
79     FBO_ATTACHMENT_NONE = 2
80 };
81
82 // Tracking FBO format
83 struct FboFormatInfo {
84     FboAttachmentType type;
85     GLenum rb_format;
86     GLint tex_internalformat;
87     GLenum tex_format;
88     GLenum tex_type;
89     GLsizei tex_multisamples;
90 };
91
92 class GLClientState {
93 public:
94     typedef enum {
95         VERTEX_LOCATION = 0,
96         NORMAL_LOCATION = 1,
97         COLOR_LOCATION = 2,
98         POINTSIZE_LOCATION = 3,
99         TEXCOORD0_LOCATION = 4,
100         TEXCOORD1_LOCATION = 5,
101         TEXCOORD2_LOCATION = 6,
102         TEXCOORD3_LOCATION = 7,
103         TEXCOORD4_LOCATION = 8,
104         TEXCOORD5_LOCATION = 9,
105         TEXCOORD6_LOCATION = 10,
106         TEXCOORD7_LOCATION = 11,
107         MATRIXINDEX_LOCATION = 12,
108         WEIGHT_LOCATION = 13,
109         LAST_LOCATION = 14
110     } StateLocation;
111
112     typedef struct {
113         GLint enabled;
114         GLint size;
115         GLenum type;
116         GLsizei stride;
117         void *data;
118         GLuint bufferObject;
119         GLenum glConst;
120         unsigned int elementSize;
121         bool enableDirty;  // true if any enable state has changed since last draw
122         bool normalized;
123     } VertexAttribState;
124
125     typedef struct {
126         int unpack_alignment;
127
128         int unpack_row_length;
129         int unpack_image_height;
130         int unpack_skip_pixels;
131         int unpack_skip_rows;
132         int unpack_skip_images;
133
134         int pack_alignment;
135
136         int pack_row_length;
137         int pack_skip_pixels;
138         int pack_skip_rows;
139     } PixelStoreState;
140
141     enum {
142         MAX_TEXTURE_UNITS = 256,
143     };
144
145 public:
146     GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
147     ~GLClientState();
148     int nLocations() { return m_nLocations; }
149     const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
150     int setPixelStore(GLenum param, GLint value);
151     GLuint currentArrayVbo() { return m_currentArrayVbo; }
152     GLuint currentIndexVbo() { return m_currentIndexVbo; }
153     void enable(int location, int state);
154     void setState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
155     void setBufferObject(int location, GLuint id);
156     const VertexAttribState  *getState(int location);
157     const VertexAttribState  *getStateAndEnableDirty(int location, bool *enableChanged);
158     int getLocation(GLenum loc);
159     void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
160     int getActiveTexture() const { return m_activeTexture; }
161     void setMaxVertexAttribs(int val) {
162         m_maxVertexAttribs = val;
163         m_maxVertexAttribsDirty = false;
164     }
165
166     void unBindBuffer(GLuint id)
167     {
168         if (m_currentArrayVbo == id) m_currentArrayVbo = 0;
169         else if (m_currentIndexVbo == id) m_currentIndexVbo = 0;
170     }
171
172     int bindBuffer(GLenum target, GLuint id)
173     {
174         int err = 0;
175         switch(target) {
176         case GL_ARRAY_BUFFER:
177             m_currentArrayVbo = id;
178             break;
179         case GL_ELEMENT_ARRAY_BUFFER:
180             m_currentIndexVbo = id;
181             break;
182         default:
183             err = -1;
184         }
185         return err;
186     }
187
188     int getBuffer(GLenum target)
189     {
190       int ret=0;
191       switch (target) {
192       case GL_ARRAY_BUFFER:
193           ret = m_currentArrayVbo;
194           break;
195       case GL_ELEMENT_ARRAY_BUFFER:
196           ret = m_currentIndexVbo;
197           break;
198       default:
199           ret = -1;
200       }
201       return ret;
202     }
203     size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
204     size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
205     size_t clearBufferNumElts(GLenum buffer) const;
206
207     void setCurrentProgram(GLint program) { m_currentProgram = program; }
208     GLint currentProgram() const { return m_currentProgram; }
209
210     void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
211     size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
212     /* OES_EGL_image_external
213      *
214      * These functions manipulate GL state which interacts with the
215      * OES_EGL_image_external extension, to support client-side emulation on
216      * top of host implementations that don't have it.
217      *
218      * Most of these calls should only be used with TEXTURE_2D or
219      * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
220      * targets should bypass this. An exception is bindTexture(), which should
221      * see all glBindTexture() calls for any target.
222      */
223
224     // glActiveTexture(GL_TEXTURE0 + i)
225     // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
226     GLenum setActiveTextureUnit(GLenum texture);
227     GLenum getActiveTextureUnit() const;
228
229     // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
230     void enableTextureTarget(GLenum target);
231
232     // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
233     void disableTextureTarget(GLenum target);
234
235     // Implements the target priority logic:
236     // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
237     // * Return GL_TEXTURE_2D if enabled, else
238     // * Return the allDisabled value.
239     // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
240     // simpler; for other cases passing a recognizable enum like GL_ZERO or
241     // GL_INVALID_ENUM is appropriate.
242     GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
243
244     // glBindTexture(GL_TEXTURE_*, ...)
245     // Set the target binding of the active texture unit to texture. Returns
246     // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
247     // previously been bound to a different target. If firstUse is not NULL,
248     // it is set to indicate whether this is the first use of the texture.
249     // For accurate error detection, bindTexture should be called for *all*
250     // targets, not just 2D and EXTERNAL_OES.
251     GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
252     void setBoundEGLImage(GLenum target, GLeglImageOES image);
253
254     // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
255     GLuint getBoundTexture(GLenum target) const;
256     // Other publicly-visible texture queries
257     GLenum queryTexLastBoundTarget(GLuint name) const;
258     GLenum queryTexFormat(GLuint name) const;
259     GLint queryTexInternalFormat(GLuint name) const;
260     GLsizei queryTexWidth(GLsizei level, GLuint name) const;
261     GLsizei queryTexHeight(GLsizei level, GLuint name) const;
262     GLsizei queryTexDepth(GLsizei level, GLuint name) const;
263     bool queryTexEGLImageBacked(GLuint name) const;
264
265     // For AMD GPUs, it is easy for the emulator to segfault
266     // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
267     // and uses GL_LUMINANCE as internal format.
268     // In particular, the segfault happens when negative components of
269     // cube maps are defined before positive ones,
270     // This procedure checks internal state to see if we have defined
271     // the positive component of a cube map already. If not, it returns
272     // which positive component needs to be defined first.
273     // If there is no need for the extra definition, 0 is returned.
274     GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level,
275                                                      GLenum internalformat);
276
277     // Tracks the format of the currently bound texture.
278     // This is to pass dEQP tests for fbo completeness.
279     void setBoundTextureInternalFormat(GLenum target, GLint format);
280     void setBoundTextureFormat(GLenum target, GLenum format);
281     void setBoundTextureType(GLenum target, GLenum type);
282     void setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
283     void setBoundTextureSamples(GLenum target, GLsizei samples);
284
285     // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
286     void setBoundTextureImmutableFormat(GLenum target);
287     bool isBoundTextureImmutableFormat(GLenum target) const;
288
289     // glDeleteTextures(...)
290     // Remove references to the to-be-deleted textures.
291     void deleteTextures(GLsizei n, const GLuint* textures);
292
293     // Render buffer objects
294     void addRenderbuffers(GLsizei n, GLuint* renderbuffers);
295     void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers);
296     bool usedRenderbufferName(GLuint name) const;
297     void bindRenderbuffer(GLenum target, GLuint name);
298     GLuint boundRenderbuffer() const;
299     void setBoundRenderbufferFormat(GLenum format);
300
301     // Frame buffer objects
302     void addFramebuffers(GLsizei n, GLuint* framebuffers);
303     void removeFramebuffers(GLsizei n, const GLuint* framebuffers);
304     bool usedFramebufferName(GLuint name) const;
305     void bindFramebuffer(GLenum target, GLuint name);
306     void setCheckFramebufferStatus(GLenum status);
307     GLenum getCheckFramebufferStatus() const;
308     GLuint boundFramebuffer() const;
309
310     // Texture object -> FBO
311     void attachTextureObject(GLenum attachment, GLuint texture);
312     GLuint getFboAttachmentTextureId(GLenum attachment) const;
313
314     // RBO -> FBO
315     void attachRbo(GLenum attachment, GLuint renderbuffer);
316     GLuint getFboAttachmentRboId(GLenum attachment) const;
317
318     // FBO attachments in general
319     bool attachmentHasObject(GLenum attachment) const;
320
321     void setTextureData(SharedTextureDataMap* sharedTexData);
322     // set eglsurface property on default framebuffer
323     // if coming from eglMakeCurrent
324     void fromMakeCurrent();
325
326     // Queries the format backing the current framebuffer.
327     // Type differs depending on whether the attachment
328     // is a texture or renderbuffer.
329     void getBoundFramebufferFormat(
330             GLenum attachment, FboFormatInfo* res_info) const;
331
332 private:
333     PixelStoreState m_pixelStore;
334     VertexAttribState *m_states;
335     int m_glesMajorVersion;
336     int m_glesMinorVersion;
337     int m_maxVertexAttribs;
338     bool m_maxVertexAttribsDirty;
339     int m_nLocations;
340     GLuint m_currentArrayVbo;
341     GLuint m_currentIndexVbo;
342     int m_activeTexture;
343     GLint m_currentProgram;
344
345     bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
346
347     enum TextureTarget {
348         TEXTURE_2D = 0,
349         TEXTURE_EXTERNAL = 1,
350         TEXTURE_CUBE_MAP = 2,
351         TEXTURE_2D_ARRAY = 3,
352         TEXTURE_3D = 4,
353         TEXTURE_2D_MULTISAMPLE = 5,
354         TEXTURE_TARGET_COUNT
355     };
356     struct TextureUnit {
357         unsigned int enables;
358         GLuint texture[TEXTURE_TARGET_COUNT];
359     };
360     struct TextureState {
361         TextureUnit unit[MAX_TEXTURE_UNITS];
362         TextureUnit* activeUnit;
363         // Initialized from shared group.
364         SharedTextureDataMap* textureRecs;
365     };
366     TextureState m_tex;
367
368     // State tracking of cube map definitions.
369     // Currently used only for driver workarounds
370     // when using GL_LUMINANCE and defining cube maps with
371     // glCopyTexImage2D.
372     struct CubeMapDef {
373         GLuint id;
374         GLenum target;
375         GLint level;
376         GLenum internalformat;
377     };
378     struct CubeMapDefCompare {
379         bool operator() (const CubeMapDef& a,
380                          const CubeMapDef& b) const {
381             if (a.id != b.id) return a.id < b.id;
382             if (a.target != b.target) return a.target < b.target;
383             if (a.level != b.level) return a.level < b.level;
384             if (a.internalformat != b.internalformat)
385                 return a.internalformat < b.internalformat;
386             return false;
387         }
388     };
389     std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs;
390     void writeCopyTexImageState(GLenum target, GLint level,
391                                 GLenum internalformat);
392     GLenum copyTexImageNeededTarget(GLenum target, GLint level,
393                                     GLenum internalformat);
394
395     struct RboState {
396         GLuint boundRenderbuffer;
397         size_t boundRenderbufferIndex;
398         std::vector<RboProps> rboData;
399     };
400     RboState mRboState;
401     void addFreshRenderbuffer(GLuint name);
402     void setBoundRenderbufferIndex();
403     size_t getRboIndex(GLuint name) const;
404     RboProps& boundRboProps();
405     const RboProps& boundRboProps_const() const;
406
407     struct FboState {
408         GLuint boundFramebuffer;
409         size_t boundFramebufferIndex;
410         std::vector<FboProps> fboData;
411         GLenum fboCheckStatus;
412     };
413     FboState mFboState;
414     void addFreshFramebuffer(GLuint name);
415     void setBoundFramebufferIndex();
416     size_t getFboIndex(GLuint name) const;
417     FboProps& boundFboProps();
418     const FboProps& boundFboProps_const() const;
419
420     // Querying framebuffer format
421     GLenum queryRboFormat(GLuint name) const;
422     GLenum queryTexType(GLuint name) const;
423     GLsizei queryTexSamples(GLuint name) const;
424
425     static int compareTexId(const void* pid, const void* prec);
426     TextureRec* addTextureRec(GLuint id, GLenum target);
427     TextureRec* getTextureRec(GLuint id) const;
428
429 public:
430     void getClientStatePointer(GLenum pname, GLvoid** params);
431
432     template <class T>
433     int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
434     {
435         bool handled = true;
436         const VertexAttribState *vertexAttrib = getState(index);
437         if (vertexAttrib == NULL) {
438             ERR("getVeterxAttriParameter for non existant index %d\n", index);
439             // set gl error;
440             return handled;
441         }
442
443         switch(param) {
444         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
445             *ptr = (T)(vertexAttrib->bufferObject);
446             break;
447         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
448             *ptr = (T)(vertexAttrib->enabled);
449             break;
450         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
451             *ptr = (T)(vertexAttrib->size);
452             break;
453         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
454             *ptr = (T)(vertexAttrib->stride);
455             break;
456         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
457             *ptr = (T)(vertexAttrib->type);
458             break;
459         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
460             *ptr = (T)(vertexAttrib->normalized);
461             break;
462         case GL_CURRENT_VERTEX_ATTRIB:
463             handled = false;
464             break;
465         default:
466             handled = false;
467             ERR("unknown vertex-attrib parameter param %d\n", param);
468         }
469         return handled;
470     }
471
472     template <class T>
473     bool getClientStateParameter(GLenum param, T* ptr)
474     {
475         bool isClientStateParam = false;
476         switch (param) {
477         case GL_CLIENT_ACTIVE_TEXTURE: {
478             GLint tex = getActiveTexture() + GL_TEXTURE0;
479             *ptr = tex;
480             isClientStateParam = true;
481             break;
482             }
483         case GL_VERTEX_ARRAY_SIZE: {
484             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
485             *ptr = state->size;
486             isClientStateParam = true;
487             break;
488             }
489         case GL_VERTEX_ARRAY_TYPE: {
490             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
491             *ptr = state->type;
492             isClientStateParam = true;
493             break;
494             }
495         case GL_VERTEX_ARRAY_STRIDE: {
496             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
497             *ptr = state->stride;
498             isClientStateParam = true;
499             break;
500             }
501         case GL_COLOR_ARRAY_SIZE: {
502             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
503             *ptr = state->size;
504             isClientStateParam = true;
505             break;
506             }
507         case GL_COLOR_ARRAY_TYPE: {
508             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
509             *ptr = state->type;
510             isClientStateParam = true;
511             break;
512             }
513         case GL_COLOR_ARRAY_STRIDE: {
514             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
515             *ptr = state->stride;
516             isClientStateParam = true;
517             break;
518             }
519         case GL_NORMAL_ARRAY_TYPE: {
520             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
521             *ptr = state->type;
522             isClientStateParam = true;
523             break;
524             }
525         case GL_NORMAL_ARRAY_STRIDE: {
526             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
527             *ptr = state->stride;
528             isClientStateParam = true;
529             break;
530             }
531         case GL_TEXTURE_COORD_ARRAY_SIZE: {
532             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
533             *ptr = state->size;
534             isClientStateParam = true;
535             break;
536             }
537         case GL_TEXTURE_COORD_ARRAY_TYPE: {
538             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
539             *ptr = state->type;
540             isClientStateParam = true;
541             break;
542             }
543         case GL_TEXTURE_COORD_ARRAY_STRIDE: {
544             const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
545             *ptr = state->stride;
546             isClientStateParam = true;
547             break;
548             }
549         case GL_POINT_SIZE_ARRAY_TYPE_OES: {
550             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
551             *ptr = state->type;
552             isClientStateParam = true;
553             break;
554             }
555         case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
556             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
557             *ptr = state->stride;
558             isClientStateParam = true;
559             break;
560             }
561         case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
562             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
563             *ptr = state->size;
564             isClientStateParam = true;
565             break;
566             }
567         case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
568             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
569             *ptr = state->type;
570             isClientStateParam = true;
571             break;
572             }
573         case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
574             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
575             *ptr = state->stride;
576             isClientStateParam = true;
577             break;
578             }
579         case GL_WEIGHT_ARRAY_SIZE_OES: {
580             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
581             *ptr = state->size;
582             isClientStateParam = true;
583             break;
584             }
585         case GL_WEIGHT_ARRAY_TYPE_OES: {
586             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
587             *ptr = state->type;
588             isClientStateParam = true;
589             break;
590             }
591         case GL_WEIGHT_ARRAY_STRIDE_OES: {
592             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
593             *ptr = state->stride;
594             isClientStateParam = true;
595             break;
596             }
597         case GL_VERTEX_ARRAY_BUFFER_BINDING: {
598             const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
599             *ptr = state->bufferObject;
600             isClientStateParam = true;
601             break;
602             }
603         case GL_NORMAL_ARRAY_BUFFER_BINDING: {
604             const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
605             *ptr = state->bufferObject;
606             isClientStateParam = true;
607             break;
608             }
609         case GL_COLOR_ARRAY_BUFFER_BINDING: {
610             const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
611             *ptr = state->bufferObject;
612             isClientStateParam = true;
613             break;
614             }
615         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
616             const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
617             *ptr = state->bufferObject;
618             isClientStateParam = true;
619             break;
620             }
621         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
622             const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
623             *ptr = state->bufferObject;
624             isClientStateParam = true;
625             break;
626             }
627         case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
628             const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
629             *ptr = state->bufferObject;
630             isClientStateParam = true;
631             break;
632             }
633         case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
634             const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
635             *ptr = state->bufferObject;
636             isClientStateParam = true;
637             break;
638             }
639         case GL_ARRAY_BUFFER_BINDING: {
640             int buffer = getBuffer(GL_ARRAY_BUFFER);
641             *ptr = buffer;
642             isClientStateParam = true;
643             break;
644             }
645         case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
646             int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
647             *ptr = buffer;
648             isClientStateParam = true;
649             break;
650             }
651         case GL_MAX_VERTEX_ATTRIBS: {
652             if (m_maxVertexAttribsDirty) {
653                 isClientStateParam = false;
654             } else {
655                 *ptr = m_maxVertexAttribs;
656                 isClientStateParam = true;
657             }
658             break;
659             }
660         }
661         return isClientStateParam;
662     }
663
664 };
665 #endif