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