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