blob: e41cf440aa9cb25010091f169706f23dc24889a2 [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) :
149 element_array_buffer_binding(ibo),
150 attribState(nLoc),
151 bindingState(nBindings) { }
152 VertexAttribStateVector attribState;
153 VertexAttribBindingVector bindingState;
154 GLuint element_array_buffer_binding;
155 };
156
157 typedef std::map<GLuint, VAOState> VAOStateMap;
158 struct VAOStateRef {
159 VAOStateRef() { }
160 VAOStateRef(
161 VAOStateMap::iterator iter) : it(iter) { }
162 VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; }
163 BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; }
164 VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; }
165 const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; }
166 GLuint vaoId() const { return it->first; }
167 GLuint& iboId() { return it->second.element_array_buffer_binding; }
168 VAOStateMap::iterator it;
169 };
170
keunyoungb85b2752013-03-08 12:28:03 -0800171 typedef struct {
172 int unpack_alignment;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800173
174 int unpack_row_length;
175 int unpack_image_height;
176 int unpack_skip_pixels;
177 int unpack_skip_rows;
178 int unpack_skip_images;
179
keunyoungb85b2752013-03-08 12:28:03 -0800180 int pack_alignment;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800181
182 int pack_row_length;
183 int pack_skip_pixels;
184 int pack_skip_rows;
keunyoungb85b2752013-03-08 12:28:03 -0800185 } PixelStoreState;
186
187 enum {
Lingfeng Yang74e29292017-01-10 14:54:38 -0800188 MAX_TEXTURE_UNITS = 256,
keunyoungb85b2752013-03-08 12:28:03 -0800189 };
190
191public:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800192 GLClientState();
193 GLClientState(int majorVersion, int minorVersion);
keunyoungb85b2752013-03-08 12:28:03 -0800194 ~GLClientState();
195 int nLocations() { return m_nLocations; }
196 const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
197 int setPixelStore(GLenum param, GLint value);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800198 GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800199 const VertexAttribBindingVector& currentVertexBufferBindings() const {
200 return m_currVaoState.bufferBindings_const();
201 }
202
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800203 GLuint currentArrayVbo() { return m_arrayBuffer; }
204 GLuint currentIndexVbo() { return m_currVaoState.iboId(); }
keunyoungb85b2752013-03-08 12:28:03 -0800205 void enable(int location, int state);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800206 // Vertex array objects and vertex attributes
207 void addVertexArrayObjects(GLsizei n, GLuint* arrays);
208 void removeVertexArrayObjects(GLsizei n, const GLuint* arrays);
209 void addVertexArrayObject(GLuint name);
210 void removeVertexArrayObject(GLuint name);
211 void setVertexArrayObject(GLuint vao);
212 bool isVertexArrayObject(GLuint vao) const;
213 void setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt = false);
214 void setVertexBindingDivisor(int bindingindex, GLuint divisor);
215 const BufferBinding& getCurrAttributeBindingInfo(int attribindex);
216 void setVertexAttribBinding(int attribindex, int bindingindex);
217 void setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt = false);
218 const VertexAttribState& getState(int location);
219 const VertexAttribState& getStateAndEnableDirty(int location, bool *enableChanged);
keunyoungb85b2752013-03-08 12:28:03 -0800220 int getLocation(GLenum loc);
221 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
222 int getActiveTexture() const { return m_activeTexture; }
Lingfeng Yangb0176982016-03-01 21:27:49 -0800223 void setMaxVertexAttribs(int val) {
224 m_maxVertexAttribs = val;
225 m_maxVertexAttribsDirty = false;
226 }
keunyoungb85b2752013-03-08 12:28:03 -0800227
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800228 void addBuffer(GLuint id);
229 void removeBuffer(GLuint id);
230 bool bufferIdExists(GLuint id) const;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800231 void unBindBuffer(GLuint id);
bohub0f0cdf2014-11-06 18:08:07 -0800232
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800233 int bindBuffer(GLenum target, GLuint id);
234 void bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride);
235 int getMaxIndexedBufferBindings(GLenum target) const;
keunyoungb85b2752013-03-08 12:28:03 -0800236
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800237 int getBuffer(GLenum target);
238
Lingfeng Yang74e29292017-01-10 14:54:38 -0800239 size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
240 size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
241 size_t clearBufferNumElts(GLenum buffer) const;
keunyoungb85b2752013-03-08 12:28:03 -0800242
243 void setCurrentProgram(GLint program) { m_currentProgram = program; }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800244 void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; }
keunyoungb85b2752013-03-08 12:28:03 -0800245 GLint currentProgram() const { return m_currentProgram; }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800246 GLint currentShaderProgram() const { return m_currentShaderProgram; }
keunyoungb85b2752013-03-08 12:28:03 -0800247
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800248 struct UniformBlockInfoKey {
249 GLuint program;
250 GLuint uniformBlockIndex;
251 };
252 struct UniformBlockInfoKeyCompare {
253 bool operator() (const UniformBlockInfoKey& a,
254 const UniformBlockInfoKey& b) const {
255 if (a.program != b.program) return a.program < b.program;
256 if (a.uniformBlockIndex != b.uniformBlockIndex) return a.uniformBlockIndex < b.uniformBlockIndex;
257 return false;
258 }
259 };
260 struct UniformBlockUniformInfo {
261 size_t numActiveUniforms;
262 };
263
264 typedef std::map<UniformBlockInfoKey, UniformBlockUniformInfo, UniformBlockInfoKeyCompare> UniformBlockInfoMap;
265 UniformBlockInfoMap m_uniformBlockInfoMap;
266
Lingfeng Yange6556dc2017-01-09 12:04:12 -0800267 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
268 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800269
270 typedef std::map<GLuint, GLuint> ProgramPipelineMap;
271 typedef ProgramPipelineMap::iterator ProgramPipelineIterator;
272 void associateProgramWithPipeline(GLuint program, GLuint pipeline);
273 ProgramPipelineIterator programPipelineBegin();
274 ProgramPipelineIterator programPipelineEnd();
275
keunyoungb85b2752013-03-08 12:28:03 -0800276 /* OES_EGL_image_external
277 *
278 * These functions manipulate GL state which interacts with the
279 * OES_EGL_image_external extension, to support client-side emulation on
280 * top of host implementations that don't have it.
281 *
282 * Most of these calls should only be used with TEXTURE_2D or
283 * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
284 * targets should bypass this. An exception is bindTexture(), which should
285 * see all glBindTexture() calls for any target.
286 */
287
288 // glActiveTexture(GL_TEXTURE0 + i)
289 // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
290 GLenum setActiveTextureUnit(GLenum texture);
291 GLenum getActiveTextureUnit() const;
292
293 // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
294 void enableTextureTarget(GLenum target);
295
296 // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
297 void disableTextureTarget(GLenum target);
298
299 // Implements the target priority logic:
300 // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
301 // * Return GL_TEXTURE_2D if enabled, else
302 // * Return the allDisabled value.
303 // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
304 // simpler; for other cases passing a recognizable enum like GL_ZERO or
305 // GL_INVALID_ENUM is appropriate.
306 GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
307
308 // glBindTexture(GL_TEXTURE_*, ...)
309 // Set the target binding of the active texture unit to texture. Returns
310 // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
311 // previously been bound to a different target. If firstUse is not NULL,
312 // it is set to indicate whether this is the first use of the texture.
313 // For accurate error detection, bindTexture should be called for *all*
314 // targets, not just 2D and EXTERNAL_OES.
315 GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800316 void setBoundEGLImage(GLenum target, GLeglImageOES image);
keunyoungb85b2752013-03-08 12:28:03 -0800317
318 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
319 GLuint getBoundTexture(GLenum target) const;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800320 // Other publicly-visible texture queries
321 GLenum queryTexLastBoundTarget(GLuint name) const;
322 GLenum queryTexFormat(GLuint name) const;
323 GLint queryTexInternalFormat(GLuint name) const;
324 GLsizei queryTexWidth(GLsizei level, GLuint name) const;
325 GLsizei queryTexHeight(GLsizei level, GLuint name) const;
326 GLsizei queryTexDepth(GLsizei level, GLuint name) const;
327 bool queryTexEGLImageBacked(GLuint name) const;
keunyoungb85b2752013-03-08 12:28:03 -0800328
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700329 // For AMD GPUs, it is easy for the emulator to segfault
330 // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
331 // and uses GL_LUMINANCE as internal format.
332 // In particular, the segfault happens when negative components of
333 // cube maps are defined before positive ones,
334 // This procedure checks internal state to see if we have defined
335 // the positive component of a cube map already. If not, it returns
336 // which positive component needs to be defined first.
337 // If there is no need for the extra definition, 0 is returned.
338 GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level,
339 GLenum internalformat);
340
Lingfeng Yang69066602016-04-12 09:29:11 -0700341 // Tracks the format of the currently bound texture.
342 // This is to pass dEQP tests for fbo completeness.
343 void setBoundTextureInternalFormat(GLenum target, GLint format);
344 void setBoundTextureFormat(GLenum target, GLenum format);
345 void setBoundTextureType(GLenum target, GLenum type);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800346 void setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
347 void setBoundTextureSamples(GLenum target, GLsizei samples);
348
349 // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
350 void setBoundTextureImmutableFormat(GLenum target);
351 bool isBoundTextureImmutableFormat(GLenum target) const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700352
keunyoungb85b2752013-03-08 12:28:03 -0800353 // glDeleteTextures(...)
354 // Remove references to the to-be-deleted textures.
355 void deleteTextures(GLsizei n, const GLuint* textures);
356
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700357 // Render buffer objects
358 void addRenderbuffers(GLsizei n, GLuint* renderbuffers);
359 void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers);
360 bool usedRenderbufferName(GLuint name) const;
361 void bindRenderbuffer(GLenum target, GLuint name);
362 GLuint boundRenderbuffer() const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700363 void setBoundRenderbufferFormat(GLenum format);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800364 void setBoundRenderbufferSamples(GLsizei samples);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700365
366 // Frame buffer objects
367 void addFramebuffers(GLsizei n, GLuint* framebuffers);
368 void removeFramebuffers(GLsizei n, const GLuint* framebuffers);
369 bool usedFramebufferName(GLuint name) const;
370 void bindFramebuffer(GLenum target, GLuint name);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800371 void setCheckFramebufferStatus(GLenum target, GLenum status);
372 GLenum getCheckFramebufferStatus(GLenum target) const;
373 GLuint boundFramebuffer(GLenum target) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700374
375 // Texture object -> FBO
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800376 void attachTextureObject(GLenum target, GLenum attachment, GLuint texture);
377 GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700378
379 // RBO -> FBO
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800380 void detachRbo(GLuint renderbuffer);
381 void detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer);
382 void attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer);
383 GLuint getFboAttachmentRboId(GLenum target, GLenum attachment) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700384
385 // FBO attachments in general
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800386 bool attachmentHasObject(GLenum target, GLenum attachment) const;
387 GLuint objectOfAttachment(GLenum target, GLenum attachment) const;
388
Lingfeng Yang4a66b312017-01-09 13:27:49 -0800389 // Transform feedback state
390 void setTransformFeedbackActiveUnpaused(bool activeUnpaused);
391 bool getTransformFeedbackActiveUnpaused() const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700392
Lingfeng Yang74e29292017-01-10 14:54:38 -0800393 void setTextureData(SharedTextureDataMap* sharedTexData);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700394 // set eglsurface property on default framebuffer
395 // if coming from eglMakeCurrent
396 void fromMakeCurrent();
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800397 // set indexed buffer state.
398 // We need to query the underlying OpenGL to get
399 // accurate values for indexed buffers
400 // and # render targets.
401 void initFromCaps(
402 int max_transform_feedback_separate_attribs,
403 int max_uniform_buffer_bindings,
404 int max_atomic_counter_buffer_bindings,
405 int max_shader_storage_buffer_bindings,
406 int max_vertex_attrib_bindings,
407 int max_color_attachments,
408 int max_draw_buffers);
409 bool needsInitFromCaps() const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700410
Lingfeng Yang69066602016-04-12 09:29:11 -0700411 // Queries the format backing the current framebuffer.
412 // Type differs depending on whether the attachment
413 // is a texture or renderbuffer.
414 void getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800415 GLenum target,
416 GLenum attachment,
417 FboFormatInfo* res_info) const;
418 FboAttachmentType getBoundFramebufferAttachmentType(
419 GLenum target,
420 GLenum attachment) const;
421 int getMaxColorAttachments() const;
422 int getMaxDrawBuffers() const;
keunyoungb85b2752013-03-08 12:28:03 -0800423private:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800424 void init();
425 bool m_initialized;
keunyoungb85b2752013-03-08 12:28:03 -0800426 PixelStoreState m_pixelStore;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800427
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800428 std::set<GLuint> mBufferIds;
429
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800430 // GL_ARRAY_BUFFER_BINDING is separate from VAO state
431 GLuint m_arrayBuffer;
432 VAOStateMap m_vaoMap;
433 VAOStateRef m_currVaoState;
434
435 // Other buffer id's, other targets
436 GLuint m_copyReadBuffer;
437 GLuint m_copyWriteBuffer;
438
439 GLuint m_pixelPackBuffer;
440 GLuint m_pixelUnpackBuffer;
441
442 GLuint m_transformFeedbackBuffer;
443 GLuint m_uniformBuffer;
444
445 GLuint m_atomicCounterBuffer;
446 GLuint m_dispatchIndirectBuffer;
447 GLuint m_drawIndirectBuffer;
448 GLuint m_shaderStorageBuffer;
449
450 bool m_transformFeedbackActiveUnpaused;
451
452 int m_max_transform_feedback_separate_attribs;
453 int m_max_uniform_buffer_bindings;
454 int m_max_atomic_counter_buffer_bindings;
455 int m_max_shader_storage_buffer_bindings;
456 int m_max_vertex_attrib_bindings;
457 std::vector<BufferBinding> m_indexedTransformFeedbackBuffers;
458 std::vector<BufferBinding> m_indexedUniformBuffers;
459 std::vector<BufferBinding> m_indexedAtomicCounterBuffers;
460 std::vector<BufferBinding> m_indexedShaderStorageBuffers;
461
Lingfeng Yang74e29292017-01-10 14:54:38 -0800462 int m_glesMajorVersion;
463 int m_glesMinorVersion;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800464 int m_maxVertexAttribs;
465 bool m_maxVertexAttribsDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800466 int m_nLocations;
keunyoungb85b2752013-03-08 12:28:03 -0800467 int m_activeTexture;
468 GLint m_currentProgram;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800469 GLint m_currentShaderProgram;
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800470 ProgramPipelineMap m_programPipelines;
keunyoungb85b2752013-03-08 12:28:03 -0800471
keunyoungb85b2752013-03-08 12:28:03 -0800472 enum TextureTarget {
473 TEXTURE_2D = 0,
474 TEXTURE_EXTERNAL = 1,
Lingfeng Yang74e29292017-01-10 14:54:38 -0800475 TEXTURE_CUBE_MAP = 2,
476 TEXTURE_2D_ARRAY = 3,
477 TEXTURE_3D = 4,
478 TEXTURE_2D_MULTISAMPLE = 5,
keunyoungb85b2752013-03-08 12:28:03 -0800479 TEXTURE_TARGET_COUNT
480 };
481 struct TextureUnit {
482 unsigned int enables;
483 GLuint texture[TEXTURE_TARGET_COUNT];
484 };
keunyoungb85b2752013-03-08 12:28:03 -0800485 struct TextureState {
486 TextureUnit unit[MAX_TEXTURE_UNITS];
487 TextureUnit* activeUnit;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800488 // Initialized from shared group.
489 SharedTextureDataMap* textureRecs;
keunyoungb85b2752013-03-08 12:28:03 -0800490 };
491 TextureState m_tex;
492
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700493 // State tracking of cube map definitions.
494 // Currently used only for driver workarounds
495 // when using GL_LUMINANCE and defining cube maps with
496 // glCopyTexImage2D.
497 struct CubeMapDef {
498 GLuint id;
499 GLenum target;
500 GLint level;
501 GLenum internalformat;
502 };
503 struct CubeMapDefCompare {
504 bool operator() (const CubeMapDef& a,
505 const CubeMapDef& b) const {
506 if (a.id != b.id) return a.id < b.id;
507 if (a.target != b.target) return a.target < b.target;
508 if (a.level != b.level) return a.level < b.level;
509 if (a.internalformat != b.internalformat)
510 return a.internalformat < b.internalformat;
511 return false;
512 }
513 };
514 std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs;
515 void writeCopyTexImageState(GLenum target, GLint level,
516 GLenum internalformat);
517 GLenum copyTexImageNeededTarget(GLenum target, GLint level,
518 GLenum internalformat);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700519
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800520 int m_max_color_attachments;
521 int m_max_draw_buffers;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700522 struct RboState {
523 GLuint boundRenderbuffer;
524 size_t boundRenderbufferIndex;
525 std::vector<RboProps> rboData;
526 };
527 RboState mRboState;
528 void addFreshRenderbuffer(GLuint name);
529 void setBoundRenderbufferIndex();
530 size_t getRboIndex(GLuint name) const;
531 RboProps& boundRboProps();
532 const RboProps& boundRboProps_const() const;
533
534 struct FboState {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800535 GLuint boundDrawFramebuffer;
536 GLuint boundReadFramebuffer;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700537 size_t boundFramebufferIndex;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800538 std::map<GLuint, FboProps> fboData;
539 GLenum drawFboCheckStatus;
540 GLenum readFboCheckStatus;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700541 };
542 FboState mFboState;
543 void addFreshFramebuffer(GLuint name);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800544 FboProps& boundFboProps(GLenum target);
545 const FboProps& boundFboProps_const(GLenum target) const;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700546
Lingfeng Yang69066602016-04-12 09:29:11 -0700547 // Querying framebuffer format
548 GLenum queryRboFormat(GLuint name) const;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800549 GLsizei queryRboSamples(GLuint name) const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700550 GLenum queryTexType(GLuint name) const;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800551 GLsizei queryTexSamples(GLuint name) const;
Lingfeng Yang69066602016-04-12 09:29:11 -0700552
keunyoungb85b2752013-03-08 12:28:03 -0800553 static int compareTexId(const void* pid, const void* prec);
554 TextureRec* addTextureRec(GLuint id, GLenum target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800555 TextureRec* getTextureRec(GLuint id) const;
keunyoungb85b2752013-03-08 12:28:03 -0800556
557public:
558 void getClientStatePointer(GLenum pname, GLvoid** params);
559
560 template <class T>
561 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
562 {
563 bool handled = true;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800564 const VertexAttribState& vertexAttrib = getState(index);
565 const BufferBinding& vertexAttribBufferBinding =
566 m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex];
keunyoungb85b2752013-03-08 12:28:03 -0800567
568 switch(param) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800569#define GL_VERTEX_ATTRIB_BINDING 0x82D4
570 case GL_VERTEX_ATTRIB_BINDING:
571 *ptr = (T)vertexAttrib.bindingindex;
572 break;
573#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
574 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
575 *ptr = (T)vertexAttrib.reloffset;
576 break;
keunyoungb85b2752013-03-08 12:28:03 -0800577 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800578 *ptr = (T)(vertexAttribBufferBinding.buffer);
keunyoungb85b2752013-03-08 12:28:03 -0800579 break;
580 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800581 *ptr = (T)(vertexAttrib.enabled);
582 break;
583#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
584 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
585 *ptr = (T)(vertexAttrib.isInt);
keunyoungb85b2752013-03-08 12:28:03 -0800586 break;
587 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800588 *ptr = (T)(vertexAttrib.size);
keunyoungb85b2752013-03-08 12:28:03 -0800589 break;
590 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800591 *ptr = (T)(vertexAttribBufferBinding.stride);
keunyoungb85b2752013-03-08 12:28:03 -0800592 break;
593 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800594 *ptr = (T)(vertexAttrib.type);
keunyoungb85b2752013-03-08 12:28:03 -0800595 break;
596 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800597 *ptr = (T)(vertexAttrib.normalized);
keunyoungb85b2752013-03-08 12:28:03 -0800598 break;
599 case GL_CURRENT_VERTEX_ATTRIB:
600 handled = false;
601 break;
602 default:
603 handled = false;
604 ERR("unknown vertex-attrib parameter param %d\n", param);
605 }
606 return handled;
607 }
608
609 template <class T>
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800610 bool getClientStateParameter(GLenum param, T* out)
keunyoungb85b2752013-03-08 12:28:03 -0800611 {
612 bool isClientStateParam = false;
613 switch (param) {
614 case GL_CLIENT_ACTIVE_TEXTURE: {
615 GLint tex = getActiveTexture() + GL_TEXTURE0;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800616 *out = tex;
keunyoungb85b2752013-03-08 12:28:03 -0800617 isClientStateParam = true;
618 break;
619 }
620 case GL_VERTEX_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800621 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
622 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800623 isClientStateParam = true;
624 break;
625 }
626 case GL_VERTEX_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800627 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
628 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800629 isClientStateParam = true;
630 break;
631 }
632 case GL_VERTEX_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800633 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
634 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800635 isClientStateParam = true;
636 break;
637 }
638 case GL_COLOR_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800639 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
640 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800641 isClientStateParam = true;
642 break;
643 }
644 case GL_COLOR_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800645 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
646 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800647 isClientStateParam = true;
648 break;
649 }
650 case GL_COLOR_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800651 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
652 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800653 isClientStateParam = true;
654 break;
655 }
656 case GL_NORMAL_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800657 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
658 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800659 isClientStateParam = true;
660 break;
661 }
662 case GL_NORMAL_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800663 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
664 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800665 isClientStateParam = true;
666 break;
667 }
668 case GL_TEXTURE_COORD_ARRAY_SIZE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800669 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
670 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800671 isClientStateParam = true;
672 break;
673 }
674 case GL_TEXTURE_COORD_ARRAY_TYPE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800675 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
676 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800677 isClientStateParam = true;
678 break;
679 }
680 case GL_TEXTURE_COORD_ARRAY_STRIDE: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800681 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
682 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800683 isClientStateParam = true;
684 break;
685 }
686 case GL_POINT_SIZE_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800687 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
688 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800689 isClientStateParam = true;
690 break;
691 }
692 case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800693 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
694 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800695 isClientStateParam = true;
696 break;
697 }
698 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800699 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
700 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800701 isClientStateParam = true;
702 break;
703 }
704 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800705 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
706 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800707 isClientStateParam = true;
708 break;
709 }
710 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800711 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
712 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800713 isClientStateParam = true;
714 break;
715 }
716 case GL_WEIGHT_ARRAY_SIZE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800717 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
718 *out = state.size;
keunyoungb85b2752013-03-08 12:28:03 -0800719 isClientStateParam = true;
720 break;
721 }
722 case GL_WEIGHT_ARRAY_TYPE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800723 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
724 *out = state.type;
keunyoungb85b2752013-03-08 12:28:03 -0800725 isClientStateParam = true;
726 break;
727 }
728 case GL_WEIGHT_ARRAY_STRIDE_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800729 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
730 *out = state.stride;
keunyoungb85b2752013-03-08 12:28:03 -0800731 isClientStateParam = true;
732 break;
733 }
734 case GL_VERTEX_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800735 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
736 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800737 isClientStateParam = true;
738 break;
739 }
740 case GL_NORMAL_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800741 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
742 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800743 isClientStateParam = true;
744 break;
745 }
746 case GL_COLOR_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800747 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
748 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800749 isClientStateParam = true;
750 break;
751 }
752 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800753 const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
754 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800755 isClientStateParam = true;
756 break;
757 }
758 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800759 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
760 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800761 isClientStateParam = true;
762 break;
763 }
764 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800765 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
766 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800767 isClientStateParam = true;
768 break;
769 }
770 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800771 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
772 *out = state.bufferObject;
keunyoungb85b2752013-03-08 12:28:03 -0800773 isClientStateParam = true;
774 break;
775 }
776 case GL_ARRAY_BUFFER_BINDING: {
777 int buffer = getBuffer(GL_ARRAY_BUFFER);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800778 *out = buffer;
keunyoungb85b2752013-03-08 12:28:03 -0800779 isClientStateParam = true;
780 break;
781 }
782 case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
783 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800784 *out = buffer;
keunyoungb85b2752013-03-08 12:28:03 -0800785 isClientStateParam = true;
786 break;
787 }
Lingfeng Yangb0176982016-03-01 21:27:49 -0800788 case GL_MAX_VERTEX_ATTRIBS: {
789 if (m_maxVertexAttribsDirty) {
790 isClientStateParam = false;
791 } else {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800792 *out = m_maxVertexAttribs;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800793 isClientStateParam = true;
794 }
795 break;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800796 }
keunyoungb85b2752013-03-08 12:28:03 -0800797 }
798 return isClientStateParam;
799 }
800
801};
802#endif