2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef _GL_CLIENT_STATE_H_
17 #define _GL_CLIENT_STATE_H_
25 #include "TextureSharedData.h"
28 #include <GLES/glext.h>
29 #include <GLES2/gl2.h>
30 #include <GLES2/gl2ext.h>
35 #include "codec_defs.h"
41 // Tracking framebuffer objects:
42 // which framebuffer is bound,
43 // and which texture names
44 // are currently bound to which attachment points.
49 GLuint colorAttachment0_texture;
50 GLuint depthAttachment_texture;
51 GLuint stencilAttachment_texture;
53 bool colorAttachment0_hasTexObj;
54 bool depthAttachment_hasTexObj;
55 bool stencilAttachment_hasTexObj;
57 GLuint colorAttachment0_rbo;
58 GLuint depthAttachment_rbo;
59 GLuint stencilAttachment_rbo;
61 bool colorAttachment0_hasRbo;
62 bool depthAttachment_hasRbo;
63 bool stencilAttachment_hasRbo;
74 // Enum for describing whether a framebuffer attachment
75 // is a texture or renderbuffer.
76 enum FboAttachmentType {
77 FBO_ATTACHMENT_RENDERBUFFER = 0,
78 FBO_ATTACHMENT_TEXTURE = 1,
79 FBO_ATTACHMENT_NONE = 2
82 // Tracking FBO format
83 struct FboFormatInfo {
84 FboAttachmentType type;
86 GLint tex_internalformat;
89 GLsizei tex_multisamples;
98 POINTSIZE_LOCATION = 3,
99 TEXCOORD0_LOCATION = 4,
100 TEXCOORD1_LOCATION = 5,
101 TEXCOORD2_LOCATION = 6,
102 TEXCOORD3_LOCATION = 7,
103 TEXCOORD4_LOCATION = 8,
104 TEXCOORD5_LOCATION = 9,
105 TEXCOORD6_LOCATION = 10,
106 TEXCOORD7_LOCATION = 11,
107 MATRIXINDEX_LOCATION = 12,
108 WEIGHT_LOCATION = 13,
120 unsigned int elementSize;
121 bool enableDirty; // true if any enable state has changed since last draw
126 int unpack_alignment;
128 int unpack_row_length;
129 int unpack_image_height;
130 int unpack_skip_pixels;
131 int unpack_skip_rows;
132 int unpack_skip_images;
137 int pack_skip_pixels;
142 MAX_TEXTURE_UNITS = 256,
146 GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
148 int nLocations() { return m_nLocations; }
149 const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
150 int setPixelStore(GLenum param, GLint value);
151 GLuint currentArrayVbo() { return m_currentArrayVbo; }
152 GLuint currentIndexVbo() { return m_currentIndexVbo; }
153 void enable(int location, int state);
154 void setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
155 void setBufferObject(int location, GLuint id);
156 const VertexAttribState *getState(int location);
157 const VertexAttribState *getStateAndEnableDirty(int location, bool *enableChanged);
158 int getLocation(GLenum loc);
159 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
160 int getActiveTexture() const { return m_activeTexture; }
161 void setMaxVertexAttribs(int val) {
162 m_maxVertexAttribs = val;
163 m_maxVertexAttribsDirty = false;
166 void unBindBuffer(GLuint id)
168 if (m_currentArrayVbo == id) m_currentArrayVbo = 0;
169 else if (m_currentIndexVbo == id) m_currentIndexVbo = 0;
172 int bindBuffer(GLenum target, GLuint id)
176 case GL_ARRAY_BUFFER:
177 m_currentArrayVbo = id;
179 case GL_ELEMENT_ARRAY_BUFFER:
180 m_currentIndexVbo = id;
188 int getBuffer(GLenum target)
192 case GL_ARRAY_BUFFER:
193 ret = m_currentArrayVbo;
195 case GL_ELEMENT_ARRAY_BUFFER:
196 ret = m_currentIndexVbo;
203 size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
204 size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
205 size_t clearBufferNumElts(GLenum buffer) const;
207 void setCurrentProgram(GLint program) { m_currentProgram = program; }
208 GLint currentProgram() const { return m_currentProgram; }
210 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
211 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
212 /* OES_EGL_image_external
214 * These functions manipulate GL state which interacts with the
215 * OES_EGL_image_external extension, to support client-side emulation on
216 * top of host implementations that don't have it.
218 * Most of these calls should only be used with TEXTURE_2D or
219 * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
220 * targets should bypass this. An exception is bindTexture(), which should
221 * see all glBindTexture() calls for any target.
224 // glActiveTexture(GL_TEXTURE0 + i)
225 // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
226 GLenum setActiveTextureUnit(GLenum texture);
227 GLenum getActiveTextureUnit() const;
229 // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
230 void enableTextureTarget(GLenum target);
232 // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
233 void disableTextureTarget(GLenum target);
235 // Implements the target priority logic:
236 // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
237 // * Return GL_TEXTURE_2D if enabled, else
238 // * Return the allDisabled value.
239 // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
240 // simpler; for other cases passing a recognizable enum like GL_ZERO or
241 // GL_INVALID_ENUM is appropriate.
242 GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
244 // glBindTexture(GL_TEXTURE_*, ...)
245 // Set the target binding of the active texture unit to texture. Returns
246 // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
247 // previously been bound to a different target. If firstUse is not NULL,
248 // it is set to indicate whether this is the first use of the texture.
249 // For accurate error detection, bindTexture should be called for *all*
250 // targets, not just 2D and EXTERNAL_OES.
251 GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
252 void setBoundEGLImage(GLenum target, GLeglImageOES image);
254 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
255 GLuint getBoundTexture(GLenum target) const;
256 // Other publicly-visible texture queries
257 GLenum queryTexLastBoundTarget(GLuint name) const;
258 GLenum queryTexFormat(GLuint name) const;
259 GLint queryTexInternalFormat(GLuint name) const;
260 GLsizei queryTexWidth(GLsizei level, GLuint name) const;
261 GLsizei queryTexHeight(GLsizei level, GLuint name) const;
262 GLsizei queryTexDepth(GLsizei level, GLuint name) const;
263 bool queryTexEGLImageBacked(GLuint name) const;
265 // For AMD GPUs, it is easy for the emulator to segfault
266 // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
267 // and uses GL_LUMINANCE as internal format.
268 // In particular, the segfault happens when negative components of
269 // cube maps are defined before positive ones,
270 // This procedure checks internal state to see if we have defined
271 // the positive component of a cube map already. If not, it returns
272 // which positive component needs to be defined first.
273 // If there is no need for the extra definition, 0 is returned.
274 GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level,
275 GLenum internalformat);
277 // Tracks the format of the currently bound texture.
278 // This is to pass dEQP tests for fbo completeness.
279 void setBoundTextureInternalFormat(GLenum target, GLint format);
280 void setBoundTextureFormat(GLenum target, GLenum format);
281 void setBoundTextureType(GLenum target, GLenum type);
282 void setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
283 void setBoundTextureSamples(GLenum target, GLsizei samples);
285 // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
286 void setBoundTextureImmutableFormat(GLenum target);
287 bool isBoundTextureImmutableFormat(GLenum target) const;
289 // glDeleteTextures(...)
290 // Remove references to the to-be-deleted textures.
291 void deleteTextures(GLsizei n, const GLuint* textures);
293 // Render buffer objects
294 void addRenderbuffers(GLsizei n, GLuint* renderbuffers);
295 void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers);
296 bool usedRenderbufferName(GLuint name) const;
297 void bindRenderbuffer(GLenum target, GLuint name);
298 GLuint boundRenderbuffer() const;
299 void setBoundRenderbufferFormat(GLenum format);
301 // Frame buffer objects
302 void addFramebuffers(GLsizei n, GLuint* framebuffers);
303 void removeFramebuffers(GLsizei n, const GLuint* framebuffers);
304 bool usedFramebufferName(GLuint name) const;
305 void bindFramebuffer(GLenum target, GLuint name);
306 void setCheckFramebufferStatus(GLenum status);
307 GLenum getCheckFramebufferStatus() const;
308 GLuint boundFramebuffer() const;
310 // Texture object -> FBO
311 void attachTextureObject(GLenum attachment, GLuint texture);
312 GLuint getFboAttachmentTextureId(GLenum attachment) const;
315 void attachRbo(GLenum attachment, GLuint renderbuffer);
316 GLuint getFboAttachmentRboId(GLenum attachment) const;
318 // FBO attachments in general
319 bool attachmentHasObject(GLenum attachment) const;
321 void setTextureData(SharedTextureDataMap* sharedTexData);
322 // set eglsurface property on default framebuffer
323 // if coming from eglMakeCurrent
324 void fromMakeCurrent();
326 // Queries the format backing the current framebuffer.
327 // Type differs depending on whether the attachment
328 // is a texture or renderbuffer.
329 void getBoundFramebufferFormat(
330 GLenum attachment, FboFormatInfo* res_info) const;
333 PixelStoreState m_pixelStore;
334 VertexAttribState *m_states;
335 int m_glesMajorVersion;
336 int m_glesMinorVersion;
337 int m_maxVertexAttribs;
338 bool m_maxVertexAttribsDirty;
340 GLuint m_currentArrayVbo;
341 GLuint m_currentIndexVbo;
343 GLint m_currentProgram;
345 bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
349 TEXTURE_EXTERNAL = 1,
350 TEXTURE_CUBE_MAP = 2,
351 TEXTURE_2D_ARRAY = 3,
353 TEXTURE_2D_MULTISAMPLE = 5,
357 unsigned int enables;
358 GLuint texture[TEXTURE_TARGET_COUNT];
360 struct TextureState {
361 TextureUnit unit[MAX_TEXTURE_UNITS];
362 TextureUnit* activeUnit;
363 // Initialized from shared group.
364 SharedTextureDataMap* textureRecs;
368 // State tracking of cube map definitions.
369 // Currently used only for driver workarounds
370 // when using GL_LUMINANCE and defining cube maps with
376 GLenum internalformat;
378 struct CubeMapDefCompare {
379 bool operator() (const CubeMapDef& a,
380 const CubeMapDef& b) const {
381 if (a.id != b.id) return a.id < b.id;
382 if (a.target != b.target) return a.target < b.target;
383 if (a.level != b.level) return a.level < b.level;
384 if (a.internalformat != b.internalformat)
385 return a.internalformat < b.internalformat;
389 std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs;
390 void writeCopyTexImageState(GLenum target, GLint level,
391 GLenum internalformat);
392 GLenum copyTexImageNeededTarget(GLenum target, GLint level,
393 GLenum internalformat);
396 GLuint boundRenderbuffer;
397 size_t boundRenderbufferIndex;
398 std::vector<RboProps> rboData;
401 void addFreshRenderbuffer(GLuint name);
402 void setBoundRenderbufferIndex();
403 size_t getRboIndex(GLuint name) const;
404 RboProps& boundRboProps();
405 const RboProps& boundRboProps_const() const;
408 GLuint boundFramebuffer;
409 size_t boundFramebufferIndex;
410 std::vector<FboProps> fboData;
411 GLenum fboCheckStatus;
414 void addFreshFramebuffer(GLuint name);
415 void setBoundFramebufferIndex();
416 size_t getFboIndex(GLuint name) const;
417 FboProps& boundFboProps();
418 const FboProps& boundFboProps_const() const;
420 // Querying framebuffer format
421 GLenum queryRboFormat(GLuint name) const;
422 GLenum queryTexType(GLuint name) const;
423 GLsizei queryTexSamples(GLuint name) const;
425 static int compareTexId(const void* pid, const void* prec);
426 TextureRec* addTextureRec(GLuint id, GLenum target);
427 TextureRec* getTextureRec(GLuint id) const;
430 void getClientStatePointer(GLenum pname, GLvoid** params);
433 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
436 const VertexAttribState *vertexAttrib = getState(index);
437 if (vertexAttrib == NULL) {
438 ERR("getVeterxAttriParameter for non existant index %d\n", index);
444 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
445 *ptr = (T)(vertexAttrib->bufferObject);
447 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
448 *ptr = (T)(vertexAttrib->enabled);
450 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
451 *ptr = (T)(vertexAttrib->size);
453 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
454 *ptr = (T)(vertexAttrib->stride);
456 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
457 *ptr = (T)(vertexAttrib->type);
459 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
460 *ptr = (T)(vertexAttrib->normalized);
462 case GL_CURRENT_VERTEX_ATTRIB:
467 ERR("unknown vertex-attrib parameter param %d\n", param);
473 bool getClientStateParameter(GLenum param, T* ptr)
475 bool isClientStateParam = false;
477 case GL_CLIENT_ACTIVE_TEXTURE: {
478 GLint tex = getActiveTexture() + GL_TEXTURE0;
480 isClientStateParam = true;
483 case GL_VERTEX_ARRAY_SIZE: {
484 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
486 isClientStateParam = true;
489 case GL_VERTEX_ARRAY_TYPE: {
490 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
492 isClientStateParam = true;
495 case GL_VERTEX_ARRAY_STRIDE: {
496 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
497 *ptr = state->stride;
498 isClientStateParam = true;
501 case GL_COLOR_ARRAY_SIZE: {
502 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
504 isClientStateParam = true;
507 case GL_COLOR_ARRAY_TYPE: {
508 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
510 isClientStateParam = true;
513 case GL_COLOR_ARRAY_STRIDE: {
514 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
515 *ptr = state->stride;
516 isClientStateParam = true;
519 case GL_NORMAL_ARRAY_TYPE: {
520 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
522 isClientStateParam = true;
525 case GL_NORMAL_ARRAY_STRIDE: {
526 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
527 *ptr = state->stride;
528 isClientStateParam = true;
531 case GL_TEXTURE_COORD_ARRAY_SIZE: {
532 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
534 isClientStateParam = true;
537 case GL_TEXTURE_COORD_ARRAY_TYPE: {
538 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
540 isClientStateParam = true;
543 case GL_TEXTURE_COORD_ARRAY_STRIDE: {
544 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
545 *ptr = state->stride;
546 isClientStateParam = true;
549 case GL_POINT_SIZE_ARRAY_TYPE_OES: {
550 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
552 isClientStateParam = true;
555 case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
556 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
557 *ptr = state->stride;
558 isClientStateParam = true;
561 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
562 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
564 isClientStateParam = true;
567 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
568 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
570 isClientStateParam = true;
573 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
574 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
575 *ptr = state->stride;
576 isClientStateParam = true;
579 case GL_WEIGHT_ARRAY_SIZE_OES: {
580 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
582 isClientStateParam = true;
585 case GL_WEIGHT_ARRAY_TYPE_OES: {
586 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
588 isClientStateParam = true;
591 case GL_WEIGHT_ARRAY_STRIDE_OES: {
592 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
593 *ptr = state->stride;
594 isClientStateParam = true;
597 case GL_VERTEX_ARRAY_BUFFER_BINDING: {
598 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
599 *ptr = state->bufferObject;
600 isClientStateParam = true;
603 case GL_NORMAL_ARRAY_BUFFER_BINDING: {
604 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
605 *ptr = state->bufferObject;
606 isClientStateParam = true;
609 case GL_COLOR_ARRAY_BUFFER_BINDING: {
610 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
611 *ptr = state->bufferObject;
612 isClientStateParam = true;
615 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
616 const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
617 *ptr = state->bufferObject;
618 isClientStateParam = true;
621 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
622 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
623 *ptr = state->bufferObject;
624 isClientStateParam = true;
627 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
628 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
629 *ptr = state->bufferObject;
630 isClientStateParam = true;
633 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
634 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
635 *ptr = state->bufferObject;
636 isClientStateParam = true;
639 case GL_ARRAY_BUFFER_BINDING: {
640 int buffer = getBuffer(GL_ARRAY_BUFFER);
642 isClientStateParam = true;
645 case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
646 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
648 isClientStateParam = true;
651 case GL_MAX_VERTEX_ATTRIBS: {
652 if (m_maxVertexAttribsDirty) {
653 isClientStateParam = false;
655 *ptr = m_maxVertexAttribs;
656 isClientStateParam = true;
661 return isClientStateParam;