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
Namespace()34 TestWebGraphicsContext3D::Namespace::Namespace()
35 : next_buffer_id(1),
36 next_image_id(1),
37 next_texture_id(1) {
38 }
39
~Namespace()40 TestWebGraphicsContext3D::Namespace::~Namespace() {
41 g_shared_namespace_lock.Get().AssertAcquired();
42 if (shared_namespace_ == this)
43 shared_namespace_ = NULL;
44 }
45
46 // static
Create()47 scoped_ptr<TestWebGraphicsContext3D> TestWebGraphicsContext3D::Create() {
48 return make_scoped_ptr(new TestWebGraphicsContext3D());
49 }
50
TestWebGraphicsContext3D()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
~TestWebGraphicsContext3D()76 TestWebGraphicsContext3D::~TestWebGraphicsContext3D() {
77 base::AutoLock lock(g_shared_namespace_lock.Get());
78 namespace_ = NULL;
79 }
80
CreateNamespace()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
reshapeWithScaleFactor(int width,int height,float scale_factor)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
isContextLost()99 bool TestWebGraphicsContext3D::isContextLost() {
100 return context_lost_;
101 }
102
checkFramebufferStatus(GLenum target)103 GLenum TestWebGraphicsContext3D::checkFramebufferStatus(
104 GLenum target) {
105 if (context_lost_)
106 return GL_FRAMEBUFFER_UNDEFINED_OES;
107 return GL_FRAMEBUFFER_COMPLETE;
108 }
109
getUniformLocation(GLuint program,const GLchar * name)110 GLint TestWebGraphicsContext3D::getUniformLocation(
111 GLuint program,
112 const GLchar* name) {
113 return 0;
114 }
115
getVertexAttribOffset(GLuint index,GLenum pname)116 GLsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset(
117 GLuint index,
118 GLenum pname) {
119 return 0;
120 }
121
isBuffer(GLuint buffer)122 GLboolean TestWebGraphicsContext3D::isBuffer(
123 GLuint buffer) {
124 return false;
125 }
126
isEnabled(GLenum cap)127 GLboolean TestWebGraphicsContext3D::isEnabled(
128 GLenum cap) {
129 return false;
130 }
131
isFramebuffer(GLuint framebuffer)132 GLboolean TestWebGraphicsContext3D::isFramebuffer(
133 GLuint framebuffer) {
134 return false;
135 }
136
isProgram(GLuint program)137 GLboolean TestWebGraphicsContext3D::isProgram(
138 GLuint program) {
139 return false;
140 }
141
isRenderbuffer(GLuint renderbuffer)142 GLboolean TestWebGraphicsContext3D::isRenderbuffer(
143 GLuint renderbuffer) {
144 return false;
145 }
146
isShader(GLuint shader)147 GLboolean TestWebGraphicsContext3D::isShader(
148 GLuint shader) {
149 return false;
150 }
151
isTexture(GLuint texture)152 GLboolean TestWebGraphicsContext3D::isTexture(
153 GLuint texture) {
154 return false;
155 }
156
genBuffers(GLsizei count,GLuint * ids)157 void TestWebGraphicsContext3D::genBuffers(GLsizei count, GLuint* ids) {
158 for (int i = 0; i < count; ++i)
159 ids[i] = NextBufferId();
160 }
161
genFramebuffers(GLsizei count,GLuint * ids)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
genRenderbuffers(GLsizei count,GLuint * ids)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
genTextures(GLsizei count,GLuint * ids)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
deleteBuffers(GLsizei count,GLuint * ids)184 void TestWebGraphicsContext3D::deleteBuffers(GLsizei count, GLuint* ids) {
185 for (int i = 0; i < count; ++i)
186 RetireBufferId(ids[i]);
187 }
188
deleteFramebuffers(GLsizei count,GLuint * ids)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
deleteRenderbuffers(GLsizei count,GLuint * ids)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
deleteTextures(GLsizei count,GLuint * ids)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
createBuffer()211 GLuint TestWebGraphicsContext3D::createBuffer() {
212 GLuint id;
213 genBuffers(1, &id);
214 return id;
215 }
216
createFramebuffer()217 GLuint TestWebGraphicsContext3D::createFramebuffer() {
218 GLuint id;
219 genFramebuffers(1, &id);
220 return id;
221 }
222
createRenderbuffer()223 GLuint TestWebGraphicsContext3D::createRenderbuffer() {
224 GLuint id;
225 genRenderbuffers(1, &id);
226 return id;
227 }
228
createTexture()229 GLuint TestWebGraphicsContext3D::createTexture() {
230 GLuint id;
231 genTextures(1, &id);
232 return id;
233 }
234
deleteBuffer(GLuint id)235 void TestWebGraphicsContext3D::deleteBuffer(GLuint id) {
236 deleteBuffers(1, &id);
237 }
238
deleteFramebuffer(GLuint id)239 void TestWebGraphicsContext3D::deleteFramebuffer(GLuint id) {
240 deleteFramebuffers(1, &id);
241 }
242
deleteRenderbuffer(GLuint id)243 void TestWebGraphicsContext3D::deleteRenderbuffer(GLuint id) {
244 deleteRenderbuffers(1, &id);
245 }
246
deleteTexture(GLuint id)247 void TestWebGraphicsContext3D::deleteTexture(GLuint id) {
248 deleteTextures(1, &id);
249 }
250
createProgram()251 unsigned TestWebGraphicsContext3D::createProgram() {
252 unsigned program = next_program_id_++ | context_id_ << 16;
253 program_set_.insert(program);
254 return program;
255 }
256
createShader(GLenum)257 GLuint TestWebGraphicsContext3D::createShader(GLenum) {
258 unsigned shader = next_shader_id_++ | context_id_ << 16;
259 shader_set_.insert(shader);
260 return shader;
261 }
262
createExternalTexture()263 GLuint TestWebGraphicsContext3D::createExternalTexture() {
264 base::AutoLock lock(namespace_->lock);
265 namespace_->textures.Append(kExternalTextureId, new TestTexture());
266 return kExternalTextureId;
267 }
268
deleteProgram(GLuint id)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
deleteShader(GLuint id)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
attachShader(GLuint program,GLuint shader)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
useProgram(GLuint program)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
bindFramebuffer(GLenum target,GLuint framebuffer)295 void TestWebGraphicsContext3D::bindFramebuffer(
296 GLenum target, GLuint framebuffer) {
297 if (!framebuffer)
298 return;
299 DCHECK_EQ(kFramebufferId | context_id_ << 16, framebuffer);
300 }
301
bindRenderbuffer(GLenum target,GLuint renderbuffer)302 void TestWebGraphicsContext3D::bindRenderbuffer(
303 GLenum target, GLuint renderbuffer) {
304 if (!renderbuffer)
305 return;
306 DCHECK_EQ(kRenderbufferId | context_id_ << 16, renderbuffer);
307 }
308
bindTexture(GLenum target,GLuint texture_id)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
BoundTextureId(GLenum target)327 GLuint TestWebGraphicsContext3D::BoundTextureId(
328 GLenum target) {
329 return texture_targets_.BoundTexture(target);
330 }
331
BoundTexture(GLenum target)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
CheckTextureIsBound(GLenum target)339 void TestWebGraphicsContext3D::CheckTextureIsBound(GLenum target) {
340 DCHECK(BoundTextureId(target));
341 }
342
createQueryEXT()343 GLuint TestWebGraphicsContext3D::createQueryEXT() { return 1u; }
344
endQueryEXT(GLenum target)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
getQueryObjectuivEXT(GLuint query,GLenum pname,GLuint * params)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
getIntegerv(GLenum pname,GLint * value)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
getProgramiv(GLuint program,GLenum pname,GLint * value)373 void TestWebGraphicsContext3D::getProgramiv(GLuint program,
374 GLenum pname,
375 GLint* value) {
376 if (pname == GL_LINK_STATUS)
377 *value = 1;
378 }
379
getShaderiv(GLuint shader,GLenum pname,GLint * value)380 void TestWebGraphicsContext3D::getShaderiv(GLuint shader,
381 GLenum pname,
382 GLint* value) {
383 if (pname == GL_COMPILE_STATUS)
384 *value = 1;
385 }
386
getShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)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
genMailboxCHROMIUM(GLbyte * mailbox)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
createAndConsumeTextureCHROMIUM(GLenum target,const GLbyte * mailbox)442 GLuint TestWebGraphicsContext3D::createAndConsumeTextureCHROMIUM(
443 GLenum target,
444 const GLbyte* mailbox) {
445 return createTexture();
446 }
447
loseContextCHROMIUM(GLenum current,GLenum other)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
finish()461 void TestWebGraphicsContext3D::finish() {
462 test_support_->CallAllSyncPointCallbacks();
463 }
464
flush()465 void TestWebGraphicsContext3D::flush() {
466 test_support_->CallAllSyncPointCallbacks();
467 }
468
getAttribLocation(GLuint program,const GLchar * name)469 GLint TestWebGraphicsContext3D::getAttribLocation(GLuint program,
470 const GLchar* name) {
471 return 0;
472 }
473
getError()474 GLenum TestWebGraphicsContext3D::getError() { return GL_NO_ERROR; }
475
bindBuffer(GLenum target,GLuint buffer)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
bufferData(GLenum target,GLsizeiptr size,const void * data,GLenum usage)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
mapBufferCHROMIUM(GLenum target,GLenum access)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
unmapBufferCHROMIUM(GLenum target)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
createImageCHROMIUM(GLsizei width,GLsizei height,GLenum internalformat,GLenum usage)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
destroyImageCHROMIUM(GLuint id)561 void TestWebGraphicsContext3D::destroyImageCHROMIUM(
562 GLuint id) {
563 RetireImageId(id);
564 }
565
getImageParameterivCHROMIUM(GLuint image_id,GLenum pname,GLint * params)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
mapImageCHROMIUM(GLuint image_id)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
unmapImageCHROMIUM(GLuint image_id)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
insertSyncPoint()595 unsigned TestWebGraphicsContext3D::insertSyncPoint() {
596 return next_insert_sync_point_++;
597 }
598
waitSyncPoint(unsigned sync_point)599 void TestWebGraphicsContext3D::waitSyncPoint(unsigned sync_point) {
600 if (sync_point)
601 last_waited_sync_point_ = sync_point;
602 }
603
NumTextures() const604 size_t TestWebGraphicsContext3D::NumTextures() const {
605 base::AutoLock lock(namespace_->lock);
606 return namespace_->textures.Size();
607 }
608
TextureAt(int i) const609 GLuint TestWebGraphicsContext3D::TextureAt(int i) const {
610 base::AutoLock lock(namespace_->lock);
611 return namespace_->textures.IdAt(i);
612 }
613
NextTextureId()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
RetireTextureId(GLuint id)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
NextBufferId()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
RetireBufferId(GLuint id)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
NextImageId()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
RetireImageId(GLuint id)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
SetMaxTransferBufferUsageBytes(size_t max_transfer_buffer_usage_bytes)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
TextureTargets()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
~TextureTargets()678 TestWebGraphicsContext3D::TextureTargets::~TextureTargets() {}
679
BindTexture(GLenum target,GLuint id)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
texParameteri(GLenum target,GLenum pname,GLint param)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
getTexParameteriv(GLenum target,GLenum pname,GLint * value)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
UnbindTexture(GLuint id)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
BoundTexture(GLenum target)721 GLuint TestWebGraphicsContext3D::TextureTargets::BoundTexture(
722 GLenum target) {
723 DCHECK(bound_textures_.find(target) != bound_textures_.end());
724 return bound_textures_[target];
725 }
726
Buffer()727 TestWebGraphicsContext3D::Buffer::Buffer() : target(0), size(0) {}
728
~Buffer()729 TestWebGraphicsContext3D::Buffer::~Buffer() {}
730
Image()731 TestWebGraphicsContext3D::Image::Image() {}
732
~Image()733 TestWebGraphicsContext3D::Image::~Image() {}
734
735 } // namespace cc
736