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