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 #include "GLClientState.h" 17 #include "GLESTextureUtils.h" 18 #include "ErrorLog.h" 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include "glUtils.h" 23 #include <cutils/log.h> 24 25 #ifndef MAX 26 #define MAX(a, b) ((a) < (b) ? (b) : (a)) 27 #endif 28 29 // Don't include these in the .h file, or we get weird compile errors. 30 #include <GLES3/gl3.h> 31 #include <GLES3/gl31.h> 32 33 void GLClientState::init() { 34 m_initialized = false; 35 m_nLocations = CODEC_MAX_VERTEX_ATTRIBUTES; 36 37 m_arrayBuffer = 0; 38 m_max_vertex_attrib_bindings = m_nLocations; 39 addVertexArrayObject(0); 40 setVertexArrayObject(0); 41 // init gl constans; 42 m_currVaoState[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY; 43 m_currVaoState[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY; 44 m_currVaoState[COLOR_LOCATION].glConst = GL_COLOR_ARRAY; 45 m_currVaoState[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES; 46 m_currVaoState[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 47 m_currVaoState[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 48 m_currVaoState[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 49 m_currVaoState[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 50 m_currVaoState[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 51 m_currVaoState[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 52 m_currVaoState[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 53 m_currVaoState[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 54 m_currVaoState[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES; 55 m_currVaoState[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES; 56 57 m_copyReadBuffer = 0; 58 m_copyWriteBuffer = 0; 59 m_pixelPackBuffer = 0; 60 m_pixelUnpackBuffer = 0; 61 m_transformFeedbackBuffer = 0; 62 m_uniformBuffer = 0; 63 m_atomicCounterBuffer = 0; 64 m_dispatchIndirectBuffer = 0; 65 m_drawIndirectBuffer = 0; 66 m_shaderStorageBuffer = 0; 67 68 m_transformFeedbackActiveUnpaused = false; 69 70 // to be modified later when these are queried from host. 71 m_max_transform_feedback_separate_attribs = 0; 72 m_max_uniform_buffer_bindings = 0; 73 m_max_atomic_counter_buffer_bindings = 0; 74 m_max_shader_storage_buffer_bindings = 0; 75 76 m_activeTexture = 0; 77 m_currentProgram = 0; 78 m_currentShaderProgram = 0; 79 80 m_pixelStore.unpack_alignment = 4; 81 m_pixelStore.pack_alignment = 4; 82 83 m_pixelStore.unpack_row_length = 0; 84 m_pixelStore.unpack_image_height = 0; 85 m_pixelStore.unpack_skip_pixels = 0; 86 m_pixelStore.unpack_skip_rows = 0; 87 m_pixelStore.unpack_skip_images = 0; 88 89 m_pixelStore.pack_row_length = 0; 90 m_pixelStore.pack_skip_pixels = 0; 91 m_pixelStore.pack_skip_rows = 0; 92 93 memset(m_tex.unit, 0, sizeof(m_tex.unit)); 94 m_tex.activeUnit = &m_tex.unit[0]; 95 m_tex.textureRecs = NULL; 96 97 mRboState.boundRenderbuffer = 0; 98 mRboState.boundRenderbufferIndex = 0; 99 100 mFboState.boundDrawFramebuffer = 0; 101 mFboState.boundReadFramebuffer = 0; 102 mFboState.drawFboCheckStatus = GL_NONE; 103 mFboState.readFboCheckStatus = GL_NONE; 104 105 m_maxVertexAttribsDirty = true; 106 } 107 108 GLClientState::GLClientState() 109 { 110 init(); 111 } 112 113 GLClientState::GLClientState(int majorVersion, int minorVersion) : 114 m_glesMajorVersion(majorVersion), 115 m_glesMinorVersion(minorVersion) { 116 init(); 117 } 118 119 GLClientState::~GLClientState() 120 { 121 } 122 123 void GLClientState::enable(int location, int state) 124 { 125 m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled); 126 m_currVaoState[location].enabled = state; 127 } 128 129 void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt) 130 { 131 m_currVaoState[location].size = size; 132 m_currVaoState[location].type = type; 133 m_currVaoState[location].stride = stride; 134 m_currVaoState[location].data = (void*)data; 135 m_currVaoState[location].bufferObject = m_arrayBuffer; 136 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0; 137 switch (type) { 138 case GL_INT_2_10_10_10_REV: 139 case GL_UNSIGNED_INT_2_10_10_10_REV: 140 m_currVaoState[location].elementSize = 141 m_currVaoState[location].elementSize / 4; 142 break; 143 default: 144 break; 145 } 146 m_currVaoState[location].normalized = normalized; 147 m_currVaoState[location].isInt = isInt; 148 } 149 150 void GLClientState::setVertexBindingDivisor(int bindingindex, GLuint divisor) { 151 m_currVaoState.bufferBinding(bindingindex).divisor = divisor; 152 } 153 154 const GLClientState::BufferBinding& GLClientState::getCurrAttributeBindingInfo(int attribindex) { 155 return m_currVaoState.bufferBindings_const()[m_currVaoState[attribindex].bindingindex]; 156 } 157 158 void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) { 159 m_currVaoState[attribindex].bindingindex = bindingindex; 160 } 161 162 void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) { 163 m_currVaoState[location].size = size; 164 m_currVaoState[location].type = type; 165 m_currVaoState[location].normalized = normalized; 166 m_currVaoState[location].reloffset = reloffset; 167 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0; 168 switch (type) { 169 case GL_INT_2_10_10_10_REV: 170 case GL_UNSIGNED_INT_2_10_10_10_REV: 171 m_currVaoState[location].elementSize = 172 m_currVaoState[location].elementSize / 4; 173 break; 174 default: 175 break; 176 } 177 m_currVaoState[location].isInt = isInt; 178 } 179 180 void GLClientState::addVertexArrayObjects(GLsizei n, GLuint* arrays) { 181 for (GLsizei i = 0; i < n; i++) { 182 addVertexArrayObject(arrays[i]); 183 } 184 } 185 186 void GLClientState::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) { 187 for (GLsizei i = 0; i < n; i++) { 188 if (arrays[i] && m_currVaoState.vaoId() == arrays[i]) { 189 setVertexArrayObject(0); 190 } 191 removeVertexArrayObject(arrays[i]); 192 } 193 } 194 195 void GLClientState::addVertexArrayObject(GLuint name) { 196 if (m_vaoMap.find(name) != 197 m_vaoMap.end()) { 198 ALOGE("%s: ERROR: %u already part of current VAO state!", 199 __FUNCTION__, name); 200 return; 201 } 202 203 m_vaoMap.insert( 204 VAOStateMap::value_type( 205 name, 206 VAOState(0, m_nLocations, std::max(m_nLocations, m_max_vertex_attrib_bindings)))); 207 VertexAttribStateVector& attribState = 208 m_vaoMap.find(name)->second.attribState; 209 for (int i = 0; i < m_nLocations; i++) { 210 attribState[i].enabled = 0; 211 attribState[i].enableDirty = false; 212 attribState[i].data = 0; 213 attribState[i].reloffset = 0; 214 attribState[i].bindingindex = i; 215 attribState[i].divisor = 0; 216 attribState[i].size = 4; // 4 is the default size 217 attribState[i].type = GL_FLOAT; // GL_FLOAT is the default type 218 } 219 220 VertexAttribBindingVector& bindingState = 221 m_vaoMap.find(name)->second.bindingState; 222 for (int i = 0; i < bindingState.size(); i++) { 223 bindingState[i].effectiveStride = 16; 224 } 225 } 226 227 void GLClientState::removeVertexArrayObject(GLuint name) { 228 if (name == 0) { 229 ALOGE("%s: ERROR: cannot delete VAO 0!", 230 __FUNCTION__); 231 return; 232 } 233 if (m_vaoMap.find(name) == 234 m_vaoMap.end()) { 235 ALOGE("%s: ERROR: %u not found in VAO state!", 236 __FUNCTION__, name); 237 return; 238 } 239 m_vaoMap.erase(name); 240 } 241 242 void GLClientState::setVertexArrayObject(GLuint name) { 243 if (m_vaoMap.find(name) == 244 m_vaoMap.end()) { 245 ALOGE("%s: ERROR: %u not found in VAO state!", 246 __FUNCTION__, name); 247 return; 248 } 249 250 if (name && m_currVaoState.vaoId() == name) { 251 ALOGV("%s: set vao to self, no-op (%u)", 252 __FUNCTION__, name); 253 return; 254 } 255 256 m_currVaoState = 257 VAOStateRef(m_vaoMap.find(name)); 258 ALOGV("%s: set vao to %u (%u) %u %u", __FUNCTION__, 259 name, 260 m_currVaoState.vaoId(), 261 m_arrayBuffer, 262 m_currVaoState.iboId()); 263 } 264 265 bool GLClientState::isVertexArrayObject(GLuint vao) const { 266 return m_vaoMap.find(vao) != m_vaoMap.end(); 267 } 268 269 const GLClientState::VertexAttribState& GLClientState::getState(int location) 270 { 271 return m_currVaoState[location]; 272 } 273 274 const GLClientState::VertexAttribState& GLClientState::getStateAndEnableDirty(int location, bool *enableChanged) 275 { 276 if (enableChanged) { 277 *enableChanged = m_currVaoState[location].enableDirty; 278 } 279 280 m_currVaoState[location].enableDirty = false; 281 return m_currVaoState[location]; 282 } 283 284 int GLClientState::getLocation(GLenum loc) 285 { 286 int retval; 287 288 switch(loc) { 289 case GL_VERTEX_ARRAY: 290 retval = int(VERTEX_LOCATION); 291 break; 292 case GL_NORMAL_ARRAY: 293 retval = int(NORMAL_LOCATION); 294 break; 295 case GL_COLOR_ARRAY: 296 retval = int(COLOR_LOCATION); 297 break; 298 case GL_POINT_SIZE_ARRAY_OES: 299 retval = int(POINTSIZE_LOCATION); 300 break; 301 case GL_TEXTURE_COORD_ARRAY: 302 retval = int (TEXCOORD0_LOCATION + m_activeTexture); 303 break; 304 case GL_MATRIX_INDEX_ARRAY_OES: 305 retval = int (MATRIXINDEX_LOCATION); 306 break; 307 case GL_WEIGHT_ARRAY_OES: 308 retval = int (WEIGHT_LOCATION); 309 break; 310 default: 311 retval = loc; 312 } 313 return retval; 314 } 315 316 static void sClearIndexedBufferBinding(GLuint id, std::vector<GLClientState::BufferBinding>& bindings) { 317 for (size_t i = 0; i < bindings.size(); i++) { 318 if (bindings[i].buffer == id) { 319 bindings[i].offset = 0; 320 bindings[i].stride = 0; 321 bindings[i].effectiveStride = 16; 322 bindings[i].size = 0; 323 bindings[i].buffer = 0; 324 bindings[i].divisor = 0; 325 } 326 } 327 } 328 329 void GLClientState::addBuffer(GLuint id) { 330 mBufferIds.insert(id); 331 } 332 333 void GLClientState::removeBuffer(GLuint id) { 334 mBufferIds.erase(id); 335 } 336 337 bool GLClientState::bufferIdExists(GLuint id) const { 338 return mBufferIds.find(id) != mBufferIds.end(); 339 } 340 341 void GLClientState::unBindBuffer(GLuint id) { 342 if (m_arrayBuffer == id) m_arrayBuffer = 0; 343 if (m_currVaoState.iboId() == id) m_currVaoState.iboId() = 0; 344 if (m_copyReadBuffer == id) 345 m_copyReadBuffer = 0; 346 if (m_copyWriteBuffer == id) 347 m_copyWriteBuffer = 0; 348 if (m_pixelPackBuffer == id) 349 m_pixelPackBuffer = 0; 350 if (m_pixelUnpackBuffer == id) 351 m_pixelUnpackBuffer = 0; 352 if (m_transformFeedbackBuffer == id) 353 m_transformFeedbackBuffer = 0; 354 if (m_uniformBuffer == id) 355 m_uniformBuffer = 0; 356 if (m_atomicCounterBuffer == id) 357 m_atomicCounterBuffer = 0; 358 if (m_dispatchIndirectBuffer == id) 359 m_dispatchIndirectBuffer = 0; 360 if (m_drawIndirectBuffer == id) 361 m_drawIndirectBuffer = 0; 362 if (m_shaderStorageBuffer == id) 363 m_shaderStorageBuffer = 0; 364 365 sClearIndexedBufferBinding(id, m_indexedTransformFeedbackBuffers); 366 sClearIndexedBufferBinding(id, m_indexedUniformBuffers); 367 sClearIndexedBufferBinding(id, m_indexedAtomicCounterBuffers); 368 sClearIndexedBufferBinding(id, m_indexedShaderStorageBuffers); 369 sClearIndexedBufferBinding(id, m_currVaoState.bufferBindings()); 370 } 371 372 int GLClientState::bindBuffer(GLenum target, GLuint id) 373 { 374 int err = 0; 375 switch(target) { 376 case GL_ARRAY_BUFFER: 377 m_arrayBuffer = id; 378 break; 379 case GL_ELEMENT_ARRAY_BUFFER: 380 m_currVaoState.iboId() = id; 381 break; 382 case GL_COPY_READ_BUFFER: 383 m_copyReadBuffer = id; 384 break; 385 case GL_COPY_WRITE_BUFFER: 386 m_copyWriteBuffer = id; 387 break; 388 case GL_PIXEL_PACK_BUFFER: 389 m_pixelPackBuffer = id; 390 break; 391 case GL_PIXEL_UNPACK_BUFFER: 392 m_pixelUnpackBuffer = id; 393 break; 394 case GL_TRANSFORM_FEEDBACK_BUFFER: 395 m_transformFeedbackBuffer = id; 396 break; 397 case GL_UNIFORM_BUFFER: 398 m_uniformBuffer = id; 399 break; 400 case GL_ATOMIC_COUNTER_BUFFER: 401 m_atomicCounterBuffer = id; 402 break; 403 case GL_DISPATCH_INDIRECT_BUFFER: 404 m_dispatchIndirectBuffer = id; 405 break; 406 case GL_DRAW_INDIRECT_BUFFER: 407 m_drawIndirectBuffer = id; 408 break; 409 case GL_SHADER_STORAGE_BUFFER: 410 m_shaderStorageBuffer = id; 411 break; 412 default: 413 err = -1; 414 } 415 return err; 416 } 417 418 void GLClientState::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) { 419 switch (target) { 420 case GL_TRANSFORM_FEEDBACK_BUFFER: 421 m_indexedTransformFeedbackBuffers[index].buffer = buffer; 422 m_indexedTransformFeedbackBuffers[index].offset = offset; 423 m_indexedTransformFeedbackBuffers[index].size = size; 424 m_indexedTransformFeedbackBuffers[index].stride = stride; 425 break; 426 case GL_UNIFORM_BUFFER: 427 m_indexedUniformBuffers[index].buffer = buffer; 428 m_indexedUniformBuffers[index].offset = offset; 429 m_indexedUniformBuffers[index].size = size; 430 m_indexedUniformBuffers[index].stride = stride; 431 break; 432 case GL_ATOMIC_COUNTER_BUFFER: 433 m_indexedAtomicCounterBuffers[index].buffer = buffer; 434 m_indexedAtomicCounterBuffers[index].offset = offset; 435 m_indexedAtomicCounterBuffers[index].size = size; 436 m_indexedAtomicCounterBuffers[index].stride = stride; 437 break; 438 case GL_SHADER_STORAGE_BUFFER: 439 m_indexedShaderStorageBuffers[index].buffer = buffer; 440 m_indexedShaderStorageBuffers[index].offset = offset; 441 m_indexedShaderStorageBuffers[index].size = size; 442 m_indexedShaderStorageBuffers[index].stride = stride; 443 break; 444 default: 445 m_currVaoState.bufferBinding(index).buffer = buffer; 446 m_currVaoState.bufferBinding(index).offset = offset; 447 m_currVaoState.bufferBinding(index).size = size; 448 m_currVaoState.bufferBinding(index).stride = stride; 449 m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride; 450 return; 451 } 452 } 453 454 int GLClientState::getMaxIndexedBufferBindings(GLenum target) const { 455 switch (target) { 456 case GL_TRANSFORM_FEEDBACK_BUFFER: 457 return m_indexedTransformFeedbackBuffers.size(); 458 case GL_UNIFORM_BUFFER: 459 return m_indexedUniformBuffers.size(); 460 case GL_ATOMIC_COUNTER_BUFFER: 461 return m_indexedAtomicCounterBuffers.size(); 462 case GL_SHADER_STORAGE_BUFFER: 463 return m_indexedShaderStorageBuffers.size(); 464 default: 465 return m_currVaoState.bufferBindings_const().size(); 466 } 467 } 468 469 int GLClientState::getBuffer(GLenum target) { 470 int ret=0; 471 switch (target) { 472 case GL_ARRAY_BUFFER: 473 ret = m_arrayBuffer; 474 break; 475 case GL_ELEMENT_ARRAY_BUFFER: 476 ret = m_currVaoState.iboId(); 477 break; 478 case GL_COPY_READ_BUFFER: 479 ret = m_copyReadBuffer; 480 break; 481 case GL_COPY_WRITE_BUFFER: 482 ret = m_copyWriteBuffer; 483 break; 484 case GL_PIXEL_PACK_BUFFER: 485 ret = m_pixelPackBuffer; 486 break; 487 case GL_PIXEL_UNPACK_BUFFER: 488 ret = m_pixelUnpackBuffer; 489 break; 490 case GL_TRANSFORM_FEEDBACK_BUFFER: 491 ret = m_transformFeedbackBuffer; 492 break; 493 case GL_UNIFORM_BUFFER: 494 ret = m_uniformBuffer; 495 break; 496 case GL_ATOMIC_COUNTER_BUFFER: 497 ret = m_atomicCounterBuffer; 498 break; 499 case GL_DISPATCH_INDIRECT_BUFFER: 500 ret = m_dispatchIndirectBuffer; 501 break; 502 case GL_DRAW_INDIRECT_BUFFER: 503 ret = m_drawIndirectBuffer; 504 break; 505 case GL_SHADER_STORAGE_BUFFER: 506 ret = m_shaderStorageBuffer; 507 break; 508 default: 509 ret = -1; 510 } 511 return ret; 512 } 513 514 void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params) 515 { 516 GLenum which_state = -1; 517 switch (pname) { 518 case GL_VERTEX_ARRAY_POINTER: { 519 which_state = GLClientState::VERTEX_LOCATION; 520 break; 521 } 522 case GL_NORMAL_ARRAY_POINTER: { 523 which_state = GLClientState::NORMAL_LOCATION; 524 break; 525 } 526 case GL_COLOR_ARRAY_POINTER: { 527 which_state = GLClientState::COLOR_LOCATION; 528 break; 529 } 530 case GL_TEXTURE_COORD_ARRAY_POINTER: { 531 which_state = getActiveTexture() + GLClientState::TEXCOORD0_LOCATION; 532 break; 533 } 534 case GL_POINT_SIZE_ARRAY_POINTER_OES: { 535 which_state = GLClientState::POINTSIZE_LOCATION; 536 break; 537 } 538 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: { 539 which_state = GLClientState::MATRIXINDEX_LOCATION; 540 break; 541 } 542 case GL_WEIGHT_ARRAY_POINTER_OES: { 543 which_state = GLClientState::WEIGHT_LOCATION; 544 break; 545 } 546 } 547 if (which_state != -1) 548 *params = getState(which_state).data; 549 } 550 551 int GLClientState::setPixelStore(GLenum param, GLint value) 552 { 553 int retval = 0; 554 switch(param) { 555 case GL_UNPACK_ALIGNMENT: 556 m_pixelStore.unpack_alignment = value; 557 break; 558 case GL_PACK_ALIGNMENT: 559 m_pixelStore.pack_alignment = value; 560 break; 561 case GL_UNPACK_ROW_LENGTH: 562 m_pixelStore.unpack_row_length = value; 563 break; 564 case GL_UNPACK_IMAGE_HEIGHT: 565 m_pixelStore.unpack_image_height = value; 566 break; 567 case GL_UNPACK_SKIP_PIXELS: 568 m_pixelStore.unpack_skip_pixels = value; 569 break; 570 case GL_UNPACK_SKIP_ROWS: 571 m_pixelStore.unpack_skip_rows = value; 572 break; 573 case GL_UNPACK_SKIP_IMAGES: 574 m_pixelStore.unpack_skip_images = value; 575 break; 576 case GL_PACK_ROW_LENGTH: 577 m_pixelStore.pack_row_length = value; 578 break; 579 case GL_PACK_SKIP_PIXELS: 580 m_pixelStore.pack_skip_pixels = value; 581 break; 582 case GL_PACK_SKIP_ROWS: 583 m_pixelStore.pack_skip_rows = value; 584 break; 585 default: 586 retval = GL_INVALID_ENUM; 587 } 588 return retval; 589 } 590 591 592 size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const 593 { 594 if (width <= 0 || height <= 0 || depth <= 0) return 0; 595 596 ALOGV("%s: pack? %d", __FUNCTION__, pack); 597 if (pack) { 598 ALOGV("%s: pack stats", __FUNCTION__); 599 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment); 600 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length); 601 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels); 602 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows); 603 } else { 604 ALOGV("%s: unpack stats", __FUNCTION__); 605 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment); 606 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length); 607 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height); 608 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels); 609 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows); 610 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images); 611 } 612 return GLESTextureUtils::computeTotalImageSize( 613 width, height, depth, 614 format, type, 615 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment, 616 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length, 617 pack ? 0 : m_pixelStore.unpack_image_height, 618 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels, 619 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows, 620 pack ? 0 : m_pixelStore.unpack_skip_images); 621 } 622 623 size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const 624 { 625 if (width <= 0 || height <= 0 || depth <= 0) return 0; 626 627 ALOGV("%s: pack? %d", __FUNCTION__, pack); 628 if (pack) { 629 ALOGV("%s: pack stats", __FUNCTION__); 630 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment); 631 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length); 632 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels); 633 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows); 634 } else { 635 ALOGV("%s: unpack stats", __FUNCTION__); 636 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment); 637 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length); 638 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height); 639 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels); 640 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows); 641 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images); 642 } 643 return GLESTextureUtils::computeNeededBufferSize( 644 width, height, depth, 645 format, type, 646 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment, 647 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length, 648 pack ? 0 : m_pixelStore.unpack_image_height, 649 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels, 650 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows, 651 pack ? 0 : m_pixelStore.unpack_skip_images); 652 } 653 654 655 size_t GLClientState::clearBufferNumElts(GLenum buffer) const 656 { 657 switch (buffer) { 658 case GL_COLOR: 659 return 4; 660 case GL_DEPTH: 661 case GL_STENCIL: 662 return 1; 663 } 664 return 1; 665 } 666 667 void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) { 668 UniformBlockInfoKey key; 669 key.program = program; 670 key.uniformBlockIndex = uniformBlockIndex; 671 672 UniformBlockUniformInfo info; 673 info.numActiveUniforms = (size_t)numActiveUniforms; 674 675 m_uniformBlockInfoMap[key] = info; 676 } 677 678 size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const { 679 UniformBlockInfoKey key; 680 key.program = program; 681 key.uniformBlockIndex = uniformBlockIndex; 682 UniformBlockInfoMap::const_iterator it = 683 m_uniformBlockInfoMap.find(key); 684 if (it == m_uniformBlockInfoMap.end()) return 0; 685 return it->second.numActiveUniforms; 686 } 687 688 void GLClientState::associateProgramWithPipeline(GLuint program, GLuint pipeline) { 689 m_programPipelines[program] = pipeline; 690 } 691 692 GLClientState::ProgramPipelineIterator GLClientState::programPipelineBegin() { 693 return m_programPipelines.begin(); 694 } 695 696 GLClientState::ProgramPipelineIterator GLClientState::programPipelineEnd() { 697 return m_programPipelines.end(); 698 } 699 700 GLenum GLClientState::setActiveTextureUnit(GLenum texture) 701 { 702 GLuint unit = texture - GL_TEXTURE0; 703 if (unit >= MAX_TEXTURE_UNITS) { 704 return GL_INVALID_ENUM; 705 } 706 m_tex.activeUnit = &m_tex.unit[unit]; 707 return GL_NO_ERROR; 708 } 709 710 GLenum GLClientState::getActiveTextureUnit() const 711 { 712 return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]); 713 } 714 715 void GLClientState::enableTextureTarget(GLenum target) 716 { 717 switch (target) { 718 case GL_TEXTURE_2D: 719 m_tex.activeUnit->enables |= (1u << TEXTURE_2D); 720 break; 721 case GL_TEXTURE_EXTERNAL_OES: 722 m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL); 723 break; 724 } 725 } 726 727 void GLClientState::disableTextureTarget(GLenum target) 728 { 729 switch (target) { 730 case GL_TEXTURE_2D: 731 m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D); 732 break; 733 case GL_TEXTURE_EXTERNAL_OES: 734 m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL); 735 break; 736 } 737 } 738 739 GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const 740 { 741 unsigned int enables = m_tex.activeUnit->enables; 742 if (enables & (1u << TEXTURE_EXTERNAL)) { 743 return GL_TEXTURE_EXTERNAL_OES; 744 } else if (enables & (1u << TEXTURE_2D)) { 745 return GL_TEXTURE_2D; 746 } else { 747 return allDisabled; 748 } 749 } 750 751 int GLClientState::compareTexId(const void* pid, const void* prec) 752 { 753 const GLuint* id = (const GLuint*)pid; 754 const TextureRec* rec = (const TextureRec*)prec; 755 return (GLint)(*id) - (GLint)rec->id; 756 } 757 758 GLenum GLClientState::bindTexture(GLenum target, GLuint texture, 759 GLboolean* firstUse) 760 { 761 GLboolean first = GL_FALSE; 762 763 TextureRec* texrec = getTextureRec(texture); 764 if (!texrec) { 765 texrec = addTextureRec(texture, target); 766 } 767 768 if (texture && target != texrec->target && 769 (target != GL_TEXTURE_EXTERNAL_OES && 770 texrec->target != GL_TEXTURE_EXTERNAL_OES)) { 771 ALOGD("%s: issue GL_INVALID_OPERATION: target 0x%x texrectarget 0x%x texture %u", __FUNCTION__, target, texrec->target, texture); 772 } 773 774 switch (target) { 775 case GL_TEXTURE_2D: 776 m_tex.activeUnit->texture[TEXTURE_2D] = texture; 777 break; 778 case GL_TEXTURE_EXTERNAL_OES: 779 m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture; 780 break; 781 case GL_TEXTURE_CUBE_MAP: 782 m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture; 783 break; 784 case GL_TEXTURE_2D_ARRAY: 785 m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture; 786 break; 787 case GL_TEXTURE_3D: 788 m_tex.activeUnit->texture[TEXTURE_3D] = texture; 789 break; 790 case GL_TEXTURE_2D_MULTISAMPLE: 791 m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture; 792 break; 793 } 794 795 if (firstUse) { 796 *firstUse = first; 797 } 798 799 return GL_NO_ERROR; 800 } 801 802 void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) { 803 GLuint texture = getBoundTexture(target); 804 TextureRec* texrec = getTextureRec(texture); 805 if (!texrec) return; 806 texrec->boundEGLImage = true; 807 } 808 809 TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target) 810 { 811 TextureRec* tex = new TextureRec; 812 tex->id = id; 813 tex->target = target; 814 tex->format = -1; 815 tex->multisamples = 0; 816 tex->immutable = false; 817 tex->boundEGLImage = false; 818 tex->dims = new TextureDims; 819 820 (*(m_tex.textureRecs))[id] = tex; 821 return tex; 822 } 823 824 TextureRec* GLClientState::getTextureRec(GLuint id) const { 825 SharedTextureDataMap::const_iterator it = 826 m_tex.textureRecs->find(id); 827 if (it == m_tex.textureRecs->end()) { 828 return NULL; 829 } 830 return it->second; 831 } 832 833 void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) { 834 GLuint texture = getBoundTexture(target); 835 TextureRec* texrec = getTextureRec(texture); 836 if (!texrec) return; 837 texrec->internalformat = internalformat; 838 } 839 840 void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) { 841 GLuint texture = getBoundTexture(target); 842 TextureRec* texrec = getTextureRec(texture); 843 if (!texrec) return; 844 texrec->format = format; 845 } 846 847 void GLClientState::setBoundTextureType(GLenum target, GLenum type) { 848 GLuint texture = getBoundTexture(target); 849 TextureRec* texrec = getTextureRec(texture); 850 if (!texrec) return; 851 texrec->type = type; 852 } 853 854 void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) { 855 GLuint texture = getBoundTexture(target); 856 TextureRec* texrec = getTextureRec(texture); 857 if (!texrec) { 858 return; 859 } 860 861 if (level == -1) { 862 GLsizei curr_width = width; 863 GLsizei curr_height = height; 864 GLsizei curr_depth = depth; 865 GLsizei curr_level = 0; 866 867 while (true) { 868 texrec->dims->widths[curr_level] = curr_width; 869 texrec->dims->heights[curr_level] = curr_height; 870 texrec->dims->depths[curr_level] = curr_depth; 871 if (curr_width >> 1 == 0 && 872 curr_height >> 1 == 0 && 873 ((target == GL_TEXTURE_3D && curr_depth == 0) || 874 true)) { 875 break; 876 } 877 curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1; 878 curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1; 879 if (target == GL_TEXTURE_3D) { 880 curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1; 881 } 882 curr_level++; 883 } 884 885 } else { 886 texrec->dims->widths[level] = width; 887 texrec->dims->heights[level] = height; 888 texrec->dims->depths[level] = depth; 889 } 890 } 891 892 void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) { 893 GLuint texture = getBoundTexture(target); 894 TextureRec* texrec = getTextureRec(texture); 895 if (!texrec) return; 896 texrec->multisamples = samples; 897 } 898 899 void GLClientState::setBoundTextureImmutableFormat(GLenum target) { 900 GLuint texture = getBoundTexture(target); 901 TextureRec* texrec = getTextureRec(texture); 902 if (!texrec) return; 903 texrec->immutable = true; 904 } 905 906 bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const { 907 GLuint texture = getBoundTexture(target); 908 TextureRec* texrec = getTextureRec(texture); 909 if (!texrec) return false; 910 return texrec->immutable; 911 } 912 913 GLuint GLClientState::getBoundTexture(GLenum target) const 914 { 915 switch (target) { 916 case GL_TEXTURE_2D: 917 return m_tex.activeUnit->texture[TEXTURE_2D]; 918 case GL_TEXTURE_EXTERNAL_OES: 919 return m_tex.activeUnit->texture[TEXTURE_EXTERNAL]; 920 case GL_TEXTURE_CUBE_MAP: 921 return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP]; 922 case GL_TEXTURE_2D_ARRAY: 923 return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY]; 924 case GL_TEXTURE_3D: 925 return m_tex.activeUnit->texture[TEXTURE_3D]; 926 case GL_TEXTURE_2D_MULTISAMPLE: 927 return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE]; 928 default: 929 return 0; 930 } 931 } 932 933 // BEGIN driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- 934 // (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')> 935 936 static bool unreliableInternalFormat(GLenum internalformat) { 937 switch (internalformat) { 938 case GL_LUMINANCE: 939 return true; 940 default: 941 return false; 942 } 943 } 944 945 void GLClientState::writeCopyTexImageState 946 (GLenum target, GLint level, GLenum internalformat) { 947 if (unreliableInternalFormat(internalformat)) { 948 CubeMapDef entry; 949 entry.id = getBoundTexture(GL_TEXTURE_2D); 950 entry.target = target; 951 entry.level = level; 952 entry.internalformat = internalformat; 953 m_cubeMapDefs.insert(entry); 954 } 955 } 956 957 static GLenum identifyPositiveCubeMapComponent(GLenum target) { 958 switch (target) { 959 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 960 return GL_TEXTURE_CUBE_MAP_POSITIVE_X; 961 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 962 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y; 963 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 964 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z; 965 default: 966 return 0; 967 } 968 } 969 970 GLenum GLClientState::copyTexImageNeededTarget 971 (GLenum target, GLint level, GLenum internalformat) { 972 if (unreliableInternalFormat(internalformat)) { 973 GLenum positiveComponent = 974 identifyPositiveCubeMapComponent(target); 975 if (positiveComponent) { 976 CubeMapDef query; 977 query.id = getBoundTexture(GL_TEXTURE_2D); 978 query.target = positiveComponent; 979 query.level = level; 980 query.internalformat = internalformat; 981 if (m_cubeMapDefs.find(query) == 982 m_cubeMapDefs.end()) { 983 return positiveComponent; 984 } 985 } 986 } 987 return 0; 988 } 989 990 GLenum GLClientState::copyTexImageLuminanceCubeMapAMDWorkaround 991 (GLenum target, GLint level, GLenum internalformat) { 992 writeCopyTexImageState(target, level, internalformat); 993 return copyTexImageNeededTarget(target, level, internalformat); 994 } 995 996 // (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')> 997 // END driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- 998 999 void GLClientState::deleteTextures(GLsizei n, const GLuint* textures) 1000 { 1001 // Updating the textures array could be made more efficient when deleting 1002 // several textures: 1003 // - compacting the array could be done in a single pass once the deleted 1004 // textures are marked, or 1005 // - could swap deleted textures to the end and re-sort. 1006 TextureRec* texrec; 1007 for (const GLuint* texture = textures; texture != textures + n; texture++) { 1008 texrec = getTextureRec(*texture); 1009 if (texrec && texrec->dims) { 1010 delete texrec->dims; 1011 } 1012 if (texrec) { 1013 m_tex.textureRecs->erase(*texture); 1014 delete texrec; 1015 for (TextureUnit* unit = m_tex.unit; 1016 unit != m_tex.unit + MAX_TEXTURE_UNITS; 1017 unit++) 1018 { 1019 if (unit->texture[TEXTURE_2D] == *texture) { 1020 unit->texture[TEXTURE_2D] = 0; 1021 } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) { 1022 unit->texture[TEXTURE_EXTERNAL] = 0; 1023 } 1024 } 1025 } 1026 } 1027 } 1028 1029 // RBO////////////////////////////////////////////////////////////////////////// 1030 1031 void GLClientState::addFreshRenderbuffer(GLuint name) { 1032 // if underlying opengl says these are fresh names, 1033 // but we are keeping a stale one, reset it. 1034 RboProps props; 1035 props.target = GL_RENDERBUFFER; 1036 props.name = name; 1037 props.format = GL_NONE; 1038 props.multisamples = 0; 1039 props.previouslyBound = false; 1040 1041 if (usedRenderbufferName(name)) { 1042 mRboState.rboData[getRboIndex(name)] = props; 1043 } else { 1044 mRboState.rboData.push_back(props); 1045 } 1046 } 1047 1048 void GLClientState::addRenderbuffers(GLsizei n, GLuint* renderbuffers) { 1049 for (size_t i = 0; i < n; i++) { 1050 addFreshRenderbuffer(renderbuffers[i]); 1051 } 1052 } 1053 1054 size_t GLClientState::getRboIndex(GLuint name) const { 1055 for (size_t i = 0; i < mRboState.rboData.size(); i++) { 1056 if (mRboState.rboData[i].name == name) { 1057 return i; 1058 } 1059 } 1060 return -1; 1061 } 1062 1063 void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) { 1064 size_t bound_rbo_idx = getRboIndex(boundRboProps_const().name); 1065 1066 std::vector<GLuint> to_remove; 1067 for (size_t i = 0; i < n; i++) { 1068 if (renderbuffers[i] != 0) { // Never remove the zero rb. 1069 to_remove.push_back(getRboIndex(renderbuffers[i])); 1070 } 1071 } 1072 1073 for (size_t i = 0; i < to_remove.size(); i++) { 1074 mRboState.rboData[to_remove[i]] = mRboState.rboData.back(); 1075 mRboState.rboData.pop_back(); 1076 } 1077 1078 // If we just deleted the currently bound rb, 1079 // bind the zero rb 1080 if (getRboIndex(boundRboProps_const().name) != bound_rbo_idx) { 1081 bindRenderbuffer(GL_RENDERBUFFER, 0); 1082 } 1083 } 1084 1085 bool GLClientState::usedRenderbufferName(GLuint name) const { 1086 for (size_t i = 0; i < mRboState.rboData.size(); i++) { 1087 if (mRboState.rboData[i].name == name) { 1088 return true; 1089 } 1090 } 1091 return false; 1092 } 1093 1094 void GLClientState::setBoundRenderbufferIndex() { 1095 for (size_t i = 0; i < mRboState.rboData.size(); i++) { 1096 if (mRboState.rboData[i].name == mRboState.boundRenderbuffer) { 1097 mRboState.boundRenderbufferIndex = i; 1098 break; 1099 } 1100 } 1101 } 1102 1103 RboProps& GLClientState::boundRboProps() { 1104 return mRboState.rboData[mRboState.boundRenderbufferIndex]; 1105 } 1106 1107 const RboProps& GLClientState::boundRboProps_const() const { 1108 return mRboState.rboData[mRboState.boundRenderbufferIndex]; 1109 } 1110 1111 void GLClientState::bindRenderbuffer(GLenum target, GLuint name) { 1112 // If unused, add it. 1113 if (!usedRenderbufferName(name)) { 1114 addFreshRenderbuffer(name); 1115 } 1116 mRboState.boundRenderbuffer = name; 1117 setBoundRenderbufferIndex(); 1118 boundRboProps().target = target; 1119 boundRboProps().previouslyBound = true; 1120 } 1121 1122 GLuint GLClientState::boundRenderbuffer() const { 1123 return boundRboProps_const().name; 1124 } 1125 1126 void GLClientState::setBoundRenderbufferFormat(GLenum format) { 1127 boundRboProps().format = format; 1128 } 1129 1130 void GLClientState::setBoundRenderbufferSamples(GLsizei samples) { 1131 boundRboProps().multisamples = samples; 1132 } 1133 1134 // FBO////////////////////////////////////////////////////////////////////////// 1135 1136 // Format querying 1137 1138 GLenum GLClientState::queryRboFormat(GLuint rbo_name) const { 1139 return mRboState.rboData[getRboIndex(rbo_name)].format; 1140 } 1141 1142 GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const { 1143 return mRboState.rboData[getRboIndex(rbo_name)].multisamples; 1144 } 1145 1146 GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const { 1147 TextureRec* texrec = getTextureRec(tex_name); 1148 if (!texrec) return -1; 1149 return texrec->internalformat; 1150 } 1151 1152 GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const { 1153 TextureRec* texrec = getTextureRec(tex_name); 1154 if (!texrec) { 1155 return 0; 1156 } 1157 return texrec->dims->widths[level]; 1158 } 1159 1160 GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const { 1161 TextureRec* texrec = getTextureRec(tex_name); 1162 if (!texrec) return 0; 1163 return texrec->dims->heights[level]; 1164 } 1165 1166 GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const { 1167 TextureRec* texrec = getTextureRec(tex_name); 1168 if (!texrec) return 0; 1169 return texrec->dims->depths[level]; 1170 } 1171 1172 bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const { 1173 TextureRec* texrec = getTextureRec(tex_name); 1174 if (!texrec) return false; 1175 return texrec->boundEGLImage; 1176 } 1177 1178 GLenum GLClientState::queryTexFormat(GLuint tex_name) const { 1179 TextureRec* texrec = getTextureRec(tex_name); 1180 if (!texrec) return -1; 1181 return texrec->format; 1182 } 1183 1184 GLenum GLClientState::queryTexType(GLuint tex_name) const { 1185 TextureRec* texrec = getTextureRec(tex_name); 1186 if (!texrec) return -1; 1187 return texrec->type; 1188 } 1189 1190 GLsizei GLClientState::queryTexSamples(GLuint tex_name) const { 1191 TextureRec* texrec = getTextureRec(tex_name); 1192 if (!texrec) return 0; 1193 return texrec->multisamples; 1194 } 1195 1196 GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const { 1197 TextureRec* texrec = getTextureRec(tex_name); 1198 if (!texrec) return GL_NONE; 1199 return texrec->target; 1200 } 1201 1202 void GLClientState::getBoundFramebufferFormat( 1203 GLenum target, 1204 GLenum attachment, FboFormatInfo* res_info) const { 1205 const FboProps& props = boundFboProps_const(target); 1206 1207 res_info->type = FBO_ATTACHMENT_NONE; 1208 res_info->rb_format = GL_NONE; 1209 res_info->rb_multisamples = 0; 1210 res_info->tex_internalformat = -1; 1211 res_info->tex_format = GL_NONE; 1212 res_info->tex_type = GL_NONE; 1213 res_info->tex_multisamples = 0; 1214 1215 int colorAttachmentIndex = 1216 glUtilsColorAttachmentIndex(attachment); 1217 1218 if (colorAttachmentIndex != -1) { 1219 if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) { 1220 res_info->type = FBO_ATTACHMENT_RENDERBUFFER; 1221 res_info->rb_format = 1222 queryRboFormat( 1223 props.colorAttachmenti_rbos[colorAttachmentIndex]); 1224 res_info->rb_multisamples = 1225 queryRboSamples( 1226 props.colorAttachmenti_rbos[colorAttachmentIndex]); 1227 } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) { 1228 res_info->type = FBO_ATTACHMENT_TEXTURE; 1229 res_info->tex_internalformat = 1230 queryTexInternalFormat( 1231 props.colorAttachmenti_textures[colorAttachmentIndex]); 1232 res_info->tex_format = 1233 queryTexFormat( 1234 props.colorAttachmenti_textures[colorAttachmentIndex]); 1235 res_info->tex_type = 1236 queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]); 1237 res_info->tex_multisamples = 1238 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]); 1239 } else { 1240 res_info->type = FBO_ATTACHMENT_NONE; 1241 } 1242 } 1243 1244 switch (attachment) { 1245 case GL_DEPTH_ATTACHMENT: 1246 if (props.depthAttachment_hasRbo) { 1247 res_info->type = FBO_ATTACHMENT_RENDERBUFFER; 1248 res_info->rb_format = queryRboFormat(props.depthAttachment_rbo); 1249 res_info->rb_multisamples = 1250 queryRboSamples( 1251 props.colorAttachmenti_rbos[colorAttachmentIndex]); 1252 } else if (props.depthAttachment_hasTexObj) { 1253 res_info->type = FBO_ATTACHMENT_TEXTURE; 1254 res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture); 1255 res_info->tex_format = queryTexFormat(props.depthAttachment_texture); 1256 res_info->tex_type = queryTexType(props.depthAttachment_texture); 1257 res_info->tex_multisamples = 1258 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]); 1259 } else { 1260 res_info->type = FBO_ATTACHMENT_NONE; 1261 } 1262 break; 1263 case GL_STENCIL_ATTACHMENT: 1264 if (props.stencilAttachment_hasRbo) { 1265 res_info->type = FBO_ATTACHMENT_RENDERBUFFER; 1266 res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo); 1267 res_info->rb_multisamples = 1268 queryRboSamples( 1269 props.colorAttachmenti_rbos[colorAttachmentIndex]); 1270 } else if (props.stencilAttachment_hasTexObj) { 1271 res_info->type = FBO_ATTACHMENT_TEXTURE; 1272 res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture); 1273 res_info->tex_format = queryTexFormat(props.stencilAttachment_texture); 1274 res_info->tex_type = queryTexType(props.stencilAttachment_texture); 1275 res_info->tex_multisamples = 1276 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]); 1277 } else { 1278 res_info->type = FBO_ATTACHMENT_NONE; 1279 } 1280 break; 1281 case GL_DEPTH_STENCIL_ATTACHMENT: 1282 if (props.depthstencilAttachment_hasRbo) { 1283 res_info->type = FBO_ATTACHMENT_RENDERBUFFER; 1284 res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo); 1285 res_info->rb_multisamples = 1286 queryRboSamples( 1287 props.colorAttachmenti_rbos[colorAttachmentIndex]); 1288 } else if (props.depthstencilAttachment_hasTexObj) { 1289 res_info->type = FBO_ATTACHMENT_TEXTURE; 1290 res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture); 1291 res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture); 1292 res_info->tex_type = queryTexType(props.depthstencilAttachment_texture); 1293 res_info->tex_multisamples = 1294 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]); 1295 } else { 1296 res_info->type = FBO_ATTACHMENT_NONE; 1297 } 1298 break; 1299 } 1300 } 1301 1302 FboAttachmentType GLClientState::getBoundFramebufferAttachmentType(GLenum target, GLenum attachment) const { 1303 FboFormatInfo info; 1304 getBoundFramebufferFormat(target, attachment, &info); 1305 return info.type; 1306 } 1307 1308 1309 int GLClientState::getMaxColorAttachments() const { 1310 return m_max_color_attachments; 1311 } 1312 1313 int GLClientState::getMaxDrawBuffers() const { 1314 return m_max_draw_buffers; 1315 } 1316 1317 void GLClientState::addFreshFramebuffer(GLuint name) { 1318 FboProps props; 1319 props.name = name; 1320 props.previouslyBound = false; 1321 1322 props.colorAttachmenti_textures.resize(m_max_color_attachments, 0); 1323 props.depthAttachment_texture = 0; 1324 props.stencilAttachment_texture = 0; 1325 props.depthstencilAttachment_texture = 0; 1326 1327 props.colorAttachmenti_hasTex.resize(m_max_color_attachments, false); 1328 props.depthAttachment_hasTexObj = false; 1329 props.stencilAttachment_hasTexObj = false; 1330 props.depthstencilAttachment_hasTexObj = false; 1331 1332 props.colorAttachmenti_rbos.resize(m_max_color_attachments, 0); 1333 props.depthAttachment_rbo = 0; 1334 props.stencilAttachment_rbo = 0; 1335 props.depthstencilAttachment_rbo = 0; 1336 1337 props.colorAttachmenti_hasRbo.resize(m_max_color_attachments, false); 1338 props.depthAttachment_hasRbo = false; 1339 props.stencilAttachment_hasRbo = false; 1340 props.depthstencilAttachment_hasRbo = false; 1341 mFboState.fboData[name] = props; 1342 } 1343 1344 void GLClientState::addFramebuffers(GLsizei n, GLuint* framebuffers) { 1345 for (size_t i = 0; i < n; i++) { 1346 addFreshFramebuffer(framebuffers[i]); 1347 } 1348 } 1349 1350 void GLClientState::removeFramebuffers(GLsizei n, const GLuint* framebuffers) { 1351 for (size_t i = 0; i < n; i++) { 1352 if (framebuffers[i] != 0) { // Never remove the zero fb. 1353 if (framebuffers[i] == mFboState.boundDrawFramebuffer) { 1354 bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 1355 } 1356 if (framebuffers[i] == mFboState.boundReadFramebuffer) { 1357 bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 1358 } 1359 mFboState.fboData.erase(framebuffers[i]); 1360 } 1361 } 1362 } 1363 1364 bool GLClientState::usedFramebufferName(GLuint name) const { 1365 return mFboState.fboData.find(name) != mFboState.fboData.end(); 1366 } 1367 1368 FboProps& GLClientState::boundFboProps(GLenum target) { 1369 switch (target) { 1370 case GL_DRAW_FRAMEBUFFER: 1371 return mFboState.fboData[mFboState.boundDrawFramebuffer]; 1372 case GL_READ_FRAMEBUFFER: 1373 return mFboState.fboData[mFboState.boundReadFramebuffer]; 1374 case GL_FRAMEBUFFER: 1375 return mFboState.fboData[mFboState.boundDrawFramebuffer]; 1376 } 1377 return mFboState.fboData[mFboState.boundDrawFramebuffer]; 1378 } 1379 1380 const FboProps& GLClientState::boundFboProps_const(GLenum target) const { 1381 switch (target) { 1382 case GL_DRAW_FRAMEBUFFER: 1383 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second; 1384 case GL_READ_FRAMEBUFFER: 1385 return mFboState.fboData.find(mFboState.boundReadFramebuffer)->second; 1386 case GL_FRAMEBUFFER: 1387 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second; 1388 } 1389 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second; 1390 } 1391 1392 void GLClientState::bindFramebuffer(GLenum target, GLuint name) { 1393 // If unused, add it. 1394 if (!usedFramebufferName(name)) { 1395 addFreshFramebuffer(name); 1396 } 1397 switch (target) { 1398 case GL_DRAW_FRAMEBUFFER: 1399 mFboState.boundDrawFramebuffer = name; 1400 break; 1401 case GL_READ_FRAMEBUFFER: 1402 mFboState.boundReadFramebuffer = name; 1403 break; 1404 default: // case GL_FRAMEBUFFER: 1405 mFboState.boundDrawFramebuffer = name; 1406 mFboState.boundReadFramebuffer = name; 1407 break; 1408 } 1409 boundFboProps(target).previouslyBound = true; 1410 } 1411 1412 void GLClientState::setCheckFramebufferStatus(GLenum target, GLenum status) { 1413 switch (target) { 1414 case GL_DRAW_FRAMEBUFFER: 1415 mFboState.drawFboCheckStatus = status; 1416 break; 1417 case GL_READ_FRAMEBUFFER: 1418 mFboState.readFboCheckStatus = status; 1419 break; 1420 case GL_FRAMEBUFFER: 1421 mFboState.drawFboCheckStatus = status; 1422 break; 1423 } 1424 } 1425 1426 GLenum GLClientState::getCheckFramebufferStatus(GLenum target) const { 1427 switch (target) { 1428 case GL_DRAW_FRAMEBUFFER: 1429 return mFboState.drawFboCheckStatus; 1430 case GL_READ_FRAMEBUFFER: 1431 return mFboState.readFboCheckStatus; 1432 case GL_FRAMEBUFFER: 1433 return mFboState.drawFboCheckStatus; 1434 } 1435 return mFboState.drawFboCheckStatus; 1436 } 1437 1438 GLuint GLClientState::boundFramebuffer(GLenum target) const { 1439 return boundFboProps_const(target).name; 1440 } 1441 1442 // Texture objects for FBOs///////////////////////////////////////////////////// 1443 1444 void GLClientState::attachTextureObject( 1445 GLenum target, 1446 GLenum attachment, GLuint texture) { 1447 1448 int colorAttachmentIndex = 1449 glUtilsColorAttachmentIndex(attachment); 1450 1451 if (colorAttachmentIndex != -1) { 1452 boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture; 1453 boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = true; 1454 } 1455 1456 switch (attachment) { 1457 case GL_DEPTH_ATTACHMENT: 1458 boundFboProps(target).depthAttachment_texture = texture; 1459 boundFboProps(target).depthAttachment_hasTexObj = true; 1460 break; 1461 case GL_STENCIL_ATTACHMENT: 1462 boundFboProps(target).stencilAttachment_texture = texture; 1463 boundFboProps(target).stencilAttachment_hasTexObj = true; 1464 break; 1465 case GL_DEPTH_STENCIL_ATTACHMENT: 1466 boundFboProps(target).depthstencilAttachment_texture = texture; 1467 boundFboProps(target).depthstencilAttachment_hasTexObj = true; 1468 boundFboProps(target).stencilAttachment_texture = texture; 1469 boundFboProps(target).stencilAttachment_hasTexObj = true; 1470 boundFboProps(target).depthAttachment_texture = texture; 1471 boundFboProps(target).depthAttachment_hasTexObj = true; 1472 break; 1473 } 1474 } 1475 1476 GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const { 1477 GLuint res = 0; // conservative 1478 1479 int colorAttachmentIndex = 1480 glUtilsColorAttachmentIndex(attachment); 1481 1482 if (colorAttachmentIndex != -1) { 1483 res = boundFboProps_const(target).colorAttachmenti_textures[colorAttachmentIndex]; 1484 } 1485 1486 switch (attachment) { 1487 case GL_DEPTH_ATTACHMENT: 1488 res = boundFboProps_const(target).depthAttachment_texture; 1489 break; 1490 case GL_STENCIL_ATTACHMENT: 1491 res = boundFboProps_const(target).stencilAttachment_texture; 1492 break; 1493 case GL_DEPTH_STENCIL_ATTACHMENT: 1494 res = boundFboProps_const(target).depthstencilAttachment_texture; 1495 break; 1496 } 1497 return res; 1498 } 1499 1500 // RBOs for FBOs//////////////////////////////////////////////////////////////// 1501 1502 void GLClientState::detachRbo(GLuint renderbuffer) { 1503 for (int i = 0; i < m_max_color_attachments; i++) { 1504 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer); 1505 detachRboFromFbo(GL_READ_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer); 1506 } 1507 1508 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer); 1509 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer); 1510 1511 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer); 1512 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer); 1513 1514 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer); 1515 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer); 1516 } 1517 1518 void GLClientState::detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer) { 1519 int colorAttachmentIndex = 1520 glUtilsColorAttachmentIndex(attachment); 1521 1522 if (colorAttachmentIndex != -1) { 1523 if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] && 1524 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) { 1525 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0; 1526 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false; 1527 } 1528 } 1529 1530 switch (attachment) { 1531 case GL_DEPTH_ATTACHMENT: 1532 if (boundFboProps(target).depthAttachment_rbo == renderbuffer && 1533 boundFboProps(target).depthAttachment_hasRbo) { 1534 boundFboProps(target).depthAttachment_rbo = 0; 1535 boundFboProps(target).depthAttachment_hasRbo = false; 1536 } 1537 break; 1538 case GL_STENCIL_ATTACHMENT: 1539 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer && 1540 boundFboProps(target).stencilAttachment_hasRbo) { 1541 boundFboProps(target).stencilAttachment_rbo = 0; 1542 boundFboProps(target).stencilAttachment_hasRbo = false; 1543 } 1544 break; 1545 case GL_DEPTH_STENCIL_ATTACHMENT: 1546 if (boundFboProps(target).depthAttachment_rbo == renderbuffer && 1547 boundFboProps(target).depthAttachment_hasRbo) { 1548 boundFboProps(target).depthAttachment_rbo = 0; 1549 boundFboProps(target).depthAttachment_hasRbo = false; 1550 } 1551 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer && 1552 boundFboProps(target).stencilAttachment_hasRbo) { 1553 boundFboProps(target).stencilAttachment_rbo = 0; 1554 boundFboProps(target).stencilAttachment_hasRbo = false; 1555 } 1556 if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer && 1557 boundFboProps(target).depthstencilAttachment_hasRbo) { 1558 boundFboProps(target).depthstencilAttachment_rbo = 0; 1559 boundFboProps(target).depthstencilAttachment_hasRbo = false; 1560 } 1561 break; 1562 } 1563 } 1564 1565 void GLClientState::attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer) { 1566 1567 int colorAttachmentIndex = 1568 glUtilsColorAttachmentIndex(attachment); 1569 1570 if (colorAttachmentIndex != -1) { 1571 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer; 1572 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = true; 1573 } 1574 1575 switch (attachment) { 1576 case GL_DEPTH_ATTACHMENT: 1577 boundFboProps(target).depthAttachment_rbo = renderbuffer; 1578 boundFboProps(target).depthAttachment_hasRbo = true; 1579 break; 1580 case GL_STENCIL_ATTACHMENT: 1581 boundFboProps(target).stencilAttachment_rbo = renderbuffer; 1582 boundFboProps(target).stencilAttachment_hasRbo = true; 1583 break; 1584 case GL_DEPTH_STENCIL_ATTACHMENT: 1585 boundFboProps(target).depthAttachment_rbo = renderbuffer; 1586 boundFboProps(target).depthAttachment_hasRbo = true; 1587 boundFboProps(target).stencilAttachment_rbo = renderbuffer; 1588 boundFboProps(target).stencilAttachment_hasRbo = true; 1589 boundFboProps(target).depthstencilAttachment_rbo = renderbuffer; 1590 boundFboProps(target).depthstencilAttachment_hasRbo = true; 1591 break; 1592 } 1593 } 1594 1595 GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const { 1596 GLuint res = 0; // conservative 1597 1598 int colorAttachmentIndex = 1599 glUtilsColorAttachmentIndex(attachment); 1600 1601 if (colorAttachmentIndex != -1) { 1602 res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex]; 1603 } 1604 1605 switch (attachment) { 1606 case GL_DEPTH_ATTACHMENT: 1607 res = boundFboProps_const(target).depthAttachment_rbo; 1608 break; 1609 case GL_STENCIL_ATTACHMENT: 1610 res = boundFboProps_const(target).stencilAttachment_rbo; 1611 break; 1612 case GL_DEPTH_STENCIL_ATTACHMENT: 1613 res = boundFboProps_const(target).depthstencilAttachment_rbo; 1614 break; 1615 } 1616 return res; 1617 } 1618 1619 bool GLClientState::attachmentHasObject(GLenum target, GLenum attachment) const { 1620 bool res = true; // liberal 1621 1622 int colorAttachmentIndex = 1623 glUtilsColorAttachmentIndex(attachment); 1624 1625 if (colorAttachmentIndex != -1) { 1626 res = boundFboProps_const(target).colorAttachmenti_hasTex[colorAttachmentIndex] || 1627 boundFboProps_const(target).colorAttachmenti_hasRbo[colorAttachmentIndex]; 1628 } 1629 1630 switch (attachment) { 1631 case GL_DEPTH_ATTACHMENT: 1632 res = (boundFboProps_const(target).depthAttachment_hasTexObj) || 1633 (boundFboProps_const(target).depthAttachment_hasRbo); 1634 break; 1635 case GL_STENCIL_ATTACHMENT: 1636 res = (boundFboProps_const(target).stencilAttachment_hasTexObj) || 1637 (boundFboProps_const(target).stencilAttachment_hasRbo); 1638 break; 1639 case GL_DEPTH_STENCIL_ATTACHMENT: 1640 res = (boundFboProps_const(target).depthstencilAttachment_hasTexObj) || 1641 (boundFboProps_const(target).depthstencilAttachment_hasRbo); 1642 break; 1643 } 1644 return res; 1645 } 1646 1647 GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const { 1648 const FboProps& props = boundFboProps_const(target); 1649 1650 int colorAttachmentIndex = 1651 glUtilsColorAttachmentIndex(attachment); 1652 1653 if (colorAttachmentIndex != -1) { 1654 if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) { 1655 return props.colorAttachmenti_textures[colorAttachmentIndex]; 1656 } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) { 1657 return props.colorAttachmenti_rbos[colorAttachmentIndex]; 1658 } else { 1659 return 0; 1660 } 1661 } 1662 1663 switch (attachment) { 1664 case GL_DEPTH_ATTACHMENT: 1665 if (props.depthAttachment_hasTexObj) { 1666 return props.depthAttachment_texture; 1667 } else if (props.depthAttachment_hasRbo) { 1668 return props.depthAttachment_rbo; 1669 } else { 1670 return 0; 1671 } 1672 break; 1673 case GL_STENCIL_ATTACHMENT: 1674 if (props.stencilAttachment_hasTexObj) { 1675 return props.stencilAttachment_texture; 1676 } else if (props.stencilAttachment_hasRbo) { 1677 return props.stencilAttachment_rbo; 1678 } else { 1679 return 0; 1680 } 1681 case GL_DEPTH_STENCIL_ATTACHMENT: 1682 if (props.depthstencilAttachment_hasTexObj) { 1683 return props.depthstencilAttachment_texture; 1684 } else if (props.depthstencilAttachment_hasRbo) { 1685 return props.depthstencilAttachment_rbo; 1686 } else { 1687 return 0; 1688 } 1689 break; 1690 } 1691 return 0; 1692 } 1693 1694 void GLClientState::setTransformFeedbackActiveUnpaused(bool activeUnpaused) { 1695 m_transformFeedbackActiveUnpaused = activeUnpaused; 1696 } 1697 1698 bool GLClientState::getTransformFeedbackActiveUnpaused() const { 1699 return m_transformFeedbackActiveUnpaused; 1700 } 1701 1702 void GLClientState::setTextureData(SharedTextureDataMap* sharedTexData) { 1703 m_tex.textureRecs = sharedTexData; 1704 } 1705 1706 void GLClientState::fromMakeCurrent() { 1707 if (mFboState.fboData.find(0) == mFboState.fboData.end()) { 1708 addFreshFramebuffer(0); 1709 } 1710 FboProps& default_fb_props = mFboState.fboData[0]; 1711 default_fb_props.colorAttachmenti_hasRbo[0] = true; 1712 default_fb_props.depthAttachment_hasRbo = true; 1713 default_fb_props.stencilAttachment_hasRbo = true; 1714 default_fb_props.depthstencilAttachment_hasRbo = true; 1715 } 1716 1717 void GLClientState::initFromCaps( 1718 int max_transform_feedback_separate_attribs, 1719 int max_uniform_buffer_bindings, 1720 int max_atomic_counter_buffer_bindings, 1721 int max_shader_storage_buffer_bindings, 1722 int max_vertex_attrib_bindings, 1723 int max_color_attachments, 1724 int max_draw_buffers) { 1725 1726 m_max_vertex_attrib_bindings = max_vertex_attrib_bindings; 1727 1728 if (m_glesMajorVersion >= 3) { 1729 m_max_transform_feedback_separate_attribs = max_transform_feedback_separate_attribs; 1730 m_max_uniform_buffer_bindings = max_uniform_buffer_bindings; 1731 m_max_atomic_counter_buffer_bindings = max_atomic_counter_buffer_bindings; 1732 m_max_shader_storage_buffer_bindings = max_shader_storage_buffer_bindings; 1733 1734 if (m_max_transform_feedback_separate_attribs) 1735 m_indexedTransformFeedbackBuffers.resize(m_max_transform_feedback_separate_attribs); 1736 if (m_max_uniform_buffer_bindings) 1737 m_indexedUniformBuffers.resize(m_max_uniform_buffer_bindings); 1738 if (m_max_atomic_counter_buffer_bindings) 1739 m_indexedAtomicCounterBuffers.resize(m_max_atomic_counter_buffer_bindings); 1740 if (m_max_shader_storage_buffer_bindings) 1741 m_indexedShaderStorageBuffers.resize(m_max_shader_storage_buffer_bindings); 1742 1743 BufferBinding buf0Binding; 1744 buf0Binding.buffer = 0; 1745 buf0Binding.offset = 0; 1746 buf0Binding.size = 0; 1747 buf0Binding.stride = 0; 1748 buf0Binding.effectiveStride = 0; 1749 1750 for (size_t i = 0; i < m_indexedTransformFeedbackBuffers.size(); ++i) 1751 m_indexedTransformFeedbackBuffers[i] = buf0Binding; 1752 for (size_t i = 0; i < m_indexedUniformBuffers.size(); ++i) 1753 m_indexedUniformBuffers[i] = buf0Binding; 1754 for (size_t i = 0; i < m_indexedAtomicCounterBuffers.size(); ++i) 1755 m_indexedAtomicCounterBuffers[i] = buf0Binding; 1756 for (size_t i = 0; i < m_indexedShaderStorageBuffers.size(); ++i) 1757 m_indexedShaderStorageBuffers[i] = buf0Binding; 1758 } 1759 1760 m_max_color_attachments = max_color_attachments; 1761 m_max_draw_buffers = max_draw_buffers; 1762 1763 addFreshRenderbuffer(0); 1764 addFreshFramebuffer(0); 1765 1766 m_initialized = true; 1767 } 1768 1769 bool GLClientState::needsInitFromCaps() const { 1770 return !m_initialized; 1771 } 1772