• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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