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