1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/test/test_web_graphics_context_3d.h" 6 7 #include <algorithm> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/lazy_instance.h" 12 #include "base/logging.h" 13 #include "base/message_loop/message_loop.h" 14 #include "cc/test/test_context_support.h" 15 #include "gpu/GLES2/gl2extchromium.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "third_party/khronos/GLES2/gl2ext.h" 18 19 namespace cc { 20 21 static const GLuint kFramebufferId = 1; 22 static const GLuint kRenderbufferId = 2; 23 24 static unsigned s_context_id = 1; 25 26 const GLuint TestWebGraphicsContext3D::kExternalTextureId = 1337; 27 28 static base::LazyInstance<base::Lock>::Leaky 29 g_shared_namespace_lock = LAZY_INSTANCE_INITIALIZER; 30 31 TestWebGraphicsContext3D::Namespace* 32 TestWebGraphicsContext3D::shared_namespace_ = NULL; 33 34 TestWebGraphicsContext3D::Namespace::Namespace() 35 : next_buffer_id(1), 36 next_image_id(1), 37 next_texture_id(1) { 38 } 39 40 TestWebGraphicsContext3D::Namespace::~Namespace() { 41 g_shared_namespace_lock.Get().AssertAcquired(); 42 if (shared_namespace_ == this) 43 shared_namespace_ = NULL; 44 } 45 46 // static 47 scoped_ptr<TestWebGraphicsContext3D> TestWebGraphicsContext3D::Create() { 48 return make_scoped_ptr(new TestWebGraphicsContext3D()); 49 } 50 51 TestWebGraphicsContext3D::TestWebGraphicsContext3D() 52 : context_id_(s_context_id++), 53 times_bind_texture_succeeds_(-1), 54 times_end_query_succeeds_(-1), 55 context_lost_(false), 56 times_map_image_chromium_succeeds_(-1), 57 times_map_buffer_chromium_succeeds_(-1), 58 current_used_transfer_buffer_usage_bytes_(0), 59 max_used_transfer_buffer_usage_bytes_(0), 60 next_program_id_(1000), 61 next_shader_id_(2000), 62 max_texture_size_(2048), 63 reshape_called_(false), 64 width_(0), 65 height_(0), 66 scale_factor_(-1.f), 67 test_support_(NULL), 68 last_update_type_(NoUpdate), 69 next_insert_sync_point_(1), 70 last_waited_sync_point_(0), 71 bound_buffer_(0), 72 weak_ptr_factory_(this) { 73 CreateNamespace(); 74 } 75 76 TestWebGraphicsContext3D::~TestWebGraphicsContext3D() { 77 base::AutoLock lock(g_shared_namespace_lock.Get()); 78 namespace_ = NULL; 79 } 80 81 void TestWebGraphicsContext3D::CreateNamespace() { 82 base::AutoLock lock(g_shared_namespace_lock.Get()); 83 if (shared_namespace_) { 84 namespace_ = shared_namespace_; 85 } else { 86 namespace_ = new Namespace; 87 shared_namespace_ = namespace_.get(); 88 } 89 } 90 91 void TestWebGraphicsContext3D::reshapeWithScaleFactor( 92 int width, int height, float scale_factor) { 93 reshape_called_ = true; 94 width_ = width; 95 height_ = height; 96 scale_factor_ = scale_factor; 97 } 98 99 bool TestWebGraphicsContext3D::isContextLost() { 100 return context_lost_; 101 } 102 103 GLenum TestWebGraphicsContext3D::checkFramebufferStatus( 104 GLenum target) { 105 if (context_lost_) 106 return GL_FRAMEBUFFER_UNDEFINED_OES; 107 return GL_FRAMEBUFFER_COMPLETE; 108 } 109 110 GLint TestWebGraphicsContext3D::getUniformLocation( 111 GLuint program, 112 const GLchar* name) { 113 return 0; 114 } 115 116 GLsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset( 117 GLuint index, 118 GLenum pname) { 119 return 0; 120 } 121 122 GLboolean TestWebGraphicsContext3D::isBuffer( 123 GLuint buffer) { 124 return false; 125 } 126 127 GLboolean TestWebGraphicsContext3D::isEnabled( 128 GLenum cap) { 129 return false; 130 } 131 132 GLboolean TestWebGraphicsContext3D::isFramebuffer( 133 GLuint framebuffer) { 134 return false; 135 } 136 137 GLboolean TestWebGraphicsContext3D::isProgram( 138 GLuint program) { 139 return false; 140 } 141 142 GLboolean TestWebGraphicsContext3D::isRenderbuffer( 143 GLuint renderbuffer) { 144 return false; 145 } 146 147 GLboolean TestWebGraphicsContext3D::isShader( 148 GLuint shader) { 149 return false; 150 } 151 152 GLboolean TestWebGraphicsContext3D::isTexture( 153 GLuint texture) { 154 return false; 155 } 156 157 void TestWebGraphicsContext3D::genBuffers(GLsizei count, GLuint* ids) { 158 for (int i = 0; i < count; ++i) 159 ids[i] = NextBufferId(); 160 } 161 162 void TestWebGraphicsContext3D::genFramebuffers( 163 GLsizei count, GLuint* ids) { 164 for (int i = 0; i < count; ++i) 165 ids[i] = kFramebufferId | context_id_ << 16; 166 } 167 168 void TestWebGraphicsContext3D::genRenderbuffers( 169 GLsizei count, GLuint* ids) { 170 for (int i = 0; i < count; ++i) 171 ids[i] = kRenderbufferId | context_id_ << 16; 172 } 173 174 void TestWebGraphicsContext3D::genTextures(GLsizei count, GLuint* ids) { 175 for (int i = 0; i < count; ++i) { 176 ids[i] = NextTextureId(); 177 DCHECK_NE(ids[i], kExternalTextureId); 178 } 179 base::AutoLock lock(namespace_->lock); 180 for (int i = 0; i < count; ++i) 181 namespace_->textures.Append(ids[i], new TestTexture()); 182 } 183 184 void TestWebGraphicsContext3D::deleteBuffers(GLsizei count, GLuint* ids) { 185 for (int i = 0; i < count; ++i) 186 RetireBufferId(ids[i]); 187 } 188 189 void TestWebGraphicsContext3D::deleteFramebuffers( 190 GLsizei count, GLuint* ids) { 191 for (int i = 0; i < count; ++i) 192 DCHECK_EQ(kFramebufferId | context_id_ << 16, ids[i]); 193 } 194 195 void TestWebGraphicsContext3D::deleteRenderbuffers( 196 GLsizei count, GLuint* ids) { 197 for (int i = 0; i < count; ++i) 198 DCHECK_EQ(kRenderbufferId | context_id_ << 16, ids[i]); 199 } 200 201 void TestWebGraphicsContext3D::deleteTextures(GLsizei count, GLuint* ids) { 202 for (int i = 0; i < count; ++i) 203 RetireTextureId(ids[i]); 204 base::AutoLock lock(namespace_->lock); 205 for (int i = 0; i < count; ++i) { 206 namespace_->textures.Remove(ids[i]); 207 texture_targets_.UnbindTexture(ids[i]); 208 } 209 } 210 211 GLuint TestWebGraphicsContext3D::createBuffer() { 212 GLuint id; 213 genBuffers(1, &id); 214 return id; 215 } 216 217 GLuint TestWebGraphicsContext3D::createFramebuffer() { 218 GLuint id; 219 genFramebuffers(1, &id); 220 return id; 221 } 222 223 GLuint TestWebGraphicsContext3D::createRenderbuffer() { 224 GLuint id; 225 genRenderbuffers(1, &id); 226 return id; 227 } 228 229 GLuint TestWebGraphicsContext3D::createTexture() { 230 GLuint id; 231 genTextures(1, &id); 232 return id; 233 } 234 235 void TestWebGraphicsContext3D::deleteBuffer(GLuint id) { 236 deleteBuffers(1, &id); 237 } 238 239 void TestWebGraphicsContext3D::deleteFramebuffer(GLuint id) { 240 deleteFramebuffers(1, &id); 241 } 242 243 void TestWebGraphicsContext3D::deleteRenderbuffer(GLuint id) { 244 deleteRenderbuffers(1, &id); 245 } 246 247 void TestWebGraphicsContext3D::deleteTexture(GLuint id) { 248 deleteTextures(1, &id); 249 } 250 251 unsigned TestWebGraphicsContext3D::createProgram() { 252 unsigned program = next_program_id_++ | context_id_ << 16; 253 program_set_.insert(program); 254 return program; 255 } 256 257 GLuint TestWebGraphicsContext3D::createShader(GLenum) { 258 unsigned shader = next_shader_id_++ | context_id_ << 16; 259 shader_set_.insert(shader); 260 return shader; 261 } 262 263 GLuint TestWebGraphicsContext3D::createExternalTexture() { 264 base::AutoLock lock(namespace_->lock); 265 namespace_->textures.Append(kExternalTextureId, new TestTexture()); 266 return kExternalTextureId; 267 } 268 269 void TestWebGraphicsContext3D::deleteProgram(GLuint id) { 270 if (!program_set_.count(id)) 271 ADD_FAILURE() << "deleteProgram called on unknown program " << id; 272 program_set_.erase(id); 273 } 274 275 void TestWebGraphicsContext3D::deleteShader(GLuint id) { 276 if (!shader_set_.count(id)) 277 ADD_FAILURE() << "deleteShader called on unknown shader " << id; 278 shader_set_.erase(id); 279 } 280 281 void TestWebGraphicsContext3D::attachShader(GLuint program, GLuint shader) { 282 if (!program_set_.count(program)) 283 ADD_FAILURE() << "attachShader called with unknown program " << program; 284 if (!shader_set_.count(shader)) 285 ADD_FAILURE() << "attachShader called with unknown shader " << shader; 286 } 287 288 void TestWebGraphicsContext3D::useProgram(GLuint program) { 289 if (!program) 290 return; 291 if (!program_set_.count(program)) 292 ADD_FAILURE() << "useProgram called on unknown program " << program; 293 } 294 295 void TestWebGraphicsContext3D::bindFramebuffer( 296 GLenum target, GLuint framebuffer) { 297 if (!framebuffer) 298 return; 299 DCHECK_EQ(kFramebufferId | context_id_ << 16, framebuffer); 300 } 301 302 void TestWebGraphicsContext3D::bindRenderbuffer( 303 GLenum target, GLuint renderbuffer) { 304 if (!renderbuffer) 305 return; 306 DCHECK_EQ(kRenderbufferId | context_id_ << 16, renderbuffer); 307 } 308 309 void TestWebGraphicsContext3D::bindTexture( 310 GLenum target, GLuint texture_id) { 311 if (times_bind_texture_succeeds_ >= 0) { 312 if (!times_bind_texture_succeeds_) { 313 loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, 314 GL_INNOCENT_CONTEXT_RESET_ARB); 315 } 316 --times_bind_texture_succeeds_; 317 } 318 319 if (!texture_id) 320 return; 321 base::AutoLock lock(namespace_->lock); 322 DCHECK(namespace_->textures.ContainsId(texture_id)); 323 texture_targets_.BindTexture(target, texture_id); 324 used_textures_.insert(texture_id); 325 } 326 327 GLuint TestWebGraphicsContext3D::BoundTextureId( 328 GLenum target) { 329 return texture_targets_.BoundTexture(target); 330 } 331 332 scoped_refptr<TestTexture> TestWebGraphicsContext3D::BoundTexture( 333 GLenum target) { 334 // The caller is expected to lock the namespace for texture access. 335 namespace_->lock.AssertAcquired(); 336 return namespace_->textures.TextureForId(BoundTextureId(target)); 337 } 338 339 void TestWebGraphicsContext3D::CheckTextureIsBound(GLenum target) { 340 DCHECK(BoundTextureId(target)); 341 } 342 343 GLuint TestWebGraphicsContext3D::createQueryEXT() { return 1u; } 344 345 void TestWebGraphicsContext3D::endQueryEXT(GLenum target) { 346 if (times_end_query_succeeds_ >= 0) { 347 if (!times_end_query_succeeds_) { 348 loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, 349 GL_INNOCENT_CONTEXT_RESET_ARB); 350 } 351 --times_end_query_succeeds_; 352 } 353 } 354 355 void TestWebGraphicsContext3D::getQueryObjectuivEXT( 356 GLuint query, 357 GLenum pname, 358 GLuint* params) { 359 // If the context is lost, behave as if result is available. 360 if (pname == GL_QUERY_RESULT_AVAILABLE_EXT) 361 *params = 1; 362 } 363 364 void TestWebGraphicsContext3D::getIntegerv( 365 GLenum pname, 366 GLint* value) { 367 if (pname == GL_MAX_TEXTURE_SIZE) 368 *value = max_texture_size_; 369 else if (pname == GL_ACTIVE_TEXTURE) 370 *value = GL_TEXTURE0; 371 } 372 373 void TestWebGraphicsContext3D::getProgramiv(GLuint program, 374 GLenum pname, 375 GLint* value) { 376 if (pname == GL_LINK_STATUS) 377 *value = 1; 378 } 379 380 void TestWebGraphicsContext3D::getShaderiv(GLuint shader, 381 GLenum pname, 382 GLint* value) { 383 if (pname == GL_COMPILE_STATUS) 384 *value = 1; 385 } 386 387 void TestWebGraphicsContext3D::getShaderPrecisionFormat(GLenum shadertype, 388 GLenum precisiontype, 389 GLint* range, 390 GLint* precision) { 391 // Return the minimum precision requirements of the GLES2 392 // specification. 393 switch (precisiontype) { 394 case GL_LOW_INT: 395 range[0] = 8; 396 range[1] = 8; 397 *precision = 0; 398 break; 399 case GL_MEDIUM_INT: 400 range[0] = 10; 401 range[1] = 10; 402 *precision = 0; 403 break; 404 case GL_HIGH_INT: 405 range[0] = 16; 406 range[1] = 16; 407 *precision = 0; 408 break; 409 case GL_LOW_FLOAT: 410 range[0] = 8; 411 range[1] = 8; 412 *precision = 8; 413 break; 414 case GL_MEDIUM_FLOAT: 415 range[0] = 14; 416 range[1] = 14; 417 *precision = 10; 418 break; 419 case GL_HIGH_FLOAT: 420 range[0] = 62; 421 range[1] = 62; 422 *precision = 16; 423 break; 424 default: 425 NOTREACHED(); 426 break; 427 } 428 } 429 430 void TestWebGraphicsContext3D::genMailboxCHROMIUM(GLbyte* mailbox) { 431 static char mailbox_name1 = '1'; 432 static char mailbox_name2 = '1'; 433 mailbox[0] = mailbox_name1; 434 mailbox[1] = mailbox_name2; 435 mailbox[2] = '\0'; 436 if (++mailbox_name1 == 0) { 437 mailbox_name1 = '1'; 438 ++mailbox_name2; 439 } 440 } 441 442 GLuint TestWebGraphicsContext3D::createAndConsumeTextureCHROMIUM( 443 GLenum target, 444 const GLbyte* mailbox) { 445 return createTexture(); 446 } 447 448 void TestWebGraphicsContext3D::loseContextCHROMIUM(GLenum current, 449 GLenum other) { 450 if (context_lost_) 451 return; 452 context_lost_ = true; 453 if (!context_lost_callback_.is_null()) 454 context_lost_callback_.Run(); 455 456 for (size_t i = 0; i < shared_contexts_.size(); ++i) 457 shared_contexts_[i]->loseContextCHROMIUM(current, other); 458 shared_contexts_.clear(); 459 } 460 461 void TestWebGraphicsContext3D::finish() { 462 test_support_->CallAllSyncPointCallbacks(); 463 } 464 465 void TestWebGraphicsContext3D::flush() { 466 test_support_->CallAllSyncPointCallbacks(); 467 } 468 469 GLint TestWebGraphicsContext3D::getAttribLocation(GLuint program, 470 const GLchar* name) { 471 return 0; 472 } 473 474 GLenum TestWebGraphicsContext3D::getError() { return GL_NO_ERROR; } 475 476 void TestWebGraphicsContext3D::bindBuffer(GLenum target, 477 GLuint buffer) { 478 bound_buffer_ = buffer; 479 if (!bound_buffer_) 480 return; 481 unsigned context_id = buffer >> 16; 482 unsigned buffer_id = buffer & 0xffff; 483 base::AutoLock lock(namespace_->lock); 484 DCHECK(buffer_id); 485 DCHECK_LT(buffer_id, namespace_->next_buffer_id); 486 DCHECK_EQ(context_id, context_id_); 487 488 base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; 489 if (buffers.count(bound_buffer_) == 0) 490 buffers.set(bound_buffer_, make_scoped_ptr(new Buffer).Pass()); 491 492 buffers.get(bound_buffer_)->target = target; 493 } 494 495 void TestWebGraphicsContext3D::bufferData(GLenum target, 496 GLsizeiptr size, 497 const void* data, 498 GLenum usage) { 499 base::AutoLock lock(namespace_->lock); 500 base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; 501 DCHECK_GT(buffers.count(bound_buffer_), 0u); 502 DCHECK_EQ(target, buffers.get(bound_buffer_)->target); 503 Buffer* buffer = buffers.get(bound_buffer_); 504 if (context_lost_) { 505 buffer->pixels.reset(); 506 return; 507 } 508 509 size_t old_size = buffer->size; 510 511 buffer->pixels.reset(new uint8[size]); 512 buffer->size = size; 513 if (data != NULL) 514 memcpy(buffer->pixels.get(), data, size); 515 if (buffer->target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) 516 current_used_transfer_buffer_usage_bytes_ += buffer->size - old_size; 517 max_used_transfer_buffer_usage_bytes_ = 518 std::max(max_used_transfer_buffer_usage_bytes_, 519 current_used_transfer_buffer_usage_bytes_); 520 } 521 522 void* TestWebGraphicsContext3D::mapBufferCHROMIUM(GLenum target, 523 GLenum access) { 524 base::AutoLock lock(namespace_->lock); 525 base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; 526 DCHECK_GT(buffers.count(bound_buffer_), 0u); 527 DCHECK_EQ(target, buffers.get(bound_buffer_)->target); 528 if (times_map_buffer_chromium_succeeds_ >= 0) { 529 if (!times_map_buffer_chromium_succeeds_) { 530 return NULL; 531 } 532 --times_map_buffer_chromium_succeeds_; 533 } 534 535 return buffers.get(bound_buffer_)->pixels.get(); 536 } 537 538 GLboolean TestWebGraphicsContext3D::unmapBufferCHROMIUM( 539 GLenum target) { 540 base::AutoLock lock(namespace_->lock); 541 base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers; 542 DCHECK_GT(buffers.count(bound_buffer_), 0u); 543 DCHECK_EQ(target, buffers.get(bound_buffer_)->target); 544 buffers.get(bound_buffer_)->pixels.reset(); 545 return true; 546 } 547 548 GLuint TestWebGraphicsContext3D::createImageCHROMIUM(GLsizei width, 549 GLsizei height, 550 GLenum internalformat, 551 GLenum usage) { 552 DCHECK_EQ(GL_RGBA8_OES, static_cast<int>(internalformat)); 553 GLuint image_id = NextImageId(); 554 base::AutoLock lock(namespace_->lock); 555 base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; 556 images.set(image_id, make_scoped_ptr(new Image).Pass()); 557 images.get(image_id)->pixels.reset(new uint8[width * height * 4]); 558 return image_id; 559 } 560 561 void TestWebGraphicsContext3D::destroyImageCHROMIUM( 562 GLuint id) { 563 RetireImageId(id); 564 } 565 566 void TestWebGraphicsContext3D::getImageParameterivCHROMIUM( 567 GLuint image_id, 568 GLenum pname, 569 GLint* params) { 570 base::AutoLock lock(namespace_->lock); 571 DCHECK_GT(namespace_->images.count(image_id), 0u); 572 DCHECK_EQ(GL_IMAGE_ROWBYTES_CHROMIUM, static_cast<int>(pname)); 573 *params = 0; 574 } 575 576 void* TestWebGraphicsContext3D::mapImageCHROMIUM(GLuint image_id) { 577 base::AutoLock lock(namespace_->lock); 578 base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images; 579 DCHECK_GT(images.count(image_id), 0u); 580 if (times_map_image_chromium_succeeds_ >= 0) { 581 if (!times_map_image_chromium_succeeds_) { 582 return NULL; 583 } 584 --times_map_image_chromium_succeeds_; 585 } 586 return images.get(image_id)->pixels.get(); 587 } 588 589 void TestWebGraphicsContext3D::unmapImageCHROMIUM( 590 GLuint image_id) { 591 base::AutoLock lock(namespace_->lock); 592 DCHECK_GT(namespace_->images.count(image_id), 0u); 593 } 594 595 unsigned TestWebGraphicsContext3D::insertSyncPoint() { 596 return next_insert_sync_point_++; 597 } 598 599 void TestWebGraphicsContext3D::waitSyncPoint(unsigned sync_point) { 600 if (sync_point) 601 last_waited_sync_point_ = sync_point; 602 } 603 604 size_t TestWebGraphicsContext3D::NumTextures() const { 605 base::AutoLock lock(namespace_->lock); 606 return namespace_->textures.Size(); 607 } 608 609 GLuint TestWebGraphicsContext3D::TextureAt(int i) const { 610 base::AutoLock lock(namespace_->lock); 611 return namespace_->textures.IdAt(i); 612 } 613 614 GLuint TestWebGraphicsContext3D::NextTextureId() { 615 base::AutoLock lock(namespace_->lock); 616 GLuint texture_id = namespace_->next_texture_id++; 617 DCHECK(texture_id < (1 << 16)); 618 texture_id |= context_id_ << 16; 619 return texture_id; 620 } 621 622 void TestWebGraphicsContext3D::RetireTextureId(GLuint id) { 623 base::AutoLock lock(namespace_->lock); 624 unsigned context_id = id >> 16; 625 unsigned texture_id = id & 0xffff; 626 DCHECK(texture_id); 627 DCHECK_LT(texture_id, namespace_->next_texture_id); 628 DCHECK_EQ(context_id, context_id_); 629 } 630 631 GLuint TestWebGraphicsContext3D::NextBufferId() { 632 base::AutoLock lock(namespace_->lock); 633 GLuint buffer_id = namespace_->next_buffer_id++; 634 DCHECK(buffer_id < (1 << 16)); 635 buffer_id |= context_id_ << 16; 636 return buffer_id; 637 } 638 639 void TestWebGraphicsContext3D::RetireBufferId(GLuint id) { 640 base::AutoLock lock(namespace_->lock); 641 unsigned context_id = id >> 16; 642 unsigned buffer_id = id & 0xffff; 643 DCHECK(buffer_id); 644 DCHECK_LT(buffer_id, namespace_->next_buffer_id); 645 DCHECK_EQ(context_id, context_id_); 646 } 647 648 GLuint TestWebGraphicsContext3D::NextImageId() { 649 base::AutoLock lock(namespace_->lock); 650 GLuint image_id = namespace_->next_image_id++; 651 DCHECK(image_id < (1 << 16)); 652 image_id |= context_id_ << 16; 653 return image_id; 654 } 655 656 void TestWebGraphicsContext3D::RetireImageId(GLuint id) { 657 base::AutoLock lock(namespace_->lock); 658 unsigned context_id = id >> 16; 659 unsigned image_id = id & 0xffff; 660 DCHECK(image_id); 661 DCHECK_LT(image_id, namespace_->next_image_id); 662 DCHECK_EQ(context_id, context_id_); 663 } 664 665 void TestWebGraphicsContext3D::SetMaxTransferBufferUsageBytes( 666 size_t max_transfer_buffer_usage_bytes) { 667 test_capabilities_.max_transfer_buffer_usage_bytes = 668 max_transfer_buffer_usage_bytes; 669 } 670 671 TestWebGraphicsContext3D::TextureTargets::TextureTargets() { 672 // Initialize default bindings. 673 bound_textures_[GL_TEXTURE_2D] = 0; 674 bound_textures_[GL_TEXTURE_EXTERNAL_OES] = 0; 675 bound_textures_[GL_TEXTURE_RECTANGLE_ARB] = 0; 676 } 677 678 TestWebGraphicsContext3D::TextureTargets::~TextureTargets() {} 679 680 void TestWebGraphicsContext3D::TextureTargets::BindTexture( 681 GLenum target, 682 GLuint id) { 683 // Make sure this is a supported target by seeing if it was bound to before. 684 DCHECK(bound_textures_.find(target) != bound_textures_.end()); 685 bound_textures_[target] = id; 686 } 687 688 void TestWebGraphicsContext3D::texParameteri(GLenum target, 689 GLenum pname, 690 GLint param) { 691 CheckTextureIsBound(target); 692 base::AutoLock lock_for_texture_access(namespace_->lock); 693 scoped_refptr<TestTexture> texture = BoundTexture(target); 694 DCHECK(texture->IsValidParameter(pname)); 695 texture->params[pname] = param; 696 } 697 698 void TestWebGraphicsContext3D::getTexParameteriv(GLenum target, 699 GLenum pname, 700 GLint* value) { 701 CheckTextureIsBound(target); 702 base::AutoLock lock_for_texture_access(namespace_->lock); 703 scoped_refptr<TestTexture> texture = BoundTexture(target); 704 DCHECK(texture->IsValidParameter(pname)); 705 TestTexture::TextureParametersMap::iterator it = texture->params.find(pname); 706 if (it != texture->params.end()) 707 *value = it->second; 708 } 709 710 void TestWebGraphicsContext3D::TextureTargets::UnbindTexture( 711 GLuint id) { 712 // Bind zero to any targets that the id is bound to. 713 for (TargetTextureMap::iterator it = bound_textures_.begin(); 714 it != bound_textures_.end(); 715 it++) { 716 if (it->second == id) 717 it->second = 0; 718 } 719 } 720 721 GLuint TestWebGraphicsContext3D::TextureTargets::BoundTexture( 722 GLenum target) { 723 DCHECK(bound_textures_.find(target) != bound_textures_.end()); 724 return bound_textures_[target]; 725 } 726 727 TestWebGraphicsContext3D::Buffer::Buffer() : target(0), size(0) {} 728 729 TestWebGraphicsContext3D::Buffer::~Buffer() {} 730 731 TestWebGraphicsContext3D::Image::Image() {} 732 733 TestWebGraphicsContext3D::Image::~Image() {} 734 735 } // namespace cc 736