OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" | |
6 | |
7 #include "third_party/khronos/GLES2/gl2.h" | |
8 #ifndef GL_GLEXT_PROTOTYPES | |
9 #define GL_GLEXT_PROTOTYPES 1 | |
10 #endif | |
11 #include "third_party/khronos/GLES2/gl2ext.h" | |
12 | |
13 #include <algorithm> | |
14 #include <set> | |
15 | |
16 #include "base/bind.h" | |
17 #include "base/lazy_instance.h" | |
18 #include "base/string_tokenizer.h" | |
19 #include "base/command_line.h" | |
20 #include "base/debug/trace_event.h" | |
21 #include "base/logging.h" | |
22 #include "base/message_loop.h" | |
23 #include "base/metrics/histogram.h" | |
24 #include "base/synchronization/lock.h" | |
25 #include "content/public/common/content_switches.h" | |
26 #include "content/renderer/gpu/command_buffer_proxy.h" | |
27 #include "content/renderer/gpu/gpu_channel_host.h" | |
28 #include "content/renderer/render_view_impl.h" | |
29 #include "gpu/command_buffer/client/gles2_implementation.h" | |
30 #include "gpu/command_buffer/common/constants.h" | |
31 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" | |
32 | |
33 static base::LazyInstance<base::Lock>::Leaky | |
34 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER; | |
35 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> > | |
36 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER; | |
37 | |
38 namespace { | |
39 | |
40 void ClearSharedContexts() { | |
41 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | |
42 g_all_shared_contexts.Pointer()->clear(); | |
43 } | |
44 | |
45 } // namespace anonymous | |
46 | |
47 | |
48 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( | |
49 int surface_id, | |
50 const GURL& active_url, | |
51 const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client) | |
52 : initialize_failed_(false), | |
53 context_(NULL), | |
54 gl_(NULL), | |
55 host_(NULL), | |
56 surface_id_(surface_id), | |
57 active_url_(active_url), | |
58 swap_client_(swap_client), | |
59 context_lost_callback_(0), | |
60 context_lost_reason_(GL_NO_ERROR), | |
61 swapbuffers_complete_callback_(0), | |
62 gpu_preference_(gfx::PreferIntegratedGpu), | |
63 cached_width_(0), | |
64 cached_height_(0), | |
65 bound_fbo_(0), | |
66 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
67 } | |
68 | |
69 WebGraphicsContext3DCommandBufferImpl:: | |
70 ~WebGraphicsContext3DCommandBufferImpl() { | |
71 if (host_) { | |
72 if (host_->WillGpuSwitchOccur(false, gpu_preference_)) { | |
73 host_->ForciblyCloseChannel(); | |
74 ClearSharedContexts(); | |
75 } | |
76 } | |
77 | |
78 { | |
79 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | |
80 g_all_shared_contexts.Pointer()->erase(this); | |
81 } | |
82 delete context_; | |
83 } | |
84 | |
85 bool WebGraphicsContext3DCommandBufferImpl::Initialize( | |
86 const WebGraphicsContext3D::Attributes& attributes) { | |
87 DCHECK(!context_); | |
88 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize"); | |
89 GpuChannelHostFactory* factory = GpuChannelHostFactory::instance(); | |
90 if (!factory) | |
91 return false; | |
92 | |
93 // The noExtensions and canRecoverFromContextLoss flags are | |
94 // currently used as hints that we are creating a context on | |
95 // behalf of WebGL or accelerated 2D canvas, respectively. | |
96 if (attributes.noExtensions || !attributes.canRecoverFromContextLoss) | |
97 gpu_preference_ = gfx::PreferDiscreteGpu; | |
98 | |
99 bool retry = false; | |
100 | |
101 // Note similar code in Pepper PlatformContext3DImpl::Init. | |
102 do { | |
103 host_ = factory->EstablishGpuChannelSync( | |
104 content:: | |
105 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); | |
106 if (!host_) | |
107 return false; | |
108 DCHECK(host_->state() == GpuChannelHost::kConnected); | |
109 | |
110 if (!retry) { | |
111 // If the creation of this context requires all contexts for this | |
112 // renderer to be destroyed on the GPU process side, then drop the | |
113 // channel and recreate it. | |
114 if (host_->WillGpuSwitchOccur(true, gpu_preference_)) { | |
115 host_->ForciblyCloseChannel(); | |
116 ClearSharedContexts(); | |
117 retry = true; | |
118 } | |
119 } else { | |
120 retry = false; | |
121 } | |
122 } while (retry); | |
123 | |
124 const content::GPUInfo& gpu_info = host_->gpu_info(); | |
125 UMA_HISTOGRAM_ENUMERATION( | |
126 "GPU.WebGraphicsContext3D_Init_CanLoseContext", | |
127 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context, | |
128 4); | |
129 if (attributes.canRecoverFromContextLoss == false) { | |
130 if (gpu_info.can_lose_context) | |
131 return false; | |
132 } | |
133 | |
134 attributes_ = attributes; | |
135 return true; | |
136 } | |
137 | |
138 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() { | |
139 if (context_) | |
140 return true; | |
141 if (initialize_failed_) | |
142 return false; | |
143 | |
144 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); | |
145 | |
146 // If the context is being initialized on something other than the main | |
147 // thread, then make sure the swap_client_ pointer is NULL so we don't | |
148 // accidentally dereference it. | |
149 GpuChannelHostFactory* factory = GpuChannelHostFactory::instance(); | |
150 if (!factory || !factory->IsMainThread()) | |
151 DCHECK(!swap_client_.get()); | |
152 | |
153 // Convert WebGL context creation attributes into RendererGLContext / EGL size | |
154 // requests. | |
155 const int alpha_size = attributes_.alpha ? 8 : 0; | |
156 const int depth_size = attributes_.depth ? 24 : 0; | |
157 const int stencil_size = attributes_.stencil ? 8 : 0; | |
158 const int samples = attributes_.antialias ? 4 : 0; | |
159 const int sample_buffers = attributes_.antialias ? 1 : 0; | |
160 const int32 attribs[] = { | |
161 RendererGLContext::ALPHA_SIZE, alpha_size, | |
162 RendererGLContext::DEPTH_SIZE, depth_size, | |
163 RendererGLContext::STENCIL_SIZE, stencil_size, | |
164 RendererGLContext::SAMPLES, samples, | |
165 RendererGLContext::SAMPLE_BUFFERS, sample_buffers, | |
166 RendererGLContext::SHARE_RESOURCES, attributes_.shareResources ? 1 : 0, | |
167 RendererGLContext::BIND_GENERATES_RESOURCES, 0, | |
168 RendererGLContext::NONE, | |
169 }; | |
170 | |
171 const char* preferred_extensions = "*"; | |
172 | |
173 // We need to lock g_all_shared_contexts until after RendererGLContext::Create | |
174 // to ensure that the context we picked for our share group isn't deleted. | |
175 // (There's also a lock in our destructor.) | |
176 { | |
177 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | |
178 RendererGLContext* share_group = NULL; | |
179 if (attributes_.shareResources) { | |
180 share_group = g_all_shared_contexts.Pointer()->empty() ? | |
181 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_; | |
182 } | |
183 | |
184 if (surface_id_) { | |
185 context_ = RendererGLContext::CreateViewContext( | |
186 host_, | |
187 surface_id_, | |
188 share_group, | |
189 preferred_extensions, | |
190 attribs, | |
191 active_url_, | |
192 gpu_preference_); | |
193 } else { | |
194 context_ = RendererGLContext::CreateOffscreenContext( | |
195 host_, | |
196 gfx::Size(1, 1), | |
197 share_group, | |
198 preferred_extensions, | |
199 attribs, | |
200 active_url_, | |
201 gpu_preference_); | |
202 } | |
203 } | |
204 | |
205 if (!context_) | |
206 return false; | |
207 | |
208 gl_ = context_->GetImplementation(); | |
209 | |
210 // TODO(twiz): This code is too fragile in that it assumes that only WebGL | |
211 // contexts will request noExtensions. | |
212 if (gl_ && attributes_.noExtensions) | |
213 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); | |
214 | |
215 context_->SetContextLostCallback( | |
216 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, | |
217 weak_ptr_factory_.GetWeakPtr())); | |
218 | |
219 // TODO(gman): Remove this. | |
220 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
221 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) { | |
222 context_->DisableShaderTranslation(); | |
223 } | |
224 | |
225 // Set attributes_ from created offscreen context. | |
226 { | |
227 GLint alpha_bits = 0; | |
228 getIntegerv(GL_ALPHA_BITS, &alpha_bits); | |
229 attributes_.alpha = alpha_bits > 0; | |
230 GLint depth_bits = 0; | |
231 getIntegerv(GL_DEPTH_BITS, &depth_bits); | |
232 attributes_.depth = depth_bits > 0; | |
233 GLint stencil_bits = 0; | |
234 getIntegerv(GL_STENCIL_BITS, &stencil_bits); | |
235 attributes_.stencil = stencil_bits > 0; | |
236 GLint samples = 0; | |
237 getIntegerv(GL_SAMPLES, &samples); | |
238 attributes_.antialias = samples > 0; | |
239 } | |
240 | |
241 if (attributes_.shareResources) { | |
242 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | |
243 g_all_shared_contexts.Pointer()->insert(this); | |
244 } | |
245 | |
246 return true; | |
247 } | |
248 | |
249 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { | |
250 if (!MaybeInitializeGL()) | |
251 return false; | |
252 return RendererGLContext::MakeCurrent(context_); | |
253 } | |
254 | |
255 int WebGraphicsContext3DCommandBufferImpl::width() { | |
256 return cached_width_; | |
257 } | |
258 | |
259 int WebGraphicsContext3DCommandBufferImpl::height() { | |
260 return cached_height_; | |
261 } | |
262 | |
263 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() { | |
264 return true; | |
265 } | |
266 | |
267 bool WebGraphicsContext3DCommandBufferImpl::setParentContext( | |
268 WebGraphicsContext3D* parent_context) { | |
269 WebGraphicsContext3DCommandBufferImpl* parent_context_impl = | |
270 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context); | |
271 return context_->SetParent( | |
272 parent_context_impl ? parent_context_impl->context() : NULL); | |
273 } | |
274 | |
275 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() { | |
276 return context_->GetParentTextureId(); | |
277 } | |
278 | |
279 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { | |
280 // Copies the contents of the off-screen render target into the texture | |
281 // used by the compositor. | |
282 if (swap_client_.get()) | |
283 swap_client_->OnViewContextSwapBuffersPosted(); | |
284 context_->SwapBuffers(); | |
285 context_->Echo(base::Bind( | |
286 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete, | |
287 weak_ptr_factory_.GetWeakPtr())); | |
288 #if defined(OS_MACOSX) | |
289 // It appears that making the compositor's on-screen context current on | |
290 // other platforms implies this flush. TODO(kbr): this means that the | |
291 // TOUCH build and, in the future, other platforms might need this. | |
292 gl_->Flush(); | |
293 #endif | |
294 } | |
295 | |
296 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM( | |
297 int x, int y, int width, int height) { | |
298 // Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture | |
299 // (see above). | |
300 if (swap_client_.get()) | |
301 swap_client_->OnViewContextSwapBuffersPosted(); | |
302 gl_->PostSubBufferCHROMIUM(x, y, width, height); | |
303 context_->Echo(base::Bind( | |
304 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete, | |
305 weak_ptr_factory_.GetWeakPtr())); | |
306 } | |
307 | |
308 void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) { | |
309 cached_width_ = width; | |
310 cached_height_ = height; | |
311 | |
312 gl_->ResizeCHROMIUM(width, height); | |
313 | |
314 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | |
315 scanline_.reset(new uint8[width * 4]); | |
316 #endif // FLIP_FRAMEBUFFER_VERTICALLY | |
317 } | |
318 | |
319 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | |
320 void WebGraphicsContext3DCommandBufferImpl::FlipVertically( | |
321 uint8* framebuffer, | |
322 unsigned int width, | |
323 unsigned int height) { | |
324 uint8* scanline = scanline_.get(); | |
325 if (!scanline) | |
326 return; | |
327 unsigned int row_bytes = width * 4; | |
328 unsigned int count = height / 2; | |
329 for (unsigned int i = 0; i < count; i++) { | |
330 uint8* row_a = framebuffer + i * row_bytes; | |
331 uint8* row_b = framebuffer + (height - i - 1) * row_bytes; | |
332 // TODO(kbr): this is where the multiplication of the alpha | |
333 // channel into the color buffer will need to occur if the | |
334 // user specifies the "premultiplyAlpha" flag in the context | |
335 // creation attributes. | |
336 memcpy(scanline, row_b, row_bytes); | |
337 memcpy(row_b, row_a, row_bytes); | |
338 memcpy(row_a, scanline, row_bytes); | |
339 } | |
340 } | |
341 #endif | |
342 | |
343 bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer( | |
344 unsigned char* pixels, | |
345 size_t buffer_size, | |
346 WebGLId buffer, | |
347 int width, | |
348 int height) { | |
349 if (buffer_size != static_cast<size_t>(4 * width * height)) { | |
350 return false; | |
351 } | |
352 | |
353 // Earlier versions of this code used the GPU to flip the | |
354 // framebuffer vertically before reading it back for compositing | |
355 // via software. This code was quite complicated, used a lot of | |
356 // GPU memory, and didn't provide an obvious speedup. Since this | |
357 // vertical flip is only a temporary solution anyway until Chrome | |
358 // is fully GPU composited, it wasn't worth the complexity. | |
359 | |
360 bool mustRestoreFBO = (bound_fbo_ != buffer); | |
361 if (mustRestoreFBO) { | |
362 gl_->BindFramebuffer(GL_FRAMEBUFFER, buffer); | |
363 } | |
364 gl_->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | |
365 | |
366 // Swizzle red and blue channels | |
367 // TODO(kbr): expose GL_BGRA as extension | |
368 for (size_t i = 0; i < buffer_size; i += 4) { | |
369 std::swap(pixels[i], pixels[i + 2]); | |
370 } | |
371 | |
372 if (mustRestoreFBO) { | |
373 gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_); | |
374 } | |
375 | |
376 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | |
377 if (pixels) { | |
378 FlipVertically(pixels, width, height); | |
379 } | |
380 #endif | |
381 | |
382 return true; | |
383 } | |
384 | |
385 bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer( | |
386 unsigned char* pixels, | |
387 size_t buffer_size) { | |
388 return readBackFramebuffer(pixels, buffer_size, 0, width(), height()); | |
389 } | |
390 | |
391 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError( | |
392 WGC3Denum error) { | |
393 if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == | |
394 synthetic_errors_.end()) { | |
395 synthetic_errors_.push_back(error); | |
396 } | |
397 } | |
398 | |
399 void* WebGraphicsContext3DCommandBufferImpl::mapBufferSubDataCHROMIUM( | |
400 WGC3Denum target, | |
401 WGC3Dintptr offset, | |
402 WGC3Dsizeiptr size, | |
403 WGC3Denum access) { | |
404 return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access); | |
405 } | |
406 | |
407 void WebGraphicsContext3DCommandBufferImpl::unmapBufferSubDataCHROMIUM( | |
408 const void* mem) { | |
409 return gl_->UnmapBufferSubDataCHROMIUM(mem); | |
410 } | |
411 | |
412 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM( | |
413 WGC3Denum target, | |
414 WGC3Dint level, | |
415 WGC3Dint xoffset, | |
416 WGC3Dint yoffset, | |
417 WGC3Dsizei width, | |
418 WGC3Dsizei height, | |
419 WGC3Denum format, | |
420 WGC3Denum type, | |
421 WGC3Denum access) { | |
422 return gl_->MapTexSubImage2DCHROMIUM( | |
423 target, level, xoffset, yoffset, width, height, format, type, access); | |
424 } | |
425 | |
426 void WebGraphicsContext3DCommandBufferImpl::unmapTexSubImage2DCHROMIUM( | |
427 const void* mem) { | |
428 gl_->UnmapTexSubImage2DCHROMIUM(mem); | |
429 } | |
430 | |
431 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM( | |
432 bool visible) { | |
433 gl_->Flush(); | |
434 context_->SetSurfaceVisible(visible); | |
435 if (!visible) | |
436 gl_->FreeEverything(); | |
437 } | |
438 | |
439 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM( | |
440 WebGLId texture, WebGLId parentTexture) { | |
441 NOTIMPLEMENTED(); | |
442 } | |
443 | |
444 void WebGraphicsContext3DCommandBufferImpl:: | |
445 rateLimitOffscreenContextCHROMIUM() { | |
446 gl_->RateLimitOffscreenContextCHROMIUM(); | |
447 } | |
448 | |
449 WebKit::WebString WebGraphicsContext3DCommandBufferImpl:: | |
450 getRequestableExtensionsCHROMIUM() { | |
451 return WebKit::WebString::fromUTF8( | |
452 gl_->GetRequestableExtensionsCHROMIUM()); | |
453 } | |
454 | |
455 void WebGraphicsContext3DCommandBufferImpl::requestExtensionCHROMIUM( | |
456 const char* extension) { | |
457 gl_->RequestExtensionCHROMIUM(extension); | |
458 } | |
459 | |
460 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM( | |
461 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, | |
462 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, | |
463 WGC3Dbitfield mask, WGC3Denum filter) { | |
464 gl_->BlitFramebufferEXT( | |
465 srcX0, srcY0, srcX1, srcY1, | |
466 dstX0, dstY0, dstX1, dstY1, | |
467 mask, filter); | |
468 } | |
469 | |
470 void WebGraphicsContext3DCommandBufferImpl:: | |
471 renderbufferStorageMultisampleCHROMIUM( | |
472 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, | |
473 WGC3Dsizei width, WGC3Dsizei height) { | |
474 gl_->RenderbufferStorageMultisampleEXT( | |
475 target, samples, internalformat, width, height); | |
476 } | |
477 | |
478 // Helper macros to reduce the amount of code. | |
479 | |
480 #define DELEGATE_TO_GL(name, glname) \ | |
481 void WebGraphicsContext3DCommandBufferImpl::name() { \ | |
482 gl_->glname(); \ | |
483 } | |
484 | |
485 #define DELEGATE_TO_GL_1(name, glname, t1) \ | |
486 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ | |
487 gl_->glname(a1); \ | |
488 } | |
489 | |
490 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ | |
491 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ | |
492 return gl_->glname(a1); \ | |
493 } | |
494 | |
495 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ | |
496 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ | |
497 return gl_->glname(a1) ? true : false; \ | |
498 } | |
499 | |
500 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ | |
501 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \ | |
502 gl_->glname(a1, a2); \ | |
503 } | |
504 | |
505 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ | |
506 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \ | |
507 return gl_->glname(a1, a2); \ | |
508 } | |
509 | |
510 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ | |
511 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ | |
512 gl_->glname(a1, a2, a3); \ | |
513 } | |
514 | |
515 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ | |
516 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) { \ | |
517 gl_->glname(a1, a2, a3, a4); \ | |
518 } | |
519 | |
520 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ | |
521 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ | |
522 t4 a4, t5 a5) { \ | |
523 gl_->glname(a1, a2, a3, a4, a5); \ | |
524 } | |
525 | |
526 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ | |
527 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ | |
528 t4 a4, t5 a5, t6 a6) { \ | |
529 gl_->glname(a1, a2, a3, a4, a5, a6); \ | |
530 } | |
531 | |
532 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ | |
533 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ | |
534 t4 a4, t5 a5, t6 a6, t7 a7) { \ | |
535 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \ | |
536 } | |
537 | |
538 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ | |
539 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ | |
540 t4 a4, t5 a5, t6 a6, \ | |
541 t7 a7, t8 a8) { \ | |
542 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \ | |
543 } | |
544 | |
545 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ | |
546 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ | |
547 t4 a4, t5 a5, t6 a6, \ | |
548 t7 a7, t8 a8, t9 a9) { \ | |
549 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | |
550 } | |
551 | |
552 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum) | |
553 | |
554 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) | |
555 | |
556 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, | |
557 WGC3Duint, const WGC3Dchar*) | |
558 | |
559 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId) | |
560 | |
561 void WebGraphicsContext3DCommandBufferImpl::bindFramebuffer( | |
562 WGC3Denum target, | |
563 WebGLId framebuffer) { | |
564 gl_->BindFramebuffer(target, framebuffer); | |
565 bound_fbo_ = framebuffer; | |
566 } | |
567 | |
568 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId) | |
569 | |
570 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId) | |
571 | |
572 DELEGATE_TO_GL_4(blendColor, BlendColor, | |
573 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) | |
574 | |
575 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) | |
576 | |
577 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, | |
578 WGC3Denum, WGC3Denum) | |
579 | |
580 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) | |
581 | |
582 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, | |
583 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) | |
584 | |
585 DELEGATE_TO_GL_4(bufferData, BufferData, | |
586 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) | |
587 | |
588 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, | |
589 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) | |
590 | |
591 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus, | |
592 WGC3Denum, WGC3Denum) | |
593 | |
594 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) | |
595 | |
596 DELEGATE_TO_GL_4(clearColor, ClearColor, | |
597 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) | |
598 | |
599 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf) | |
600 | |
601 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) | |
602 | |
603 DELEGATE_TO_GL_4(colorMask, ColorMask, | |
604 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) | |
605 | |
606 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) | |
607 | |
608 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D, | |
609 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, | |
610 WGC3Dsizei, WGC3Dsizei, const void*) | |
611 | |
612 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D, | |
613 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, | |
614 WGC3Denum, WGC3Dsizei, const void*) | |
615 | |
616 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D, | |
617 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, | |
618 WGC3Dsizei, WGC3Dsizei, WGC3Dint) | |
619 | |
620 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D, | |
621 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, | |
622 WGC3Dsizei, WGC3Dsizei) | |
623 | |
624 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) | |
625 | |
626 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) | |
627 | |
628 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) | |
629 | |
630 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf) | |
631 | |
632 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) | |
633 | |
634 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) | |
635 | |
636 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, | |
637 WGC3Duint) | |
638 | |
639 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) | |
640 | |
641 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode, | |
642 WGC3Dsizei count, | |
643 WGC3Denum type, | |
644 WGC3Dintptr offset) { | |
645 gl_->DrawElements( | |
646 mode, count, type, | |
647 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); | |
648 } | |
649 | |
650 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) | |
651 | |
652 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, | |
653 WGC3Duint) | |
654 | |
655 DELEGATE_TO_GL(finish, Finish) | |
656 | |
657 DELEGATE_TO_GL(flush, Flush) | |
658 | |
659 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer, | |
660 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) | |
661 | |
662 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D, | |
663 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) | |
664 | |
665 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) | |
666 | |
667 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum) | |
668 | |
669 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib( | |
670 WebGLId program, WGC3Duint index, ActiveInfo& info) { | |
671 if (!program) { | |
672 synthesizeGLError(GL_INVALID_VALUE); | |
673 return false; | |
674 } | |
675 GLint max_name_length = -1; | |
676 gl_->GetProgramiv( | |
677 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); | |
678 if (max_name_length < 0) | |
679 return false; | |
680 scoped_array<GLchar> name(new GLchar[max_name_length]); | |
681 if (!name.get()) { | |
682 synthesizeGLError(GL_OUT_OF_MEMORY); | |
683 return false; | |
684 } | |
685 GLsizei length = 0; | |
686 GLint size = -1; | |
687 GLenum type = 0; | |
688 gl_->GetActiveAttrib( | |
689 program, index, max_name_length, &length, &size, &type, name.get()); | |
690 if (size < 0) { | |
691 return false; | |
692 } | |
693 info.name = WebKit::WebString::fromUTF8(name.get(), length); | |
694 info.type = type; | |
695 info.size = size; | |
696 return true; | |
697 } | |
698 | |
699 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform( | |
700 WebGLId program, WGC3Duint index, ActiveInfo& info) { | |
701 GLint max_name_length = -1; | |
702 gl_->GetProgramiv( | |
703 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); | |
704 if (max_name_length < 0) | |
705 return false; | |
706 scoped_array<GLchar> name(new GLchar[max_name_length]); | |
707 if (!name.get()) { | |
708 synthesizeGLError(GL_OUT_OF_MEMORY); | |
709 return false; | |
710 } | |
711 GLsizei length = 0; | |
712 GLint size = -1; | |
713 GLenum type = 0; | |
714 gl_->GetActiveUniform( | |
715 program, index, max_name_length, &length, &size, &type, name.get()); | |
716 if (size < 0) { | |
717 return false; | |
718 } | |
719 info.name = WebKit::WebString::fromUTF8(name.get(), length); | |
720 info.type = type; | |
721 info.size = size; | |
722 return true; | |
723 } | |
724 | |
725 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, | |
726 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) | |
727 | |
728 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, | |
729 WebGLId, const WGC3Dchar*, WGC3Dint) | |
730 | |
731 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*) | |
732 | |
733 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, | |
734 WGC3Denum, WGC3Denum, WGC3Dint*) | |
735 | |
736 WebKit::WebGraphicsContext3D::Attributes | |
737 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() { | |
738 return attributes_; | |
739 } | |
740 | |
741 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() { | |
742 if (!synthetic_errors_.empty()) { | |
743 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); | |
744 WGC3Denum err = *iter; | |
745 synthetic_errors_.erase(iter); | |
746 return err; | |
747 } | |
748 | |
749 return gl_->GetError(); | |
750 } | |
751 | |
752 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() { | |
753 return initialize_failed_ || | |
754 (context_ && context_->IsCommandBufferContextLost()) || | |
755 context_lost_reason_ != GL_NO_ERROR; | |
756 } | |
757 | |
758 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) | |
759 | |
760 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, | |
761 GetFramebufferAttachmentParameteriv, | |
762 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) | |
763 | |
764 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) | |
765 | |
766 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) | |
767 | |
768 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog( | |
769 WebGLId program) { | |
770 GLint logLength = 0; | |
771 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); | |
772 if (!logLength) | |
773 return WebKit::WebString(); | |
774 scoped_array<GLchar> log(new GLchar[logLength]); | |
775 if (!log.get()) | |
776 return WebKit::WebString(); | |
777 GLsizei returnedLogLength = 0; | |
778 gl_->GetProgramInfoLog( | |
779 program, logLength, &returnedLogLength, log.get()); | |
780 DCHECK_EQ(logLength, returnedLogLength + 1); | |
781 WebKit::WebString res = | |
782 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); | |
783 return res; | |
784 } | |
785 | |
786 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv, | |
787 WGC3Denum, WGC3Denum, WGC3Dint*) | |
788 | |
789 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*) | |
790 | |
791 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog( | |
792 WebGLId shader) { | |
793 GLint logLength = 0; | |
794 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); | |
795 if (!logLength) | |
796 return WebKit::WebString(); | |
797 scoped_array<GLchar> log(new GLchar[logLength]); | |
798 if (!log.get()) | |
799 return WebKit::WebString(); | |
800 GLsizei returnedLogLength = 0; | |
801 gl_->GetShaderInfoLog( | |
802 shader, logLength, &returnedLogLength, log.get()); | |
803 DCHECK_EQ(logLength, returnedLogLength + 1); | |
804 WebKit::WebString res = | |
805 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); | |
806 return res; | |
807 } | |
808 | |
809 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource( | |
810 WebGLId shader) { | |
811 GLint logLength = 0; | |
812 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); | |
813 if (!logLength) | |
814 return WebKit::WebString(); | |
815 scoped_array<GLchar> log(new GLchar[logLength]); | |
816 if (!log.get()) | |
817 return WebKit::WebString(); | |
818 GLsizei returnedLogLength = 0; | |
819 gl_->GetShaderSource( | |
820 shader, logLength, &returnedLogLength, log.get()); | |
821 if (!returnedLogLength) | |
822 return WebKit::WebString(); | |
823 DCHECK_EQ(logLength, returnedLogLength + 1); | |
824 WebKit::WebString res = | |
825 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); | |
826 return res; | |
827 } | |
828 | |
829 WebKit::WebString WebGraphicsContext3DCommandBufferImpl:: | |
830 getTranslatedShaderSourceANGLE(WebGLId shader) { | |
831 GLint logLength = 0; | |
832 gl_->GetShaderiv( | |
833 shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength); | |
834 if (!logLength) | |
835 return WebKit::WebString(); | |
836 scoped_array<GLchar> log(new GLchar[logLength]); | |
837 if (!log.get()) | |
838 return WebKit::WebString(); | |
839 GLsizei returnedLogLength = 0; | |
840 gl_->GetTranslatedShaderSourceANGLE( | |
841 shader, logLength, &returnedLogLength, log.get()); | |
842 if (!returnedLogLength) | |
843 return WebKit::WebString(); | |
844 DCHECK_EQ(logLength, returnedLogLength + 1); | |
845 WebKit::WebString res = | |
846 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); | |
847 return res; | |
848 } | |
849 | |
850 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getString( | |
851 WGC3Denum name) { | |
852 return WebKit::WebString::fromUTF8( | |
853 reinterpret_cast<const char*>(gl_->GetString(name))); | |
854 } | |
855 | |
856 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, | |
857 WGC3Denum, WGC3Denum, WGC3Dfloat*) | |
858 | |
859 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, | |
860 WGC3Denum, WGC3Denum, WGC3Dint*) | |
861 | |
862 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) | |
863 | |
864 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) | |
865 | |
866 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, | |
867 WebGLId, const WGC3Dchar*, WGC3Dint) | |
868 | |
869 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, | |
870 WGC3Duint, WGC3Denum, WGC3Dfloat*) | |
871 | |
872 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, | |
873 WGC3Duint, WGC3Denum, WGC3Dint*) | |
874 | |
875 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset( | |
876 WGC3Duint index, WGC3Denum pname) { | |
877 GLvoid* value = NULL; | |
878 // NOTE: If pname is ever a value that returns more then 1 element | |
879 // this will corrupt memory. | |
880 gl_->GetVertexAttribPointerv(index, pname, &value); | |
881 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value)); | |
882 } | |
883 | |
884 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) | |
885 | |
886 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) | |
887 | |
888 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) | |
889 | |
890 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean) | |
891 | |
892 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) | |
893 | |
894 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean) | |
895 | |
896 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) | |
897 | |
898 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) | |
899 | |
900 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) | |
901 | |
902 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) | |
903 | |
904 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) | |
905 | |
906 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) | |
907 | |
908 DELEGATE_TO_GL_7(readPixels, ReadPixels, | |
909 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum, | |
910 WGC3Denum, void*) | |
911 | |
912 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() { | |
913 } | |
914 | |
915 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage, | |
916 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei) | |
917 | |
918 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean) | |
919 | |
920 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) | |
921 | |
922 void WebGraphicsContext3DCommandBufferImpl::shaderSource( | |
923 WebGLId shader, const WGC3Dchar* string) { | |
924 GLint length = strlen(string); | |
925 gl_->ShaderSource(shader, 1, &string, &length); | |
926 } | |
927 | |
928 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) | |
929 | |
930 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, | |
931 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) | |
932 | |
933 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) | |
934 | |
935 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, | |
936 WGC3Denum, WGC3Duint) | |
937 | |
938 DELEGATE_TO_GL_3(stencilOp, StencilOp, | |
939 WGC3Denum, WGC3Denum, WGC3Denum) | |
940 | |
941 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, | |
942 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) | |
943 | |
944 DELEGATE_TO_GL_9(texImage2D, TexImage2D, | |
945 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, | |
946 WGC3Dint, WGC3Denum, WGC3Denum, const void*) | |
947 | |
948 DELEGATE_TO_GL_3(texParameterf, TexParameterf, | |
949 WGC3Denum, WGC3Denum, WGC3Dfloat); | |
950 | |
951 static const unsigned int kTextureWrapR = 0x8072; | |
952 | |
953 void WebGraphicsContext3DCommandBufferImpl::texParameteri( | |
954 WGC3Denum target, WGC3Denum pname, WGC3Dint param) { | |
955 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in | |
956 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the | |
957 // edge of cube maps, and, if it is, push it into the GLES2 service | |
958 // side code. | |
959 if (pname == kTextureWrapR) { | |
960 return; | |
961 } | |
962 gl_->TexParameteri(target, pname, param); | |
963 } | |
964 | |
965 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, | |
966 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, | |
967 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) | |
968 | |
969 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) | |
970 | |
971 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei, | |
972 const WGC3Dfloat*) | |
973 | |
974 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) | |
975 | |
976 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | |
977 | |
978 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) | |
979 | |
980 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei, | |
981 const WGC3Dfloat*) | |
982 | |
983 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) | |
984 | |
985 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | |
986 | |
987 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint, | |
988 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | |
989 | |
990 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei, | |
991 const WGC3Dfloat*) | |
992 | |
993 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) | |
994 | |
995 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | |
996 | |
997 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, | |
998 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | |
999 | |
1000 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei, | |
1001 const WGC3Dfloat*) | |
1002 | |
1003 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, | |
1004 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) | |
1005 | |
1006 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | |
1007 | |
1008 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, | |
1009 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | |
1010 | |
1011 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, | |
1012 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | |
1013 | |
1014 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, | |
1015 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | |
1016 | |
1017 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) | |
1018 | |
1019 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) | |
1020 | |
1021 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) | |
1022 | |
1023 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, | |
1024 const WGC3Dfloat*) | |
1025 | |
1026 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint, | |
1027 WGC3Dfloat, WGC3Dfloat) | |
1028 | |
1029 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, | |
1030 const WGC3Dfloat*) | |
1031 | |
1032 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint, | |
1033 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | |
1034 | |
1035 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, | |
1036 const WGC3Dfloat*) | |
1037 | |
1038 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint, | |
1039 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | |
1040 | |
1041 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, | |
1042 const WGC3Dfloat*) | |
1043 | |
1044 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer( | |
1045 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, | |
1046 WGC3Dsizei stride, WGC3Dintptr offset) { | |
1047 gl_->VertexAttribPointer( | |
1048 index, size, type, normalized, stride, | |
1049 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); | |
1050 } | |
1051 | |
1052 DELEGATE_TO_GL_4(viewport, Viewport, | |
1053 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) | |
1054 | |
1055 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() { | |
1056 GLuint o; | |
1057 gl_->GenBuffers(1, &o); | |
1058 return o; | |
1059 } | |
1060 | |
1061 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() { | |
1062 GLuint o = 0; | |
1063 gl_->GenFramebuffers(1, &o); | |
1064 return o; | |
1065 } | |
1066 | |
1067 WebGLId WebGraphicsContext3DCommandBufferImpl::createProgram() { | |
1068 return gl_->CreateProgram(); | |
1069 } | |
1070 | |
1071 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() { | |
1072 GLuint o; | |
1073 gl_->GenRenderbuffers(1, &o); | |
1074 return o; | |
1075 } | |
1076 | |
1077 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId); | |
1078 | |
1079 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() { | |
1080 GLuint o; | |
1081 gl_->GenTextures(1, &o); | |
1082 return o; | |
1083 } | |
1084 | |
1085 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) { | |
1086 gl_->DeleteBuffers(1, &buffer); | |
1087 } | |
1088 | |
1089 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer( | |
1090 WebGLId framebuffer) { | |
1091 gl_->DeleteFramebuffers(1, &framebuffer); | |
1092 } | |
1093 | |
1094 void WebGraphicsContext3DCommandBufferImpl::deleteProgram(WebGLId program) { | |
1095 gl_->DeleteProgram(program); | |
1096 } | |
1097 | |
1098 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer( | |
1099 WebGLId renderbuffer) { | |
1100 gl_->DeleteRenderbuffers(1, &renderbuffer); | |
1101 } | |
1102 | |
1103 void WebGraphicsContext3DCommandBufferImpl::deleteShader(WebGLId shader) { | |
1104 gl_->DeleteShader(shader); | |
1105 } | |
1106 | |
1107 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) { | |
1108 gl_->DeleteTextures(1, &texture); | |
1109 } | |
1110 | |
1111 void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() { | |
1112 typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient; | |
1113 // This may be called after tear-down of the RenderView. | |
1114 if (swap_client_.get()) { | |
1115 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | |
1116 &WGC3DSwapClient::OnViewContextSwapBuffersComplete, swap_client_)); | |
1117 } | |
1118 | |
1119 if (swapbuffers_complete_callback_) | |
1120 swapbuffers_complete_callback_->onSwapBuffersComplete(); | |
1121 } | |
1122 | |
1123 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback( | |
1124 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) { | |
1125 context_lost_callback_ = cb; | |
1126 } | |
1127 | |
1128 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() { | |
1129 if (context_->IsCommandBufferContextLost() && | |
1130 context_lost_reason_ == GL_NO_ERROR) { | |
1131 return GL_UNKNOWN_CONTEXT_RESET_ARB; | |
1132 } | |
1133 | |
1134 return context_lost_reason_; | |
1135 } | |
1136 | |
1137 void WebGraphicsContext3DCommandBufferImpl:: | |
1138 setSwapBuffersCompleteCallbackCHROMIUM( | |
1139 WebGraphicsContext3D::WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* cb) { | |
1140 swapbuffers_complete_callback_ = cb; | |
1141 } | |
1142 | |
1143 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, | |
1144 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) | |
1145 | |
1146 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, | |
1147 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) | |
1148 | |
1149 #if WEBKIT_USING_SKIA | |
1150 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::onCreateGrGLInterface() { | |
1151 return webkit_glue::CreateCommandBufferSkiaGLBinding(); | |
1152 } | |
1153 #endif | |
1154 | |
1155 namespace { | |
1156 | |
1157 WGC3Denum convertReason(RendererGLContext::ContextLostReason reason) { | |
1158 switch (reason) { | |
1159 case RendererGLContext::kGuilty: | |
1160 return GL_GUILTY_CONTEXT_RESET_ARB; | |
1161 case RendererGLContext::kInnocent: | |
1162 return GL_INNOCENT_CONTEXT_RESET_ARB; | |
1163 case RendererGLContext::kUnknown: | |
1164 return GL_UNKNOWN_CONTEXT_RESET_ARB; | |
1165 } | |
1166 | |
1167 NOTREACHED(); | |
1168 return GL_UNKNOWN_CONTEXT_RESET_ARB; | |
1169 } | |
1170 | |
1171 } // anonymous namespace | |
1172 | |
1173 void WebGraphicsContext3DCommandBufferImpl::OnContextLost( | |
1174 RendererGLContext::ContextLostReason reason) { | |
1175 context_lost_reason_ = convertReason(reason); | |
1176 if (context_lost_callback_) { | |
1177 context_lost_callback_->onContextLost(); | |
1178 } | |
1179 if (attributes_.shareResources) | |
1180 ClearSharedContexts(); | |
1181 if (swap_client_.get()) | |
1182 swap_client_->OnViewContextSwapBuffersAborted(); | |
1183 } | |
OLD | NEW |