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