blob: 49a63b657f341518e6c19f57f66f9ef06f75927a [file] [log] [blame]
keunyoungb85b2752013-03-08 12:28:03 -08001/*
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
Lingfeng Yang74e29292017-01-10 14:54:38 -080025#include "TextureSharedData.h"
26
keunyoungb85b2752013-03-08 12:28:03 -080027#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
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070037#include <vector>
Lingfeng Yang74e29292017-01-10 14:54:38 -080038#include <map>
Lingfeng Yange00ec9d2016-09-16 08:54:03 -070039#include <set>
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070040
41// Tracking framebuffer objects:
42// which framebuffer is bound,
43// and which texture names
44// are currently bound to which attachment points.
45struct FboProps {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070046 GLuint name;
47 bool previouslyBound;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080048 std::vector<GLuint> colorAttachmenti_textures;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070049 GLuint depthAttachment_texture;
50 GLuint stencilAttachment_texture;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080051 GLuint depthstencilAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070052
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080053 std::vector<bool> colorAttachmenti_hasTex;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070054 bool depthAttachment_hasTexObj;
55 bool stencilAttachment_hasTexObj;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080056 bool depthstencilAttachment_hasTexObj;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070057
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080058 std::vector<GLuint> colorAttachmenti_rbos;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070059 GLuint depthAttachment_rbo;
60 GLuint stencilAttachment_rbo;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080061 GLuint depthstencilAttachment_rbo;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070062
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080063 std::vector<bool> colorAttachmenti_hasRbo;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070064 bool depthAttachment_hasRbo;
65 bool stencilAttachment_hasRbo;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080066 bool depthstencilAttachment_hasRbo;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070067};
68
69// Same for Rbo's
70struct RboProps {
71 GLenum target;
72 GLuint name;
Lingfeng Yang69066602016-04-12 09:29:11 -070073 GLenum format;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080074 GLsizei multisamples;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070075 bool previouslyBound;
76};
77
Lingfeng Yang69066602016-04-12 09:29:11 -070078// Enum for describing whether a framebuffer attachment
79// is a texture or renderbuffer.
80enum FboAttachmentType {
81 FBO_ATTACHMENT_RENDERBUFFER = 0,
82 FBO_ATTACHMENT_TEXTURE = 1,
83 FBO_ATTACHMENT_NONE = 2
84};
85
86// Tracking FBO format
87struct FboFormatInfo {
88 FboAttachmentType type;
89 GLenum rb_format;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080090 GLsizei rb_multisamples;
91
Lingfeng Yang69066602016-04-12 09:29:11 -070092 GLint tex_internalformat;
93 GLenum tex_format;
94 GLenum tex_type;
Lingfeng Yang74e29292017-01-10 14:54:38 -080095 GLsizei tex_multisamples;
Lingfeng Yang69066602016-04-12 09:29:11 -070096};
97
keunyoungb85b2752013-03-08 12:28:03 -080098class GLClientState {
99public:
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;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800124 GLuint reloffset;
keunyoungb85b2752013-03-08 12:28:03 -0800125 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;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800130 GLuint divisor;
131 bool isInt;
132 int bindingindex;
keunyoungb85b2752013-03-08 12:28:03 -0800133 } VertexAttribState;
134
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800135 struct BufferBinding {
136 GLintptr offset;
137 GLintptr stride;
138 GLintptr effectiveStride;
139 GLsizeiptr size;
140 GLuint buffer;
141 GLuint divisor;
142 };
143
144 typedef std::vector<VertexAttribState> VertexAttribStateVector;
145 typedef std::vector<BufferBinding> VertexAttribBindingVector;
146
147 struct VAOState {
148 VAOState(GLuint ibo, int nLoc, int nBindings) :
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800149 attribState(nLoc),
Matt Wachowskidfbc1b32018-08-10 12:50:40 -0700150 bindingState(nBindings),
Lingfeng Yang554a5152019-02-21 20:20:48 -0800151 element_array_buffer_binding(ibo),
152 element_array_buffer_binding_lastEncode(ibo) { }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800153 VertexAttribStateVector attribState;
154 VertexAttribBindingVector bindingState;
155 GLuint element_array_buffer_binding;
Lingfeng Yang554a5152019-02-21 20:20:48 -0800156 GLuint element_array_buffer_binding_lastEncode;
157 int attributesNeedingUpdateForDraw[CODEC_MAX_VERTEX_ATTRIBUTES];
158 int numAttributesNeedingUpdateForDraw;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800159 };
160
161 typedef std::map<GLuint, VAOState> VAOStateMap;
162 struct VAOStateRef {
163 VAOStateRef() { }
164 VAOStateRef(
165 VAOStateMap::iterator iter) : it(iter) { }
Lingfeng Yang554a5152019-02-21 20:20:48 -0800166 VAOState& vaoState() { return it->second; }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800167 VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; }
168 BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; }
169 VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; }
170 const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; }
171 GLuint vaoId() const { return it->first; }
172 GLuint& iboId() { return it->second.element_array_buffer_binding; }
Lingfeng Yang554a5152019-02-21 20:20:48 -0800173 GLuint& iboIdLastEncode() { return it->second.element_array_buffer_binding_lastEncode; }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800174 VAOStateMap::iterator it;
175 };
176
keunyoungb85b2752013-03-08 12:28:03 -0800177 typedef struct {
178 int unpack_alignment;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800179
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
keunyoungb85b2752013-03-08 12:28:03 -0800186 int pack_alignment;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800187
188 int pack_row_length;
189 int pack_skip_pixels;
190 int pack_skip_rows;
keunyoungb85b2752013-03-08 12:28:03 -0800191 } PixelStoreState;
192
193 enum {
Lingfeng Yang74e29292017-01-10 14:54:38 -0800194 MAX_TEXTURE_UNITS = 256,
keunyoungb85b2752013-03-08 12:28:03 -0800195 };
196
197public:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800198 GLClientState();
199 GLClientState(int majorVersion, int minorVersion);
keunyoungb85b2752013-03-08 12:28:03 -0800200 ~GLClientState();
201 int nLocations() { return m_nLocations; }
202 const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
203 int setPixelStore(GLenum param, GLint value);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800204 GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800205 const VertexAttribBindingVector& currentVertexBufferBindings() const {
206 return m_currVaoState.bufferBindings_const();
207 }
208
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800209 GLuint currentArrayVbo() { return m_arrayBuffer; }
210 GLuint currentIndexVbo() { return m_currVaoState.iboId(); }
keunyoungb85b2752013-03-08 12:28:03 -0800211 void enable(int location, int state);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800212 // 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);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800226 void updateEnableDirtyArrayForDraw();
227 VAOState& currentVaoState();
keunyoungb85b2752013-03-08 12:28:03 -0800228 int getLocation(GLenum loc);
229 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
230 int getActiveTexture() const { return m_activeTexture; }
Lingfeng Yangb0176982016-03-01 21:27:49 -0800231 void setMaxVertexAttribs(int val) {
232 m_maxVertexAttribs = val;
233 m_maxVertexAttribsDirty = false;
234 }
keunyoungb85b2752013-03-08 12:28:03 -0800235
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800236 void addBuffer(GLuint id);
237 void removeBuffer(GLuint id);
238 bool bufferIdExists(GLuint id) const;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800239 void unBindBuffer(GLuint id);
bohub0f0cdf2014-11-06 18:08:07 -0800240
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800241 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;
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800244 bool isNonIndexedBindNoOp(GLenum target, GLuint buffer);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800245 bool isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride);
keunyoungb85b2752013-03-08 12:28:03 -0800246
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800247 int getBuffer(GLenum target);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800248 GLuint getLastEncodedBufferBind(GLenum target);
249 void setLastEncodedBufferBind(GLenum target, GLuint id);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800250
Lingfeng Yang74e29292017-01-10 14:54:38 -0800251 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;
Lingfeng Yang22dc42d2018-05-29 10:11:38 -0700254 void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
keunyoungb85b2752013-03-08 12:28:03 -0800255
256 void setCurrentProgram(GLint program) { m_currentProgram = program; }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800257 void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; }
keunyoungb85b2752013-03-08 12:28:03 -0800258 GLint currentProgram() const { return m_currentProgram; }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800259 GLint currentShaderProgram() const { return m_currentShaderProgram; }
keunyoungb85b2752013-03-08 12:28:03 -0800260
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800261 struct UniformBlockInfoKey {
262 GLuint program;
263 GLuint uniformBlockIndex;
264 };
265 struct UniformBlockInfoKeyCompare {
266 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
Lingfeng Yange6556dc2017-01-09 12:04:12 -0800280 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
281 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800282
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
keunyoungb85b2752013-03-08 12:28:03 -0800289 /* 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
Lingfeng Yang554a5152019-02-21 20:20:48 -0800312 void bindSampler(GLuint unit, GLuint sampler);
313 bool isSamplerBindNoOp(GLuint unit, GLuint sampler);
314 void onDeleteSamplers(GLsizei n, const GLuint* samplers);
315
keunyoungb85b2752013-03-08 12:28:03 -0800316 // 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);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800333 void setBoundEGLImage(GLenum target, GLeglImageOES image);
keunyoungb85b2752013-03-08 12:28:03 -0800334
335 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
336 GLuint getBoundTexture(GLenum target) const;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800337 // 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;
keunyoungb85b2752013-03-08 12:28:03 -0800345
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700346 // 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
Lingfeng Yang69066602016-04-12 09:29:11 -0700358 // 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);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800363 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;
Lingfeng Yang69066602016-04-12 09:29:11 -0700369
keunyoungb85b2752013-03-08 12:28:03 -0800370 // glDeleteTextures(...)
371 // Remove references to the to-be-deleted textures.
372 void deleteTextures(GLsizei n, const GLuint* textures);
373
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700374 // 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;
Lingfeng Yang69066602016-04-12 09:29:11 -0700380 void setBoundRenderbufferFormat(GLenum format);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800381 void setBoundRenderbufferSamples(GLsizei samples);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700382
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);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800388 void setCheckFramebufferStatus(GLenum target, GLenum status);
389 GLenum getCheckFramebufferStatus(GLenum target) const;
390 GLuint boundFramebuffer(GLenum target) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700391
392 // Texture object -> FBO
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800393 void attachTextureObject(GLenum target, GLenum attachment, GLuint texture);
394 GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700395
396 // RBO -> FBO
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800397 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;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700401
402 // FBO attachments in general
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800403 bool attachmentHasObject(GLenum target, GLenum attachment) const;
404 GLuint objectOfAttachment(GLenum target, GLenum attachment) const;
405
Lingfeng Yang4a66b312017-01-09 13:27:49 -0800406 // Transform feedback state
407 void setTransformFeedbackActiveUnpaused(bool activeUnpaused);
408 bool getTransformFeedbackActiveUnpaused() const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700409
Lingfeng Yang74e29292017-01-10 14:54:38 -0800410 void setTextureData(SharedTextureDataMap* sharedTexData);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700411 // set eglsurface property on default framebuffer
412 // if coming from eglMakeCurrent
413 void fromMakeCurrent();
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800414 // 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;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700427
Lingfeng Yang69066602016-04-12 09:29:11 -0700428 // Queries the format backing the current framebuffer.
429 // Type differs depending on whether the attachment
430 // is a texture or renderbuffer.
431 void getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800432 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;
keunyoungb85b2752013-03-08 12:28:03 -0800440private:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800441 void init();
442 bool m_initialized;
keunyoungb85b2752013-03-08 12:28:03 -0800443 PixelStoreState m_pixelStore;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800444
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800445 std::set<GLuint> mBufferIds;
446
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800447 // GL_ARRAY_BUFFER_BINDING is separate from VAO state
448 GLuint m_arrayBuffer;
Lingfeng Yang554a5152019-02-21 20:20:48 -0800449 GLuint m_arrayBuffer_lastEncode;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800450 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
Lingfeng Yang74e29292017-01-10 14:54:38 -0800480 int m_glesMajorVersion;
481 int m_glesMinorVersion;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800482 int m_maxVertexAttribs;
483 bool m_maxVertexAttribsDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800484 int m_nLocations;
keunyoungb85b2752013-03-08 12:28:03 -0800485 int m_activeTexture;
486 GLint m_currentProgram;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800487 GLint m_currentShaderProgram;
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800488 ProgramPipelineMap m_programPipelines;
keunyoungb85b2752013-03-08 12:28:03 -0800489
keunyoungb85b2752013-03-08 12:28:03 -0800490 enum TextureTarget {
491 TEXTURE_2D = 0,
492 TEXTURE_EXTERNAL = 1,
Lingfeng Yang74e29292017-01-10 14:54:38 -0800493 TEXTURE_CUBE_MAP = 2,
494 TEXTURE_2D_ARRAY = 3,
495 TEXTURE_3D = 4,
496 TEXTURE_2D_MULTISAMPLE = 5,
keunyoungb85b2752013-03-08 12:28:03 -0800497 TEXTURE_TARGET_COUNT
498 };
499 struct TextureUnit {
500 unsigned int enables;
501 GLuint texture[TEXTURE_TARGET_COUNT];
Lingfeng Yang554a5152019-02-21 20:20:48 -0800502 GLuint boundSampler;
keunyoungb85b2752013-03-08 12:28:03 -0800503 };
keunyoungb85b2752013-03-08 12:28:03 -0800504 struct TextureState {
505 TextureUnit unit[MAX_TEXTURE_UNITS];
506 TextureUnit* activeUnit;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800507 // Initialized from shared group.
508 SharedTextureDataMap* textureRecs;
keunyoungb85b2752013-03-08 12:28:03 -0800509 };
510 TextureState m_tex;
511
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700512 // 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 {
523 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);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700538
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800539 int m_max_color_attachments;
540 int m_max_draw_buffers;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700541 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 {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800554 GLuint boundDrawFramebuffer;
555 GLuint boundReadFramebuffer;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700556 size_t boundFramebufferIndex;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800557 std::map<GLuint, FboProps> fboData;
558 GLenum drawFboCheckStatus;
559 GLenum readFboCheckStatus;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700560 };
561 FboState mFboState;
562 void addFreshFramebuffer(GLuint name);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800563 FboProps& boundFboProps(GLenum target);
564 const FboProps& boundFboProps_const(GLenum target) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700565
Lingfeng Yang69066602016-04-12 09:29:11 -0700566 // Querying framebuffer format
567 GLenum queryRboFormat(GLuint name) const;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800568 GLsizei queryRboSamples(GLuint name) const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700569 GLenum queryTexType(GLuint name) const;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800570 GLsizei queryTexSamples(GLuint name) const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700571
keunyoungb85b2752013-03-08 12:28:03 -0800572 static int compareTexId(const void* pid, const void* prec);
573 TextureRec* addTextureRec(GLuint id, GLenum target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800574 TextureRec* getTextureRec(GLuint id) const;
keunyoungb85b2752013-03-08 12:28:03 -0800575
576public:
577 void getClientStatePointer(GLenum pname, GLvoid** params);
578
579 template <class T>
580 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
581 {
582 bool handled = true;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800583 const VertexAttribState& vertexAttrib = getState(index);
584 const BufferBinding& vertexAttribBufferBinding =
585 m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex];
keunyoungb85b2752013-03-08 12:28:03 -0800586
587 switch(param) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800588#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;
keunyoungb85b2752013-03-08 12:28:03 -0800596 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800597 *ptr = (T)(vertexAttribBufferBinding.buffer);
keunyoungb85b2752013-03-08 12:28:03 -0800598 break;
599 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800600 *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);
keunyoungb85b2752013-03-08 12:28:03 -0800605 break;
606 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800607 *ptr = (T)(vertexAttrib.size);
keunyoungb85b2752013-03-08 12:28:03 -0800608 break;
609 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800610 *ptr = (T)(vertexAttribBufferBinding.stride);
keunyoungb85b2752013-03-08 12:28:03 -0800611 break;
612 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800613 *ptr = (T)(vertexAttrib.type);
keunyoungb85b2752013-03-08 12:28:03 -0800614 break;
615 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800616 *ptr = (T)(vertexAttrib.normalized);
keunyoungb85b2752013-03-08 12:28:03 -0800617 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>
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800629 bool getClientStateParameter(GLenum param, T* out)
keunyoungb85b2752013-03-08 12:28:03 -0800630 {
631 bool isClientStateParam = false;
632 switch (param) {
633 case GL_CLIENT_ACTIVE_TEXTURE: {
634 GLint tex = getActiveTexture() + GL_TEXTURE0;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800635 *out = tex;
keunyoungb85b2752013-03-08 12:28:03 -0800636 isClientStateParam = true;
637 break;
638 }
639 case GL_VERTEX_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800640 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
641 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800642 isClientStateParam = true;
643 break;
644 }
645 case GL_VERTEX_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800646 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
647 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800648 isClientStateParam = true;
649 break;
650 }
651 case GL_VERTEX_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800652 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
653 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800654 isClientStateParam = true;
655 break;
656 }
657 case GL_COLOR_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800658 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
659 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800660 isClientStateParam = true;
661 break;
662 }
663 case GL_COLOR_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800664 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
665 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800666 isClientStateParam = true;
667 break;
668 }
669 case GL_COLOR_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800670 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
671 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800672 isClientStateParam = true;
673 break;
674 }
675 case GL_NORMAL_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800676 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
677 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800678 isClientStateParam = true;
679 break;
680 }
681 case GL_NORMAL_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800682 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
683 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800684 isClientStateParam = true;
685 break;
686 }
687 case GL_TEXTURE_COORD_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800688 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
689 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800690 isClientStateParam = true;
691 break;
692 }
693 case GL_TEXTURE_COORD_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800694 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
695 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800696 isClientStateParam = true;
697 break;
698 }
699 case GL_TEXTURE_COORD_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800700 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
701 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800702 isClientStateParam = true;
703 break;
704 }
705 case GL_POINT_SIZE_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800706 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
707 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800708 isClientStateParam = true;
709 break;
710 }
711 case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800712 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
713 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800714 isClientStateParam = true;
715 break;
716 }
717 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800718 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
719 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800720 isClientStateParam = true;
721 break;
722 }
723 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800724 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
725 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800726 isClientStateParam = true;
727 break;
728 }
729 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800730 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
731 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800732 isClientStateParam = true;
733 break;
734 }
735 case GL_WEIGHT_ARRAY_SIZE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800736 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
737 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800738 isClientStateParam = true;
739 break;
740 }
741 case GL_WEIGHT_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800742 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
743 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800744 isClientStateParam = true;
745 break;
746 }
747 case GL_WEIGHT_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800748 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
749 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800750 isClientStateParam = true;
751 break;
752 }
753 case GL_VERTEX_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800754 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
755 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800756 isClientStateParam = true;
757 break;
758 }
759 case GL_NORMAL_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800760 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
761 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800762 isClientStateParam = true;
763 break;
764 }
765 case GL_COLOR_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800766 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
767 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800768 isClientStateParam = true;
769 break;
770 }
771 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800772 const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
773 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800774 isClientStateParam = true;
775 break;
776 }
777 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800778 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
779 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800780 isClientStateParam = true;
781 break;
782 }
783 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800784 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
785 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800786 isClientStateParam = true;
787 break;
788 }
789 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800790 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
791 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800792 isClientStateParam = true;
793 break;
794 }
795 case GL_ARRAY_BUFFER_BINDING: {
796 int buffer = getBuffer(GL_ARRAY_BUFFER);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800797 *out = buffer;
keunyoungb85b2752013-03-08 12:28:03 -0800798 isClientStateParam = true;
799 break;
800 }
801 case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
802 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800803 *out = buffer;
keunyoungb85b2752013-03-08 12:28:03 -0800804 isClientStateParam = true;
805 break;
806 }
Lingfeng Yangb0176982016-03-01 21:27:49 -0800807 case GL_MAX_VERTEX_ATTRIBS: {
808 if (m_maxVertexAttribsDirty) {
809 isClientStateParam = false;
810 } else {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800811 *out = m_maxVertexAttribs;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800812 isClientStateParam = true;
813 }
814 break;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800815 }
keunyoungb85b2752013-03-08 12:28:03 -0800816 }
817 return isClientStateParam;
818 }
819
820};
821#endif