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