Upstream version 8.37.180.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       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
76 TestWebGraphicsContext3D::~TestWebGraphicsContext3D() {
77   base::AutoLock lock(g_shared_namespace_lock.Get());
78   namespace_ = NULL;
79 }
80
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
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
99 bool TestWebGraphicsContext3D::isContextLost() {
100   return context_lost_;
101 }
102
103 GLenum TestWebGraphicsContext3D::checkFramebufferStatus(
104     GLenum target) {
105   if (context_lost_)
106     return GL_FRAMEBUFFER_UNDEFINED_OES;
107   return GL_FRAMEBUFFER_COMPLETE;
108 }
109
110 GLint TestWebGraphicsContext3D::getUniformLocation(
111     GLuint program,
112     const GLchar* name) {
113   return 0;
114 }
115
116 GLsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset(
117     GLuint index,
118     GLenum pname) {
119   return 0;
120 }
121
122 GLboolean TestWebGraphicsContext3D::isBuffer(
123     GLuint buffer) {
124   return false;
125 }
126
127 GLboolean TestWebGraphicsContext3D::isEnabled(
128     GLenum cap) {
129   return false;
130 }
131
132 GLboolean TestWebGraphicsContext3D::isFramebuffer(
133     GLuint framebuffer) {
134   return false;
135 }
136
137 GLboolean TestWebGraphicsContext3D::isProgram(
138     GLuint program) {
139   return false;
140 }
141
142 GLboolean TestWebGraphicsContext3D::isRenderbuffer(
143     GLuint renderbuffer) {
144   return false;
145 }
146
147 GLboolean TestWebGraphicsContext3D::isShader(
148     GLuint shader) {
149   return false;
150 }
151
152 GLboolean TestWebGraphicsContext3D::isTexture(
153     GLuint texture) {
154   return false;
155 }
156
157 void TestWebGraphicsContext3D::genBuffers(GLsizei count, GLuint* ids) {
158   for (int i = 0; i < count; ++i)
159     ids[i] = NextBufferId();
160 }
161
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
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
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
184 void TestWebGraphicsContext3D::deleteBuffers(GLsizei count, GLuint* ids) {
185   for (int i = 0; i < count; ++i)
186     RetireBufferId(ids[i]);
187 }
188
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
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
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
211 GLuint TestWebGraphicsContext3D::createBuffer() {
212   GLuint id;
213   genBuffers(1, &id);
214   return id;
215 }
216
217 GLuint TestWebGraphicsContext3D::createFramebuffer() {
218   GLuint id;
219   genFramebuffers(1, &id);
220   return id;
221 }
222
223 GLuint TestWebGraphicsContext3D::createRenderbuffer() {
224   GLuint id;
225   genRenderbuffers(1, &id);
226   return id;
227 }
228
229 GLuint TestWebGraphicsContext3D::createTexture() {
230   GLuint id;
231   genTextures(1, &id);
232   return id;
233 }
234
235 void TestWebGraphicsContext3D::deleteBuffer(GLuint id) {
236   deleteBuffers(1, &id);
237 }
238
239 void TestWebGraphicsContext3D::deleteFramebuffer(GLuint id) {
240   deleteFramebuffers(1, &id);
241 }
242
243 void TestWebGraphicsContext3D::deleteRenderbuffer(GLuint id) {
244   deleteRenderbuffers(1, &id);
245 }
246
247 void TestWebGraphicsContext3D::deleteTexture(GLuint id) {
248   deleteTextures(1, &id);
249 }
250
251 unsigned TestWebGraphicsContext3D::createProgram() {
252   unsigned program = next_program_id_++ | context_id_ << 16;
253   program_set_.insert(program);
254   return program;
255 }
256
257 GLuint TestWebGraphicsContext3D::createShader(GLenum) {
258   unsigned shader = next_shader_id_++ | context_id_ << 16;
259   shader_set_.insert(shader);
260   return shader;
261 }
262
263 GLuint TestWebGraphicsContext3D::createExternalTexture() {
264   base::AutoLock lock(namespace_->lock);
265   namespace_->textures.Append(kExternalTextureId, new TestTexture());
266   return kExternalTextureId;
267 }
268
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
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
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
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
295 void TestWebGraphicsContext3D::bindFramebuffer(
296     GLenum target, GLuint framebuffer) {
297   if (!framebuffer)
298     return;
299   DCHECK_EQ(kFramebufferId | context_id_ << 16, framebuffer);
300 }
301
302 void TestWebGraphicsContext3D::bindRenderbuffer(
303       GLenum target, GLuint renderbuffer) {
304   if (!renderbuffer)
305     return;
306   DCHECK_EQ(kRenderbufferId | context_id_ << 16, renderbuffer);
307 }
308
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
327 GLuint TestWebGraphicsContext3D::BoundTextureId(
328     GLenum target) {
329   return texture_targets_.BoundTexture(target);
330 }
331
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
339 void TestWebGraphicsContext3D::CheckTextureIsBound(GLenum target) {
340   DCHECK(BoundTextureId(target));
341 }
342
343 GLuint TestWebGraphicsContext3D::createQueryEXT() { return 1u; }
344
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
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
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
373 void TestWebGraphicsContext3D::getProgramiv(GLuint program,
374                                             GLenum pname,
375                                             GLint* value) {
376   if (pname == GL_LINK_STATUS)
377     *value = 1;
378 }
379
380 void TestWebGraphicsContext3D::getShaderiv(GLuint shader,
381                                            GLenum pname,
382                                            GLint* value) {
383   if (pname == GL_COMPILE_STATUS)
384     *value = 1;
385 }
386
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
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
442 void TestWebGraphicsContext3D::loseContextCHROMIUM(GLenum current,
443                                                    GLenum other) {
444   if (context_lost_)
445     return;
446   context_lost_ = true;
447   if (!context_lost_callback_.is_null())
448     context_lost_callback_.Run();
449
450   for (size_t i = 0; i < shared_contexts_.size(); ++i)
451     shared_contexts_[i]->loseContextCHROMIUM(current, other);
452   shared_contexts_.clear();
453 }
454
455 void TestWebGraphicsContext3D::finish() {
456   test_support_->CallAllSyncPointCallbacks();
457 }
458
459 void TestWebGraphicsContext3D::flush() {
460   test_support_->CallAllSyncPointCallbacks();
461 }
462
463 GLint TestWebGraphicsContext3D::getAttribLocation(GLuint program,
464                                                   const GLchar* name) {
465   return 0;
466 }
467
468 GLenum TestWebGraphicsContext3D::getError() { return GL_NO_ERROR; }
469
470 void TestWebGraphicsContext3D::bindBuffer(GLenum target,
471                                           GLuint buffer) {
472   bound_buffer_ = buffer;
473   if (!bound_buffer_)
474     return;
475   unsigned context_id = buffer >> 16;
476   unsigned buffer_id = buffer & 0xffff;
477   base::AutoLock lock(namespace_->lock);
478   DCHECK(buffer_id);
479   DCHECK_LT(buffer_id, namespace_->next_buffer_id);
480   DCHECK_EQ(context_id, context_id_);
481
482   base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers;
483   if (buffers.count(bound_buffer_) == 0)
484     buffers.set(bound_buffer_, make_scoped_ptr(new Buffer).Pass());
485
486   buffers.get(bound_buffer_)->target = target;
487 }
488
489 void TestWebGraphicsContext3D::bufferData(GLenum target,
490                                           GLsizeiptr size,
491                                           const void* data,
492                                           GLenum usage) {
493   base::AutoLock lock(namespace_->lock);
494   base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers;
495   DCHECK_GT(buffers.count(bound_buffer_), 0u);
496   DCHECK_EQ(target, buffers.get(bound_buffer_)->target);
497   Buffer* buffer = buffers.get(bound_buffer_);
498   if (context_lost_) {
499     buffer->pixels.reset();
500     return;
501   }
502
503   size_t old_size = buffer->size;
504
505   buffer->pixels.reset(new uint8[size]);
506   buffer->size = size;
507   if (data != NULL)
508     memcpy(buffer->pixels.get(), data, size);
509   if (buffer->target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM)
510     current_used_transfer_buffer_usage_bytes_ += buffer->size - old_size;
511   max_used_transfer_buffer_usage_bytes_ =
512       std::max(max_used_transfer_buffer_usage_bytes_,
513                current_used_transfer_buffer_usage_bytes_);
514 }
515
516 void* TestWebGraphicsContext3D::mapBufferCHROMIUM(GLenum target,
517                                                   GLenum access) {
518   base::AutoLock lock(namespace_->lock);
519   base::ScopedPtrHashMap<unsigned, Buffer>& buffers = namespace_->buffers;
520   DCHECK_GT(buffers.count(bound_buffer_), 0u);
521   DCHECK_EQ(target, buffers.get(bound_buffer_)->target);
522   if (times_map_buffer_chromium_succeeds_ >= 0) {
523     if (!times_map_buffer_chromium_succeeds_) {
524       return NULL;
525     }
526     --times_map_buffer_chromium_succeeds_;
527   }
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(GLsizei width,
543                                                      GLsizei height,
544                                                      GLenum internalformat,
545                                                      GLenum usage) {
546   DCHECK_EQ(GL_RGBA8_OES, static_cast<int>(internalformat));
547   GLuint image_id = NextImageId();
548   base::AutoLock lock(namespace_->lock);
549   base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images;
550   images.set(image_id, make_scoped_ptr(new Image).Pass());
551   images.get(image_id)->pixels.reset(new uint8[width * height * 4]);
552   return image_id;
553 }
554
555 void TestWebGraphicsContext3D::destroyImageCHROMIUM(
556     GLuint id) {
557   RetireImageId(id);
558 }
559
560 void TestWebGraphicsContext3D::getImageParameterivCHROMIUM(
561     GLuint image_id,
562     GLenum pname,
563     GLint* params) {
564   base::AutoLock lock(namespace_->lock);
565   DCHECK_GT(namespace_->images.count(image_id), 0u);
566   DCHECK_EQ(GL_IMAGE_ROWBYTES_CHROMIUM, static_cast<int>(pname));
567   *params = 0;
568 }
569
570 void* TestWebGraphicsContext3D::mapImageCHROMIUM(GLuint image_id) {
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 void TestWebGraphicsContext3D::SetMaxTransferBufferUsageBytes(
660     size_t max_transfer_buffer_usage_bytes) {
661   test_capabilities_.max_transfer_buffer_usage_bytes =
662       max_transfer_buffer_usage_bytes;
663 }
664
665 TestWebGraphicsContext3D::TextureTargets::TextureTargets() {
666   // Initialize default bindings.
667   bound_textures_[GL_TEXTURE_2D] = 0;
668   bound_textures_[GL_TEXTURE_EXTERNAL_OES] = 0;
669   bound_textures_[GL_TEXTURE_RECTANGLE_ARB] = 0;
670 }
671
672 TestWebGraphicsContext3D::TextureTargets::~TextureTargets() {}
673
674 void TestWebGraphicsContext3D::TextureTargets::BindTexture(
675     GLenum target,
676     GLuint id) {
677   // Make sure this is a supported target by seeing if it was bound to before.
678   DCHECK(bound_textures_.find(target) != bound_textures_.end());
679   bound_textures_[target] = id;
680 }
681
682 void TestWebGraphicsContext3D::texParameteri(GLenum target,
683                                              GLenum pname,
684                                              GLint param) {
685   CheckTextureIsBound(target);
686   base::AutoLock lock_for_texture_access(namespace_->lock);
687   scoped_refptr<TestTexture> texture = BoundTexture(target);
688   DCHECK(texture->IsValidParameter(pname));
689   texture->params[pname] = param;
690 }
691
692 void TestWebGraphicsContext3D::getTexParameteriv(GLenum target,
693                                                  GLenum pname,
694                                                  GLint* value) {
695   CheckTextureIsBound(target);
696   base::AutoLock lock_for_texture_access(namespace_->lock);
697   scoped_refptr<TestTexture> texture = BoundTexture(target);
698   DCHECK(texture->IsValidParameter(pname));
699   TestTexture::TextureParametersMap::iterator it = texture->params.find(pname);
700   if (it != texture->params.end())
701     *value = it->second;
702 }
703
704 void TestWebGraphicsContext3D::TextureTargets::UnbindTexture(
705     GLuint id) {
706   // Bind zero to any targets that the id is bound to.
707   for (TargetTextureMap::iterator it = bound_textures_.begin();
708        it != bound_textures_.end();
709        it++) {
710     if (it->second == id)
711       it->second = 0;
712   }
713 }
714
715 GLuint TestWebGraphicsContext3D::TextureTargets::BoundTexture(
716     GLenum target) {
717   DCHECK(bound_textures_.find(target) != bound_textures_.end());
718   return bound_textures_[target];
719 }
720
721 TestWebGraphicsContext3D::Buffer::Buffer() : target(0), size(0) {}
722
723 TestWebGraphicsContext3D::Buffer::~Buffer() {}
724
725 TestWebGraphicsContext3D::Image::Image() {}
726
727 TestWebGraphicsContext3D::Image::~Image() {}
728
729 }  // namespace cc