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