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 }; 143 144 typedef std::vector<VertexAttribState> VertexAttribStateVector; 145 typedef std::vector<BufferBinding> VertexAttribBindingVector; 146 147 struct VAOState { VAOStateVAOState148 VAOState(GLuint ibo, int nLoc, int nBindings) : 149 attribState(nLoc), 150 bindingState(nBindings), 151 element_array_buffer_binding(ibo), 152 element_array_buffer_binding_lastEncode(ibo) { } 153 VertexAttribStateVector attribState; 154 VertexAttribBindingVector bindingState; 155 GLuint element_array_buffer_binding; 156 GLuint element_array_buffer_binding_lastEncode; 157 int attributesNeedingUpdateForDraw[CODEC_MAX_VERTEX_ATTRIBUTES]; 158 int numAttributesNeedingUpdateForDraw; 159 }; 160 161 typedef std::map<GLuint, VAOState> VAOStateMap; 162 struct VAOStateRef { VAOStateRefVAOStateRef163 VAOStateRef() { } VAOStateRefVAOStateRef164 VAOStateRef( 165 VAOStateMap::iterator iter) : it(iter) { } vaoStateVAOStateRef166 VAOState& vaoState() { return it->second; } 167 VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; } bufferBindingVAOStateRef168 BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; } bufferBindingsVAOStateRef169 VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; } bufferBindings_constVAOStateRef170 const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; } vaoIdVAOStateRef171 GLuint vaoId() const { return it->first; } iboIdVAOStateRef172 GLuint& iboId() { return it->second.element_array_buffer_binding; } iboIdLastEncodeVAOStateRef173 GLuint& iboIdLastEncode() { return it->second.element_array_buffer_binding_lastEncode; } 174 VAOStateMap::iterator it; 175 }; 176 177 typedef struct { 178 int unpack_alignment; 179 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 186 int pack_alignment; 187 188 int pack_row_length; 189 int pack_skip_pixels; 190 int pack_skip_rows; 191 } PixelStoreState; 192 193 enum { 194 MAX_TEXTURE_UNITS = 256, 195 }; 196 197 public: 198 GLClientState(); 199 GLClientState(int majorVersion, int minorVersion); 200 ~GLClientState(); nLocations()201 int nLocations() { return m_nLocations; } pixelStoreState()202 const PixelStoreState *pixelStoreState() { return &m_pixelStore; } 203 int setPixelStore(GLenum param, GLint value); currentVertexArrayObject()204 GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); } currentVertexBufferBindings()205 const VertexAttribBindingVector& currentVertexBufferBindings() const { 206 return m_currVaoState.bufferBindings_const(); 207 } 208 currentArrayVbo()209 GLuint currentArrayVbo() { return m_arrayBuffer; } currentIndexVbo()210 GLuint currentIndexVbo() { return m_currVaoState.iboId(); } 211 void enable(int location, int state); 212 // 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); 226 void updateEnableDirtyArrayForDraw(); 227 VAOState& currentVaoState(); 228 int getLocation(GLenum loc); setActiveTexture(int texUnit)229 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; }; getActiveTexture()230 int getActiveTexture() const { return m_activeTexture; } setMaxVertexAttribs(int val)231 void setMaxVertexAttribs(int val) { 232 m_maxVertexAttribs = val; 233 m_maxVertexAttribsDirty = false; 234 } 235 236 void addBuffer(GLuint id); 237 void removeBuffer(GLuint id); 238 bool bufferIdExists(GLuint id) const; 239 void unBindBuffer(GLuint id); 240 241 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; 244 bool isNonIndexedBindNoOp(GLenum target, GLuint buffer); 245 bool isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride); 246 247 int getBuffer(GLenum target); 248 GLuint getLastEncodedBufferBind(GLenum target); 249 void setLastEncodedBufferBind(GLenum target, GLuint id); 250 251 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; 254 void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; 255 setCurrentProgram(GLint program)256 void setCurrentProgram(GLint program) { m_currentProgram = program; } setCurrentShaderProgram(GLint program)257 void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; } currentProgram()258 GLint currentProgram() const { return m_currentProgram; } currentShaderProgram()259 GLint currentShaderProgram() const { return m_currentShaderProgram; } 260 261 struct UniformBlockInfoKey { 262 GLuint program; 263 GLuint uniformBlockIndex; 264 }; 265 struct UniformBlockInfoKeyCompare { operatorUniformBlockInfoKeyCompare266 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 280 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms); 281 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const; 282 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 289 /* 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 312 void bindSampler(GLuint unit, GLuint sampler); 313 bool isSamplerBindNoOp(GLuint unit, GLuint sampler); 314 void onDeleteSamplers(GLsizei n, const GLuint* samplers); 315 316 // 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); 333 void setBoundEGLImage(GLenum target, GLeglImageOES image); 334 335 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES). 336 GLuint getBoundTexture(GLenum target) const; 337 // 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; 345 346 // 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 358 // 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); 363 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; 369 370 // glDeleteTextures(...) 371 // Remove references to the to-be-deleted textures. 372 void deleteTextures(GLsizei n, const GLuint* textures); 373 374 // 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; 380 void setBoundRenderbufferFormat(GLenum format); 381 void setBoundRenderbufferSamples(GLsizei samples); 382 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); 388 void setCheckFramebufferStatus(GLenum target, GLenum status); 389 GLenum getCheckFramebufferStatus(GLenum target) const; 390 GLuint boundFramebuffer(GLenum target) const; 391 392 // Texture object -> FBO 393 void attachTextureObject(GLenum target, GLenum attachment, GLuint texture); 394 GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const; 395 396 // RBO -> FBO 397 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; 401 402 // FBO attachments in general 403 bool attachmentHasObject(GLenum target, GLenum attachment) const; 404 GLuint objectOfAttachment(GLenum target, GLenum attachment) const; 405 406 // Transform feedback state 407 void setTransformFeedbackActiveUnpaused(bool activeUnpaused); 408 bool getTransformFeedbackActiveUnpaused() const; 409 410 void setTextureData(SharedTextureDataMap* sharedTexData); 411 // set eglsurface property on default framebuffer 412 // if coming from eglMakeCurrent 413 void fromMakeCurrent(); 414 // 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; 427 428 // Queries the format backing the current framebuffer. 429 // Type differs depending on whether the attachment 430 // is a texture or renderbuffer. 431 void getBoundFramebufferFormat( 432 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; 440 private: 441 void init(); 442 bool m_initialized; 443 PixelStoreState m_pixelStore; 444 445 std::set<GLuint> mBufferIds; 446 447 // GL_ARRAY_BUFFER_BINDING is separate from VAO state 448 GLuint m_arrayBuffer; 449 GLuint m_arrayBuffer_lastEncode; 450 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 480 int m_glesMajorVersion; 481 int m_glesMinorVersion; 482 int m_maxVertexAttribs; 483 bool m_maxVertexAttribsDirty; 484 int m_nLocations; 485 int m_activeTexture; 486 GLint m_currentProgram; 487 GLint m_currentShaderProgram; 488 ProgramPipelineMap m_programPipelines; 489 490 enum TextureTarget { 491 TEXTURE_2D = 0, 492 TEXTURE_EXTERNAL = 1, 493 TEXTURE_CUBE_MAP = 2, 494 TEXTURE_2D_ARRAY = 3, 495 TEXTURE_3D = 4, 496 TEXTURE_2D_MULTISAMPLE = 5, 497 TEXTURE_TARGET_COUNT 498 }; 499 struct TextureUnit { 500 unsigned int enables; 501 GLuint texture[TEXTURE_TARGET_COUNT]; 502 GLuint boundSampler; 503 }; 504 struct TextureState { 505 TextureUnit unit[MAX_TEXTURE_UNITS]; 506 TextureUnit* activeUnit; 507 // Initialized from shared group. 508 SharedTextureDataMap* textureRecs; 509 }; 510 TextureState m_tex; 511 512 // 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 { operatorCubeMapDefCompare523 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); 538 539 int m_max_color_attachments; 540 int m_max_draw_buffers; 541 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 { 554 GLuint boundDrawFramebuffer; 555 GLuint boundReadFramebuffer; 556 size_t boundFramebufferIndex; 557 std::map<GLuint, FboProps> fboData; 558 GLenum drawFboCheckStatus; 559 GLenum readFboCheckStatus; 560 }; 561 FboState mFboState; 562 void addFreshFramebuffer(GLuint name); 563 FboProps& boundFboProps(GLenum target); 564 const FboProps& boundFboProps_const(GLenum target) const; 565 566 // Querying framebuffer format 567 GLenum queryRboFormat(GLuint name) const; 568 GLsizei queryRboSamples(GLuint name) const; 569 GLenum queryTexType(GLuint name) const; 570 GLsizei queryTexSamples(GLuint name) const; 571 572 static int compareTexId(const void* pid, const void* prec); 573 TextureRec* addTextureRec(GLuint id, GLenum target); 574 TextureRec* getTextureRec(GLuint id) const; 575 576 public: 577 void getClientStatePointer(GLenum pname, GLvoid** params); 578 579 template <class T> getVertexAttribParameter(GLuint index,GLenum param,T * ptr)580 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr) 581 { 582 bool handled = true; 583 const VertexAttribState& vertexAttrib = getState(index); 584 const BufferBinding& vertexAttribBufferBinding = 585 m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex]; 586 587 switch(param) { 588 #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; 596 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 597 *ptr = (T)(vertexAttribBufferBinding.buffer); 598 break; 599 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 600 *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); 605 break; 606 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 607 *ptr = (T)(vertexAttrib.size); 608 break; 609 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 610 *ptr = (T)(vertexAttribBufferBinding.stride); 611 break; 612 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 613 *ptr = (T)(vertexAttrib.type); 614 break; 615 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 616 *ptr = (T)(vertexAttrib.normalized); 617 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> getClientStateParameter(GLenum param,T * out)629 bool getClientStateParameter(GLenum param, T* out) 630 { 631 bool isClientStateParam = false; 632 switch (param) { 633 case GL_CLIENT_ACTIVE_TEXTURE: { 634 GLint tex = getActiveTexture() + GL_TEXTURE0; 635 *out = tex; 636 isClientStateParam = true; 637 break; 638 } 639 case GL_VERTEX_ARRAY_SIZE: { 640 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 641 *out = state.size; 642 isClientStateParam = true; 643 break; 644 } 645 case GL_VERTEX_ARRAY_TYPE: { 646 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 647 *out = state.type; 648 isClientStateParam = true; 649 break; 650 } 651 case GL_VERTEX_ARRAY_STRIDE: { 652 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 653 *out = state.stride; 654 isClientStateParam = true; 655 break; 656 } 657 case GL_COLOR_ARRAY_SIZE: { 658 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 659 *out = state.size; 660 isClientStateParam = true; 661 break; 662 } 663 case GL_COLOR_ARRAY_TYPE: { 664 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 665 *out = state.type; 666 isClientStateParam = true; 667 break; 668 } 669 case GL_COLOR_ARRAY_STRIDE: { 670 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 671 *out = state.stride; 672 isClientStateParam = true; 673 break; 674 } 675 case GL_NORMAL_ARRAY_TYPE: { 676 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 677 *out = state.type; 678 isClientStateParam = true; 679 break; 680 } 681 case GL_NORMAL_ARRAY_STRIDE: { 682 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 683 *out = state.stride; 684 isClientStateParam = true; 685 break; 686 } 687 case GL_TEXTURE_COORD_ARRAY_SIZE: { 688 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 689 *out = state.size; 690 isClientStateParam = true; 691 break; 692 } 693 case GL_TEXTURE_COORD_ARRAY_TYPE: { 694 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 695 *out = state.type; 696 isClientStateParam = true; 697 break; 698 } 699 case GL_TEXTURE_COORD_ARRAY_STRIDE: { 700 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 701 *out = state.stride; 702 isClientStateParam = true; 703 break; 704 } 705 case GL_POINT_SIZE_ARRAY_TYPE_OES: { 706 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 707 *out = state.type; 708 isClientStateParam = true; 709 break; 710 } 711 case GL_POINT_SIZE_ARRAY_STRIDE_OES: { 712 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 713 *out = state.stride; 714 isClientStateParam = true; 715 break; 716 } 717 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: { 718 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 719 *out = state.size; 720 isClientStateParam = true; 721 break; 722 } 723 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: { 724 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 725 *out = state.type; 726 isClientStateParam = true; 727 break; 728 } 729 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: { 730 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 731 *out = state.stride; 732 isClientStateParam = true; 733 break; 734 } 735 case GL_WEIGHT_ARRAY_SIZE_OES: { 736 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 737 *out = state.size; 738 isClientStateParam = true; 739 break; 740 } 741 case GL_WEIGHT_ARRAY_TYPE_OES: { 742 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 743 *out = state.type; 744 isClientStateParam = true; 745 break; 746 } 747 case GL_WEIGHT_ARRAY_STRIDE_OES: { 748 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 749 *out = state.stride; 750 isClientStateParam = true; 751 break; 752 } 753 case GL_VERTEX_ARRAY_BUFFER_BINDING: { 754 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 755 *out = state.bufferObject; 756 isClientStateParam = true; 757 break; 758 } 759 case GL_NORMAL_ARRAY_BUFFER_BINDING: { 760 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 761 *out = state.bufferObject; 762 isClientStateParam = true; 763 break; 764 } 765 case GL_COLOR_ARRAY_BUFFER_BINDING: { 766 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 767 *out = state.bufferObject; 768 isClientStateParam = true; 769 break; 770 } 771 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: { 772 const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION); 773 *out = state.bufferObject; 774 isClientStateParam = true; 775 break; 776 } 777 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: { 778 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 779 *out = state.bufferObject; 780 isClientStateParam = true; 781 break; 782 } 783 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: { 784 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 785 *out = state.bufferObject; 786 isClientStateParam = true; 787 break; 788 } 789 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: { 790 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 791 *out = state.bufferObject; 792 isClientStateParam = true; 793 break; 794 } 795 case GL_ARRAY_BUFFER_BINDING: { 796 int buffer = getBuffer(GL_ARRAY_BUFFER); 797 *out = buffer; 798 isClientStateParam = true; 799 break; 800 } 801 case GL_ELEMENT_ARRAY_BUFFER_BINDING: { 802 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER); 803 *out = buffer; 804 isClientStateParam = true; 805 break; 806 } 807 case GL_MAX_VERTEX_ATTRIBS: { 808 if (m_maxVertexAttribsDirty) { 809 isClientStateParam = false; 810 } else { 811 *out = m_maxVertexAttribs; 812 isClientStateParam = true; 813 } 814 break; 815 } 816 } 817 return isClientStateParam; 818 } 819 820 }; 821 #endif 822