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 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 { VAOStateRefVAOStateRef159 VAOStateRef() { } VAOStateRefVAOStateRef160 VAOStateRef( 161 VAOStateMap::iterator iter) : it(iter) { } 162 VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; } bufferBindingVAOStateRef163 BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; } bufferBindingsVAOStateRef164 VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; } bufferBindings_constVAOStateRef165 const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; } vaoIdVAOStateRef166 GLuint vaoId() const { return it->first; } iboIdVAOStateRef167 GLuint& iboId() { return it->second.element_array_buffer_binding; } 168 VAOStateMap::iterator it; 169 }; 170 171 typedef struct { 172 int unpack_alignment; 173 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 180 int pack_alignment; 181 182 int pack_row_length; 183 int pack_skip_pixels; 184 int pack_skip_rows; 185 } PixelStoreState; 186 187 enum { 188 MAX_TEXTURE_UNITS = 256, 189 }; 190 191 public: 192 GLClientState(); 193 GLClientState(int majorVersion, int minorVersion); 194 ~GLClientState(); nLocations()195 int nLocations() { return m_nLocations; } pixelStoreState()196 const PixelStoreState *pixelStoreState() { return &m_pixelStore; } 197 int setPixelStore(GLenum param, GLint value); currentVertexArrayObject()198 GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); } currentVertexBufferBindings()199 const VertexAttribBindingVector& currentVertexBufferBindings() const { 200 return m_currVaoState.bufferBindings_const(); 201 } 202 currentArrayVbo()203 GLuint currentArrayVbo() { return m_arrayBuffer; } currentIndexVbo()204 GLuint currentIndexVbo() { return m_currVaoState.iboId(); } 205 void enable(int location, int state); 206 // 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); 220 int getLocation(GLenum loc); setActiveTexture(int texUnit)221 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; }; getActiveTexture()222 int getActiveTexture() const { return m_activeTexture; } setMaxVertexAttribs(int val)223 void setMaxVertexAttribs(int val) { 224 m_maxVertexAttribs = val; 225 m_maxVertexAttribsDirty = false; 226 } 227 228 void addBuffer(GLuint id); 229 void removeBuffer(GLuint id); 230 bool bufferIdExists(GLuint id) const; 231 void unBindBuffer(GLuint id); 232 233 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; 236 237 int getBuffer(GLenum target); 238 239 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; 242 setCurrentProgram(GLint program)243 void setCurrentProgram(GLint program) { m_currentProgram = program; } setCurrentShaderProgram(GLint program)244 void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; } currentProgram()245 GLint currentProgram() const { return m_currentProgram; } currentShaderProgram()246 GLint currentShaderProgram() const { return m_currentShaderProgram; } 247 248 struct UniformBlockInfoKey { 249 GLuint program; 250 GLuint uniformBlockIndex; 251 }; 252 struct UniformBlockInfoKeyCompare { operatorUniformBlockInfoKeyCompare253 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 267 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms); 268 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const; 269 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 276 /* 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); 316 void setBoundEGLImage(GLenum target, GLeglImageOES image); 317 318 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES). 319 GLuint getBoundTexture(GLenum target) const; 320 // 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; 328 329 // 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 341 // 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); 346 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; 352 353 // glDeleteTextures(...) 354 // Remove references to the to-be-deleted textures. 355 void deleteTextures(GLsizei n, const GLuint* textures); 356 357 // 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; 363 void setBoundRenderbufferFormat(GLenum format); 364 void setBoundRenderbufferSamples(GLsizei samples); 365 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); 371 void setCheckFramebufferStatus(GLenum target, GLenum status); 372 GLenum getCheckFramebufferStatus(GLenum target) const; 373 GLuint boundFramebuffer(GLenum target) const; 374 375 // Texture object -> FBO 376 void attachTextureObject(GLenum target, GLenum attachment, GLuint texture); 377 GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const; 378 379 // RBO -> FBO 380 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; 384 385 // FBO attachments in general 386 bool attachmentHasObject(GLenum target, GLenum attachment) const; 387 GLuint objectOfAttachment(GLenum target, GLenum attachment) const; 388 389 // Transform feedback state 390 void setTransformFeedbackActiveUnpaused(bool activeUnpaused); 391 bool getTransformFeedbackActiveUnpaused() const; 392 393 void setTextureData(SharedTextureDataMap* sharedTexData); 394 // set eglsurface property on default framebuffer 395 // if coming from eglMakeCurrent 396 void fromMakeCurrent(); 397 // 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; 410 411 // Queries the format backing the current framebuffer. 412 // Type differs depending on whether the attachment 413 // is a texture or renderbuffer. 414 void getBoundFramebufferFormat( 415 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; 423 private: 424 void init(); 425 bool m_initialized; 426 PixelStoreState m_pixelStore; 427 428 std::set<GLuint> mBufferIds; 429 430 // 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 462 int m_glesMajorVersion; 463 int m_glesMinorVersion; 464 int m_maxVertexAttribs; 465 bool m_maxVertexAttribsDirty; 466 int m_nLocations; 467 int m_activeTexture; 468 GLint m_currentProgram; 469 GLint m_currentShaderProgram; 470 ProgramPipelineMap m_programPipelines; 471 472 enum TextureTarget { 473 TEXTURE_2D = 0, 474 TEXTURE_EXTERNAL = 1, 475 TEXTURE_CUBE_MAP = 2, 476 TEXTURE_2D_ARRAY = 3, 477 TEXTURE_3D = 4, 478 TEXTURE_2D_MULTISAMPLE = 5, 479 TEXTURE_TARGET_COUNT 480 }; 481 struct TextureUnit { 482 unsigned int enables; 483 GLuint texture[TEXTURE_TARGET_COUNT]; 484 }; 485 struct TextureState { 486 TextureUnit unit[MAX_TEXTURE_UNITS]; 487 TextureUnit* activeUnit; 488 // Initialized from shared group. 489 SharedTextureDataMap* textureRecs; 490 }; 491 TextureState m_tex; 492 493 // 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 { operatorCubeMapDefCompare504 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); 519 520 int m_max_color_attachments; 521 int m_max_draw_buffers; 522 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 { 535 GLuint boundDrawFramebuffer; 536 GLuint boundReadFramebuffer; 537 size_t boundFramebufferIndex; 538 std::map<GLuint, FboProps> fboData; 539 GLenum drawFboCheckStatus; 540 GLenum readFboCheckStatus; 541 }; 542 FboState mFboState; 543 void addFreshFramebuffer(GLuint name); 544 FboProps& boundFboProps(GLenum target); 545 const FboProps& boundFboProps_const(GLenum target) const; 546 547 // Querying framebuffer format 548 GLenum queryRboFormat(GLuint name) const; 549 GLsizei queryRboSamples(GLuint name) const; 550 GLenum queryTexType(GLuint name) const; 551 GLsizei queryTexSamples(GLuint name) const; 552 553 static int compareTexId(const void* pid, const void* prec); 554 TextureRec* addTextureRec(GLuint id, GLenum target); 555 TextureRec* getTextureRec(GLuint id) const; 556 557 public: 558 void getClientStatePointer(GLenum pname, GLvoid** params); 559 560 template <class T> getVertexAttribParameter(GLuint index,GLenum param,T * ptr)561 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr) 562 { 563 bool handled = true; 564 const VertexAttribState& vertexAttrib = getState(index); 565 const BufferBinding& vertexAttribBufferBinding = 566 m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex]; 567 568 switch(param) { 569 #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; 577 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 578 *ptr = (T)(vertexAttribBufferBinding.buffer); 579 break; 580 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 581 *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); 586 break; 587 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 588 *ptr = (T)(vertexAttrib.size); 589 break; 590 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 591 *ptr = (T)(vertexAttribBufferBinding.stride); 592 break; 593 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 594 *ptr = (T)(vertexAttrib.type); 595 break; 596 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 597 *ptr = (T)(vertexAttrib.normalized); 598 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> getClientStateParameter(GLenum param,T * out)610 bool getClientStateParameter(GLenum param, T* out) 611 { 612 bool isClientStateParam = false; 613 switch (param) { 614 case GL_CLIENT_ACTIVE_TEXTURE: { 615 GLint tex = getActiveTexture() + GL_TEXTURE0; 616 *out = tex; 617 isClientStateParam = true; 618 break; 619 } 620 case GL_VERTEX_ARRAY_SIZE: { 621 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 622 *out = state.size; 623 isClientStateParam = true; 624 break; 625 } 626 case GL_VERTEX_ARRAY_TYPE: { 627 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 628 *out = state.type; 629 isClientStateParam = true; 630 break; 631 } 632 case GL_VERTEX_ARRAY_STRIDE: { 633 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 634 *out = state.stride; 635 isClientStateParam = true; 636 break; 637 } 638 case GL_COLOR_ARRAY_SIZE: { 639 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 640 *out = state.size; 641 isClientStateParam = true; 642 break; 643 } 644 case GL_COLOR_ARRAY_TYPE: { 645 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 646 *out = state.type; 647 isClientStateParam = true; 648 break; 649 } 650 case GL_COLOR_ARRAY_STRIDE: { 651 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 652 *out = state.stride; 653 isClientStateParam = true; 654 break; 655 } 656 case GL_NORMAL_ARRAY_TYPE: { 657 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 658 *out = state.type; 659 isClientStateParam = true; 660 break; 661 } 662 case GL_NORMAL_ARRAY_STRIDE: { 663 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 664 *out = state.stride; 665 isClientStateParam = true; 666 break; 667 } 668 case GL_TEXTURE_COORD_ARRAY_SIZE: { 669 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 670 *out = state.size; 671 isClientStateParam = true; 672 break; 673 } 674 case GL_TEXTURE_COORD_ARRAY_TYPE: { 675 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 676 *out = state.type; 677 isClientStateParam = true; 678 break; 679 } 680 case GL_TEXTURE_COORD_ARRAY_STRIDE: { 681 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 682 *out = state.stride; 683 isClientStateParam = true; 684 break; 685 } 686 case GL_POINT_SIZE_ARRAY_TYPE_OES: { 687 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 688 *out = state.type; 689 isClientStateParam = true; 690 break; 691 } 692 case GL_POINT_SIZE_ARRAY_STRIDE_OES: { 693 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 694 *out = state.stride; 695 isClientStateParam = true; 696 break; 697 } 698 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: { 699 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 700 *out = state.size; 701 isClientStateParam = true; 702 break; 703 } 704 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: { 705 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 706 *out = state.type; 707 isClientStateParam = true; 708 break; 709 } 710 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: { 711 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 712 *out = state.stride; 713 isClientStateParam = true; 714 break; 715 } 716 case GL_WEIGHT_ARRAY_SIZE_OES: { 717 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 718 *out = state.size; 719 isClientStateParam = true; 720 break; 721 } 722 case GL_WEIGHT_ARRAY_TYPE_OES: { 723 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 724 *out = state.type; 725 isClientStateParam = true; 726 break; 727 } 728 case GL_WEIGHT_ARRAY_STRIDE_OES: { 729 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 730 *out = state.stride; 731 isClientStateParam = true; 732 break; 733 } 734 case GL_VERTEX_ARRAY_BUFFER_BINDING: { 735 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 736 *out = state.bufferObject; 737 isClientStateParam = true; 738 break; 739 } 740 case GL_NORMAL_ARRAY_BUFFER_BINDING: { 741 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 742 *out = state.bufferObject; 743 isClientStateParam = true; 744 break; 745 } 746 case GL_COLOR_ARRAY_BUFFER_BINDING: { 747 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 748 *out = state.bufferObject; 749 isClientStateParam = true; 750 break; 751 } 752 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: { 753 const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION); 754 *out = state.bufferObject; 755 isClientStateParam = true; 756 break; 757 } 758 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: { 759 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 760 *out = state.bufferObject; 761 isClientStateParam = true; 762 break; 763 } 764 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: { 765 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 766 *out = state.bufferObject; 767 isClientStateParam = true; 768 break; 769 } 770 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: { 771 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 772 *out = state.bufferObject; 773 isClientStateParam = true; 774 break; 775 } 776 case GL_ARRAY_BUFFER_BINDING: { 777 int buffer = getBuffer(GL_ARRAY_BUFFER); 778 *out = buffer; 779 isClientStateParam = true; 780 break; 781 } 782 case GL_ELEMENT_ARRAY_BUFFER_BINDING: { 783 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER); 784 *out = buffer; 785 isClientStateParam = true; 786 break; 787 } 788 case GL_MAX_VERTEX_ATTRIBS: { 789 if (m_maxVertexAttribsDirty) { 790 isClientStateParam = false; 791 } else { 792 *out = m_maxVertexAttribs; 793 isClientStateParam = true; 794 } 795 break; 796 } 797 } 798 return isClientStateParam; 799 } 800 801 }; 802 #endif 803