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.
5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
7 #include "third_party/khronos/GLES2/gl2.h"
8 #ifndef GL_GLEXT_PROTOTYPES
9 #define GL_GLEXT_PROTOTYPES 1
11 #include "third_party/khronos/GLES2/gl2ext.h"
16 #include "base/atomicops.h"
17 #include "base/bind.h"
18 #include "base/command_line.h"
19 #include "base/debug/trace_event.h"
20 #include "base/lazy_instance.h"
21 #include "base/logging.h"
22 #include "base/message_loop/message_loop.h"
23 #include "base/metrics/field_trial.h"
24 #include "base/metrics/histogram.h"
25 #include "base/synchronization/lock.h"
26 #include "content/common/gpu/client/gpu_channel_host.h"
27 #include "content/public/common/content_constants.h"
28 #include "content/public/common/content_switches.h"
29 #include "gpu/GLES2/gl2extchromium.h"
30 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
31 #include "gpu/command_buffer/client/gles2_implementation.h"
32 #include "gpu/command_buffer/client/gles2_lib.h"
33 #include "gpu/command_buffer/client/gles2_trace_implementation.h"
34 #include "gpu/command_buffer/client/transfer_buffer.h"
35 #include "gpu/command_buffer/common/constants.h"
36 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
37 #include "gpu/command_buffer/common/mailbox.h"
38 #include "third_party/skia/include/core/SkTypes.h"
39 #include "webkit/common/gpu/gl_bindings_skia_cmd_buffer.h"
42 static base::LazyInstance<base::Lock>::Leaky
43 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
44 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
45 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
47 static base::LazyInstance<base::Lock>::Leaky
48 g_all_shared_contexts_browser_lock = LAZY_INSTANCE_INITIALIZER;
49 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
50 g_all_shared_contexts_browser = LAZY_INSTANCE_INITIALIZER;
54 void ClearSharedContextsIfInShareSet(
55 WebGraphicsContext3DCommandBufferImpl* context) {
56 // If the given context isn't in the share set, that means that it
57 // or another context it was previously sharing with already
58 // provoked a lost context. Other contexts might have since been
59 // successfully created and added to the share set, so do not clear
60 // out the share set unless we know that all the contexts in there
61 // are supposed to be lost simultaneously.
62 base::AutoLock lock(g_all_shared_contexts_lock.Get());
63 std::set<WebGraphicsContext3DCommandBufferImpl*>* share_set =
64 g_all_shared_contexts.Pointer();
65 for (std::set<WebGraphicsContext3DCommandBufferImpl*>::iterator iter =
66 share_set->begin(); iter != share_set->end(); ++iter) {
67 if (context == *iter) {
74 void ClearSharedContextsIfInShareSetBrowser(
75 WebGraphicsContext3DCommandBufferImpl* context) {
76 // If the given context isn't in the share set, that means that it
77 // or another context it was previously sharing with already
78 // provoked a lost context. Other contexts might have since been
79 // successfully created and added to the share set, so do not clear
80 // out the share set unless we know that all the contexts in there
81 // are supposed to be lost simultaneously.
82 base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
83 std::set<WebGraphicsContext3DCommandBufferImpl*>* share_set =
84 g_all_shared_contexts_browser.Pointer();
85 for (std::set<WebGraphicsContext3DCommandBufferImpl*>::iterator iter =
86 share_set->begin(); iter != share_set->end(); ++iter) {
87 if (context == *iter) {
94 size_t ClampUint64ToSizeT(uint64 value) {
95 value = std::min(value,
96 static_cast<uint64>(std::numeric_limits<size_t>::max()));
97 return static_cast<size_t>(value);
100 uint32_t GenFlushID() {
101 static base::subtle::Atomic32 flush_id = 0;
103 base::subtle::Atomic32 my_id = base::subtle::Barrier_AtomicIncrement(
105 return static_cast<uint32_t>(my_id);
108 // Singleton used to initialize and terminate the gles2 library.
109 class GLES2Initializer {
115 ~GLES2Initializer() {
120 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
123 ////////////////////////////////////////////////////////////////////////////////
125 base::LazyInstance<GLES2Initializer> g_gles2_initializer =
126 LAZY_INSTANCE_INITIALIZER;
128 ////////////////////////////////////////////////////////////////////////////////
130 } // namespace anonymous
132 // Helper macros to reduce the amount of code.
134 #define DELEGATE_TO_GL(name, glname) \
135 void WebGraphicsContext3DCommandBufferImpl::name() { \
139 #define DELEGATE_TO_GL_R(name, glname, rt) \
140 rt WebGraphicsContext3DCommandBufferImpl::name() { \
141 return gl_->glname(); \
144 #define DELEGATE_TO_GL_1(name, glname, t1) \
145 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \
149 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \
150 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \
151 return gl_->glname(a1); \
154 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \
155 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \
156 return gl_->glname(a1) ? true : false; \
159 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \
160 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \
161 gl_->glname(a1, a2); \
164 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \
165 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \
166 return gl_->glname(a1, a2); \
169 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \
170 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \
171 gl_->glname(a1, a2, a3); \
174 #define DELEGATE_TO_GL_3R(name, glname, t1, t2, t3, rt) \
175 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \
176 return gl_->glname(a1, a2, a3); \
179 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \
180 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
182 gl_->glname(a1, a2, a3, a4); \
185 #define DELEGATE_TO_GL_4R(name, glname, t1, t2, t3, t4, rt) \
186 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
188 return gl_->glname(a1, a2, a3, a4); \
191 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \
192 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
194 gl_->glname(a1, a2, a3, a4, a5); \
197 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \
198 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
199 t4 a4, t5 a5, t6 a6) { \
200 gl_->glname(a1, a2, a3, a4, a5, a6); \
203 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \
204 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
205 t4 a4, t5 a5, t6 a6, \
207 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \
210 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \
211 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
212 t4 a4, t5 a5, t6 a6, \
214 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \
217 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
218 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \
219 t4 a4, t5 a5, t6 a6, \
220 t7 a7, t8 a8, t9 a9) { \
221 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
224 class WebGraphicsContext3DErrorMessageCallback
225 : public gpu::gles2::GLES2Implementation::ErrorMessageCallback {
227 WebGraphicsContext3DErrorMessageCallback(
228 WebGraphicsContext3DCommandBufferImpl* context)
229 : graphics_context_(context) {
232 virtual void OnErrorMessage(const char* msg, int id) OVERRIDE;
235 WebGraphicsContext3DCommandBufferImpl* graphics_context_;
237 DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DErrorMessageCallback);
240 void WebGraphicsContext3DErrorMessageCallback::OnErrorMessage(
241 const char* msg, int id) {
242 graphics_context_->OnErrorMessage(msg, id);
245 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits()
246 : command_buffer_size(kDefaultCommandBufferSize),
247 start_transfer_buffer_size(kDefaultStartTransferBufferSize),
248 min_transfer_buffer_size(kDefaultMinTransferBufferSize),
249 max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
250 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {}
252 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
254 const GURL& active_url,
255 GpuChannelHost* host,
256 const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
257 const Attributes& attributes,
258 bool bind_generates_resources,
259 const SharedMemoryLimits& limits,
260 bool context_for_browser_compositor)
261 : initialize_failed_(false),
263 free_command_buffer_when_invisible_(false),
265 surface_id_(surface_id),
266 active_url_(active_url),
267 swap_client_(swap_client),
268 context_lost_callback_(0),
269 context_lost_reason_(GL_NO_ERROR),
270 error_message_callback_(0),
271 swapbuffers_complete_callback_(0),
272 attributes_(attributes),
273 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu
274 : gfx::PreferIntegratedGpu),
275 weak_ptr_factory_(this),
279 bind_generates_resources_(bind_generates_resources),
280 use_echo_for_swap_ack_(true),
282 context_for_browser_compositor_(context_for_browser_compositor),
284 #if (defined(OS_MACOSX) || defined(OS_WIN)) && !defined(USE_AURA)
285 // Get ViewMsg_SwapBuffers_ACK from browser for single-threaded path.
286 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
287 use_echo_for_swap_ack_ =
288 command_line.HasSwitch(switches::kEnableThreadedCompositing);
292 WebGraphicsContext3DCommandBufferImpl::
293 ~WebGraphicsContext3DCommandBufferImpl() {
295 real_gl_->SetErrorMessageCallback(NULL);
298 if (context_for_browser_compositor_) {
299 base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
300 g_all_shared_contexts_browser.Pointer()->erase(this);
302 base::AutoLock lock(g_all_shared_contexts_lock.Get());
303 g_all_shared_contexts.Pointer()->erase(this);
308 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
312 if (initialize_failed_)
315 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
317 if (!CreateContext(surface_id_ != 0)) {
319 initialize_failed_ = true;
323 // TODO(twiz): This code is too fragile in that it assumes that only WebGL
324 // contexts will request noExtensions.
325 if (gl_ && attributes_.noExtensions)
326 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation");
328 command_buffer_->SetChannelErrorCallback(
329 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost,
330 weak_ptr_factory_.GetWeakPtr()));
332 command_buffer_->SetOnConsoleMessageCallback(
333 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnErrorMessage,
334 weak_ptr_factory_.GetWeakPtr()));
336 client_error_message_callback_.reset(
337 new WebGraphicsContext3DErrorMessageCallback(this));
338 real_gl_->SetErrorMessageCallback(client_error_message_callback_.get());
340 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
341 free_command_buffer_when_invisible_ =
342 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers);
344 // Set attributes_ from created offscreen context.
346 static const int pcount = 4;
347 static const GLenum pnames[pcount] = {
353 GLint pvalues[pcount] = { 0, 0, 0, 0 };
355 gl_->GetMultipleIntegervCHROMIUM(pnames, pcount,
356 pvalues, sizeof(pvalues));
358 attributes_.alpha = pvalues[0] > 0;
359 attributes_.depth = pvalues[1] > 0;
360 attributes_.stencil = pvalues[2] > 0;
361 attributes_.antialias = pvalues[3] > 0;
369 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
373 // We need to lock g_all_shared_contexts to ensure that the context we picked
374 // for our share group isn't deleted.
375 // (There's also a lock in our destructor.)
376 CommandBufferProxyImpl* share_group = NULL;
377 if (attributes_.shareResources) {
378 if (context_for_browser_compositor_) {
379 base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
380 WebGraphicsContext3DCommandBufferImpl* share_group_context =
381 g_all_shared_contexts_browser.Pointer()->empty() ?
382 NULL : *g_all_shared_contexts_browser.Pointer()->begin();
383 share_group = share_group_context ?
384 share_group_context->command_buffer_.get() : NULL;
386 base::AutoLock lock(g_all_shared_contexts_lock.Get());
387 WebGraphicsContext3DCommandBufferImpl* share_group_context =
388 g_all_shared_contexts.Pointer()->empty() ?
389 NULL : *g_all_shared_contexts.Pointer()->begin();
390 share_group = share_group_context ?
391 share_group_context->command_buffer_.get() : NULL;
395 std::vector<int32> attribs;
396 attribs.push_back(ALPHA_SIZE);
397 attribs.push_back(attributes_.alpha ? 8 : 0);
398 attribs.push_back(DEPTH_SIZE);
399 attribs.push_back(attributes_.depth ? 24 : 0);
400 attribs.push_back(STENCIL_SIZE);
401 attribs.push_back(attributes_.stencil ? 8 : 0);
402 attribs.push_back(SAMPLES);
403 attribs.push_back(attributes_.antialias ? 4 : 0);
404 attribs.push_back(SAMPLE_BUFFERS);
405 attribs.push_back(attributes_.antialias ? 1 : 0);
406 attribs.push_back(NONE);
408 // Create a proxy to a command buffer in the GPU process.
410 command_buffer_.reset(host_->CreateViewCommandBuffer(
417 command_buffer_.reset(host_->CreateOffscreenCommandBuffer(
425 if (!command_buffer_)
428 // Initialize the command buffer.
429 return command_buffer_->Initialize();
432 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
434 // Ensure the gles2 library is initialized first in a thread safe way.
435 g_gles2_initializer.Get();
437 if (!command_buffer_ &&
438 !InitializeCommandBuffer(onscreen)) {
442 // Create the GLES2 helper, which writes the command buffer protocol.
443 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
444 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size))
447 if (attributes_.noAutomaticFlushes)
448 gles2_helper_->SetAutomaticFlushes(false);
450 // Create a transfer buffer used to copy resources between the renderer
451 // process and the GPU process.
452 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get()));
454 scoped_ptr<base::AutoLock> lock;
455 scoped_refptr<gpu::gles2::ShareGroup> share_group;
456 if (attributes_.shareResources) {
457 // Make sure two clients don't try to create a new ShareGroup
459 if (context_for_browser_compositor_) {
460 lock.reset(new base::AutoLock(g_all_shared_contexts_browser_lock.Get()));
461 if (!g_all_shared_contexts_browser.Pointer()->empty()) {
462 share_group = (*g_all_shared_contexts_browser.Pointer()->begin())
463 ->GetImplementation()->share_group();
467 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
468 if (!g_all_shared_contexts.Pointer()->empty()) {
469 share_group = (*g_all_shared_contexts.Pointer()->begin())
470 ->GetImplementation()->share_group();
476 // Create the object exposing the OpenGL API.
477 real_gl_.reset(new gpu::gles2::GLES2Implementation(
480 transfer_buffer_.get(),
481 bind_generates_resources_,
482 command_buffer_.get()));
483 gl_ = real_gl_.get();
485 if (attributes_.shareResources) {
486 // Don't add ourselves to the list before others can get to our ShareGroup.
487 if (context_for_browser_compositor_) {
488 g_all_shared_contexts_browser.Pointer()->insert(this);
490 g_all_shared_contexts.Pointer()->insert(this);
495 if (!real_gl_->Initialize(
496 mem_limits_.start_transfer_buffer_size,
497 mem_limits_.min_transfer_buffer_size,
498 mem_limits_.max_transfer_buffer_size,
499 mem_limits_.mapped_memory_reclaim_limit)) {
503 if (CommandLine::ForCurrentProcess()->HasSwitch(
504 switches::kEnableGpuClientTracing)) {
505 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_));
506 gl_ = trace_gl_.get();
512 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
513 if (!MaybeInitializeGL())
515 gles2::SetGLContext(gl_);
516 if (command_buffer_->GetLastError() != gpu::error::kNoError)
522 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() {
526 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int)
528 void WebGraphicsContext3DCommandBufferImpl::Destroy() {
530 // First flush the context to ensure that any pending frees of resources
531 // are completed. Otherwise, if this context is part of a share group,
532 // those resources might leak. Also, any remaining side effects of commands
533 // issued on this context might not be visible to other contexts in the
541 transfer_buffer_.reset();
542 gles2_helper_.reset();
545 if (command_buffer_) {
547 host_->DestroyCommandBuffer(command_buffer_.release());
548 command_buffer_.reset();
554 // TODO(apatrick,piman): This should be renamed to something clearer.
555 int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() {
556 return host_.get() ? host_->gpu_host_id() : 0;
559 int WebGraphicsContext3DCommandBufferImpl::GetChannelID() {
560 return host_.get() ? host_->client_id() : 0;
563 int WebGraphicsContext3DCommandBufferImpl::GetContextID() {
564 return command_buffer_->GetRouteID();
568 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() {
569 return real_gl_.get();
572 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
574 "WebGraphicsContext3DCommandBufferImpl::SwapBuffers",
575 "frame", frame_number_);
577 // Copies the contents of the off-screen render target into the texture
578 // used by the compositor.
579 if (ShouldUseSwapClient())
580 swap_client_->OnViewContextSwapBuffersPosted();
582 if (command_buffer_->GetLastState().error == gpu::error::kNoError)
585 if (use_echo_for_swap_ack_) {
586 command_buffer_->Echo(base::Bind(
587 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
588 weak_ptr_factory_.GetWeakPtr()));
590 #if defined(OS_MACOSX)
591 // It appears that making the compositor's on-screen context current on
592 // other platforms implies this flush. TODO(kbr): this means that the
593 // TOUCH build and, in the future, other platforms might need this.
598 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
599 int x, int y, int width, int height) {
600 // Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture
602 if (ShouldUseSwapClient())
603 swap_client_->OnViewContextSwapBuffersPosted();
604 gl_->PostSubBufferCHROMIUM(x, y, width, height);
605 command_buffer_->Echo(base::Bind(
606 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
607 weak_ptr_factory_.GetWeakPtr()));
610 DELEGATE_TO_GL_3(reshapeWithScaleFactor, ResizeCHROMIUM, int, int, float)
612 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError(
614 if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
615 synthetic_errors_.end()) {
616 synthetic_errors_.push_back(error);
620 DELEGATE_TO_GL_4R(mapBufferSubDataCHROMIUM, MapBufferSubDataCHROMIUM, WGC3Denum,
621 WGC3Dintptr, WGC3Dsizeiptr, WGC3Denum, void*)
623 DELEGATE_TO_GL_1(unmapBufferSubDataCHROMIUM, UnmapBufferSubDataCHROMIUM,
626 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM(
636 return gl_->MapTexSubImage2DCHROMIUM(
637 target, level, xoffset, yoffset, width, height, format, type, access);
640 DELEGATE_TO_GL_1(unmapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM,
643 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM(
647 command_buffer_->SetSurfaceVisible(visible);
649 real_gl_->FreeEverything();
652 DELEGATE_TO_GL_3(discardFramebufferEXT, DiscardFramebufferEXT, WGC3Denum,
653 WGC3Dsizei, const WGC3Denum*)
655 void WebGraphicsContext3DCommandBufferImpl::discardBackbufferCHROMIUM() {
657 command_buffer_->DiscardBackbuffer();
660 void WebGraphicsContext3DCommandBufferImpl::ensureBackbufferCHROMIUM() {
662 command_buffer_->EnsureBackbuffer();
665 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM(
666 WebGLId texture, WebGLId parentTexture) {
670 DELEGATE_TO_GL(rateLimitOffscreenContextCHROMIUM,
671 RateLimitOffscreenContextCHROMIUM)
673 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::
674 getRequestableExtensionsCHROMIUM() {
675 return WebKit::WebString::fromUTF8(
676 gl_->GetRequestableExtensionsCHROMIUM());
679 DELEGATE_TO_GL_1(requestExtensionCHROMIUM, RequestExtensionCHROMIUM,
682 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM(
683 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
684 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
685 WGC3Dbitfield mask, WGC3Denum filter) {
686 gl_->BlitFramebufferEXT(
687 srcX0, srcY0, srcX1, srcY1,
688 dstX0, dstY0, dstX1, dstY1,
692 DELEGATE_TO_GL_5(renderbufferStorageMultisampleCHROMIUM,
693 RenderbufferStorageMultisampleEXT, WGC3Denum, WGC3Dsizei,
694 WGC3Denum, WGC3Dsizei, WGC3Dsizei)
696 DELEGATE_TO_GL_1R(createStreamTextureCHROMIUM, CreateStreamTextureCHROMIUM,
699 DELEGATE_TO_GL_1(destroyStreamTextureCHROMIUM, DestroyStreamTextureCHROMIUM,
702 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
704 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
706 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId,
707 WGC3Duint, const WGC3Dchar*)
709 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId)
711 DELEGATE_TO_GL_2(bindFramebuffer, BindFramebuffer, WGC3Denum, WebGLId)
713 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId)
715 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId)
717 DELEGATE_TO_GL_4(blendColor, BlendColor,
718 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
720 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
722 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
723 WGC3Denum, WGC3Denum)
725 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
727 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
728 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
730 DELEGATE_TO_GL_4(bufferData, BufferData,
731 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
733 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
734 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
736 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus,
737 WGC3Denum, WGC3Denum)
739 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
741 DELEGATE_TO_GL_4(clearColor, ClearColor,
742 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
744 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf)
746 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
748 DELEGATE_TO_GL_4(colorMask, ColorMask,
749 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
751 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId)
753 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
754 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
755 WGC3Dsizei, WGC3Dsizei, const void*)
757 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
758 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
759 WGC3Denum, WGC3Dsizei, const void*)
761 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D,
762 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
763 WGC3Dsizei, WGC3Dsizei, WGC3Dint)
765 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D,
766 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
767 WGC3Dsizei, WGC3Dsizei)
769 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
771 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
773 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
775 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf)
777 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
779 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
781 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray,
784 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
786 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode,
789 WGC3Dintptr offset) {
792 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
795 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
797 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray,
800 void WebGraphicsContext3DCommandBufferImpl::finish() {
801 flush_id_ = GenFlushID();
803 if (!visible_ && free_command_buffer_when_invisible_)
804 real_gl_->FreeEverything();
807 void WebGraphicsContext3DCommandBufferImpl::flush() {
808 flush_id_ = GenFlushID();
810 if (!visible_ && free_command_buffer_when_invisible_)
811 real_gl_->FreeEverything();
814 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer,
815 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
817 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D,
818 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
820 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
822 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum)
824 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib(
825 WebGLId program, WGC3Duint index, ActiveInfo& info) {
827 synthesizeGLError(GL_INVALID_VALUE);
830 GLint max_name_length = -1;
832 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
833 if (max_name_length < 0)
835 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
837 synthesizeGLError(GL_OUT_OF_MEMORY);
843 gl_->GetActiveAttrib(
844 program, index, max_name_length, &length, &size, &type, name.get());
848 info.name = WebKit::WebString::fromUTF8(name.get(), length);
854 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform(
855 WebGLId program, WGC3Duint index, ActiveInfo& info) {
856 GLint max_name_length = -1;
858 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
859 if (max_name_length < 0)
861 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
863 synthesizeGLError(GL_OUT_OF_MEMORY);
869 gl_->GetActiveUniform(
870 program, index, max_name_length, &length, &size, &type, name.get());
874 info.name = WebKit::WebString::fromUTF8(name.get(), length);
880 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
881 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
883 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
884 WebGLId, const WGC3Dchar*, WGC3Dint)
886 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*)
888 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
889 WGC3Denum, WGC3Denum, WGC3Dint*)
891 WebKit::WebGraphicsContext3D::Attributes
892 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() {
896 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() {
897 if (!synthetic_errors_.empty()) {
898 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
899 WGC3Denum err = *iter;
900 synthetic_errors_.erase(iter);
904 return gl_->GetError();
907 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
908 return initialize_failed_ ||
909 (command_buffer_ && IsCommandBufferContextLost()) ||
910 context_lost_reason_ != GL_NO_ERROR;
913 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
915 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
916 GetFramebufferAttachmentParameteriv,
917 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
919 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
921 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
923 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog(
926 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
928 return WebKit::WebString();
929 scoped_ptr<GLchar[]> log(new GLchar[logLength]);
931 return WebKit::WebString();
932 GLsizei returnedLogLength = 0;
933 gl_->GetProgramInfoLog(
934 program, logLength, &returnedLogLength, log.get());
935 DCHECK_EQ(logLength, returnedLogLength + 1);
936 WebKit::WebString res =
937 WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
941 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv,
942 WGC3Denum, WGC3Denum, WGC3Dint*)
944 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*)
946 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog(
949 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
951 return WebKit::WebString();
952 scoped_ptr<GLchar[]> log(new GLchar[logLength]);
954 return WebKit::WebString();
955 GLsizei returnedLogLength = 0;
956 gl_->GetShaderInfoLog(
957 shader, logLength, &returnedLogLength, log.get());
958 DCHECK_EQ(logLength, returnedLogLength + 1);
959 WebKit::WebString res =
960 WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
964 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat,
965 WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*)
967 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource(
970 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
972 return WebKit::WebString();
973 scoped_ptr<GLchar[]> log(new GLchar[logLength]);
975 return WebKit::WebString();
976 GLsizei returnedLogLength = 0;
977 gl_->GetShaderSource(
978 shader, logLength, &returnedLogLength, log.get());
979 if (!returnedLogLength)
980 return WebKit::WebString();
981 DCHECK_EQ(logLength, returnedLogLength + 1);
982 WebKit::WebString res =
983 WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
987 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::
988 getTranslatedShaderSourceANGLE(WebGLId shader) {
991 shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength);
993 return WebKit::WebString();
994 scoped_ptr<GLchar[]> log(new GLchar[logLength]);
996 return WebKit::WebString();
997 GLsizei returnedLogLength = 0;
998 gl_->GetTranslatedShaderSourceANGLE(
999 shader, logLength, &returnedLogLength, log.get());
1000 if (!returnedLogLength)
1001 return WebKit::WebString();
1002 DCHECK_EQ(logLength, returnedLogLength + 1);
1003 WebKit::WebString res =
1004 WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
1008 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getString(
1010 return WebKit::WebString::fromUTF8(
1011 reinterpret_cast<const char*>(gl_->GetString(name)));
1014 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
1015 WGC3Denum, WGC3Denum, WGC3Dfloat*)
1017 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
1018 WGC3Denum, WGC3Denum, WGC3Dint*)
1020 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
1022 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
1024 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
1025 WebGLId, const WGC3Dchar*, WGC3Dint)
1027 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
1028 WGC3Duint, WGC3Denum, WGC3Dfloat*)
1030 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
1031 WGC3Duint, WGC3Denum, WGC3Dint*)
1033 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset(
1034 WGC3Duint index, WGC3Denum pname) {
1035 GLvoid* value = NULL;
1036 // NOTE: If pname is ever a value that returns more then 1 element
1037 // this will corrupt memory.
1038 gl_->GetVertexAttribPointerv(index, pname, &value);
1039 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value));
1042 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
1044 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
1046 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
1048 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean)
1050 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
1052 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean)
1054 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
1056 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
1058 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
1060 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
1062 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
1064 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
1066 DELEGATE_TO_GL_7(readPixels, ReadPixels,
1067 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum,
1070 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() {
1073 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage,
1074 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei)
1076 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean)
1078 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1080 void WebGraphicsContext3DCommandBufferImpl::shaderSource(
1081 WebGLId shader, const WGC3Dchar* string) {
1082 GLint length = strlen(string);
1083 gl_->ShaderSource(shader, 1, &string, &length);
1086 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
1088 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
1089 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
1091 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
1093 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
1094 WGC3Denum, WGC3Duint)
1096 DELEGATE_TO_GL_3(stencilOp, StencilOp,
1097 WGC3Denum, WGC3Denum, WGC3Denum)
1099 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
1100 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
1102 DELEGATE_TO_GL_9(texImage2D, TexImage2D,
1103 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei,
1104 WGC3Dint, WGC3Denum, WGC3Denum, const void*)
1106 DELEGATE_TO_GL_3(texParameterf, TexParameterf,
1107 WGC3Denum, WGC3Denum, WGC3Dfloat);
1109 static const unsigned int kTextureWrapR = 0x8072;
1111 void WebGraphicsContext3DCommandBufferImpl::texParameteri(
1112 WGC3Denum target, WGC3Denum pname, WGC3Dint param) {
1113 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in
1114 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the
1115 // edge of cube maps, and, if it is, push it into the GLES2 service
1117 if (pname == kTextureWrapR) {
1120 gl_->TexParameteri(target, pname, param);
1123 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
1124 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1125 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1127 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
1129 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei,
1132 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
1134 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1136 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
1138 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei,
1141 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
1143 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1145 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint,
1146 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1148 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei,
1151 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1153 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1155 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
1156 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1158 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei,
1161 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
1162 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1164 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1166 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
1167 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1169 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
1170 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1172 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
1173 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1175 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
1177 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
1179 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
1181 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint,
1184 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint,
1185 WGC3Dfloat, WGC3Dfloat)
1187 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint,
1190 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint,
1191 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1193 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint,
1196 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint,
1197 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1199 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint,
1202 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer(
1203 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
1204 WGC3Dsizei stride, WGC3Dintptr offset) {
1205 gl_->VertexAttribPointer(
1206 index, size, type, normalized, stride,
1207 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1210 DELEGATE_TO_GL_4(viewport, Viewport,
1211 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1213 DELEGATE_TO_GL_2(genBuffers, GenBuffers, WGC3Dsizei, WebGLId*);
1215 DELEGATE_TO_GL_2(genFramebuffers, GenFramebuffers, WGC3Dsizei, WebGLId*);
1217 DELEGATE_TO_GL_2(genRenderbuffers, GenRenderbuffers, WGC3Dsizei, WebGLId*);
1219 DELEGATE_TO_GL_2(genTextures, GenTextures, WGC3Dsizei, WebGLId*);
1221 DELEGATE_TO_GL_2(deleteBuffers, DeleteBuffers, WGC3Dsizei, WebGLId*);
1223 DELEGATE_TO_GL_2(deleteFramebuffers, DeleteFramebuffers, WGC3Dsizei, WebGLId*);
1225 DELEGATE_TO_GL_2(deleteRenderbuffers, DeleteRenderbuffers, WGC3Dsizei,
1228 DELEGATE_TO_GL_2(deleteTextures, DeleteTextures, WGC3Dsizei, WebGLId*);
1230 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() {
1232 gl_->GenBuffers(1, &o);
1236 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() {
1238 gl_->GenFramebuffers(1, &o);
1242 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() {
1244 gl_->GenRenderbuffers(1, &o);
1248 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() {
1250 gl_->GenTextures(1, &o);
1254 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) {
1255 gl_->DeleteBuffers(1, &buffer);
1258 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer(
1259 WebGLId framebuffer) {
1260 gl_->DeleteFramebuffers(1, &framebuffer);
1263 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer(
1264 WebGLId renderbuffer) {
1265 gl_->DeleteRenderbuffers(1, &renderbuffer);
1268 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
1269 gl_->DeleteTextures(1, &texture);
1272 DELEGATE_TO_GL_R(createProgram, CreateProgram, WebGLId)
1274 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId)
1276 DELEGATE_TO_GL_1(deleteProgram, DeleteProgram, WebGLId)
1278 DELEGATE_TO_GL_1(deleteShader, DeleteShader, WebGLId)
1280 bool WebGraphicsContext3DCommandBufferImpl::ShouldUseSwapClient() {
1281 return !!swap_client_.get();
1284 void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() {
1285 typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient;
1286 // This may be called after tear-down of the RenderView.
1287 if (ShouldUseSwapClient()) {
1288 base::MessageLoop::current()->PostTask(
1290 base::Bind(&WGC3DSwapClient::OnViewContextSwapBuffersComplete,
1294 if (swapbuffers_complete_callback_)
1295 swapbuffers_complete_callback_->onSwapBuffersComplete();
1298 void WebGraphicsContext3DCommandBufferImpl::setErrorMessageCallback(
1299 WebGraphicsContext3D::WebGraphicsErrorMessageCallback* cb) {
1300 error_message_callback_ = cb;
1303 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback(
1304 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) {
1305 context_lost_callback_ = cb;
1308 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() {
1309 if (IsCommandBufferContextLost() &&
1310 context_lost_reason_ == GL_NO_ERROR) {
1311 return GL_UNKNOWN_CONTEXT_RESET_ARB;
1314 return context_lost_reason_;
1317 bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
1318 // If the channel shut down unexpectedly, let that supersede the
1319 // command buffer's state.
1320 if (host_.get() && host_->IsLost())
1322 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
1323 return state.error == gpu::error::kLostContext;
1327 WebGraphicsContext3DCommandBufferImpl*
1328 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
1329 GpuChannelHost* host,
1330 const WebGraphicsContext3D::Attributes& attributes,
1331 const GURL& active_url) {
1334 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> null_client;
1335 return new WebGraphicsContext3DCommandBufferImpl(0,
1341 SharedMemoryLimits());
1344 void WebGraphicsContext3DCommandBufferImpl::
1345 setSwapBuffersCompleteCallbackCHROMIUM(
1346 WebGraphicsContext3D::WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* cb) {
1347 swapbuffers_complete_callback_ = cb;
1350 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM,
1351 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint)
1353 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
1354 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
1356 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() {
1358 gl_->GenQueriesEXT(1, &o);
1362 void WebGraphicsContext3DCommandBufferImpl::deleteQueryEXT(
1364 gl_->DeleteQueriesEXT(1, &query);
1367 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean)
1368 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId)
1369 DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum)
1370 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*)
1371 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
1372 WebGLId, WGC3Denum, WGC3Duint*)
1374 DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum,
1375 WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
1377 DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
1378 WebGLId, WGC3Dint, const WGC3Dchar*)
1380 void WebGraphicsContext3DCommandBufferImpl::shallowFlushCHROMIUM() {
1381 flush_id_ = GenFlushID();
1382 gl_->ShallowFlushCHROMIUM();
1385 void WebGraphicsContext3DCommandBufferImpl::shallowFinishCHROMIUM() {
1386 flush_id_ = GenFlushID();
1387 gl_->ShallowFinishCHROMIUM();
1390 DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint)
1392 void WebGraphicsContext3DCommandBufferImpl::loseContextCHROMIUM(
1393 WGC3Denum current, WGC3Denum other) {
1394 gl_->LoseContextCHROMIUM(current, other);
1398 DELEGATE_TO_GL_1(genMailboxCHROMIUM, GenMailboxCHROMIUM, WGC3Dbyte*)
1399 DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM,
1400 WGC3Denum, const WGC3Dbyte*)
1401 DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM,
1402 WGC3Denum, const WGC3Dbyte*)
1404 void WebGraphicsContext3DCommandBufferImpl::insertEventMarkerEXT(
1405 const WGC3Dchar* marker) {
1406 gl_->InsertEventMarkerEXT(0, marker);
1409 void WebGraphicsContext3DCommandBufferImpl::pushGroupMarkerEXT(
1410 const WGC3Dchar* marker) {
1411 gl_->PushGroupMarkerEXT(0, marker);
1414 DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT);
1416 WebGLId WebGraphicsContext3DCommandBufferImpl::createVertexArrayOES() {
1418 gl_->GenVertexArraysOES(1, &array);
1422 void WebGraphicsContext3DCommandBufferImpl::deleteVertexArrayOES(
1424 gl_->DeleteVertexArraysOES(1, &array);
1427 DELEGATE_TO_GL_1R(isVertexArrayOES, IsVertexArrayOES, WebGLId, WGC3Dboolean)
1428 DELEGATE_TO_GL_1(bindVertexArrayOES, BindVertexArrayOES, WebGLId)
1430 DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM,
1431 WGC3Denum, WGC3Dint)
1432 DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM,
1433 WGC3Denum, WGC3Dint)
1435 DELEGATE_TO_GL_2R(mapBufferCHROMIUM, MapBufferCHROMIUM, WGC3Denum, WGC3Denum,
1437 DELEGATE_TO_GL_1R(unmapBufferCHROMIUM, UnmapBufferCHROMIUM, WGC3Denum,
1440 DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum,
1441 WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint,
1442 WGC3Denum, WGC3Denum, const void*)
1443 DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM,
1444 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1445 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1447 DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM,
1450 DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*)
1452 DELEGATE_TO_GL_4(drawArraysInstancedANGLE, DrawArraysInstancedANGLE, WGC3Denum,
1453 WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1455 void WebGraphicsContext3DCommandBufferImpl::drawElementsInstancedANGLE(
1460 WGC3Dsizei primcount) {
1461 gl_->DrawElementsInstancedANGLE(
1463 reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount);
1466 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint,
1469 DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM,
1470 WGC3Dsizei, WGC3Dsizei, WGC3Denum,
1473 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint);
1475 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM,
1476 WGC3Duint, WGC3Denum, GLint*);
1478 DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM,
1479 WGC3Duint, WGC3Denum, void*);
1481 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint);
1483 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::createGrGLInterface() {
1484 return webkit::gpu::CreateCommandBufferSkiaGLBinding();
1489 WGC3Denum convertReason(gpu::error::ContextLostReason reason) {
1491 case gpu::error::kGuilty:
1492 return GL_GUILTY_CONTEXT_RESET_ARB;
1493 case gpu::error::kInnocent:
1494 return GL_INNOCENT_CONTEXT_RESET_ARB;
1495 case gpu::error::kUnknown:
1496 return GL_UNKNOWN_CONTEXT_RESET_ARB;
1500 return GL_UNKNOWN_CONTEXT_RESET_ARB;
1503 } // anonymous namespace
1505 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() {
1506 context_lost_reason_ = convertReason(
1507 command_buffer_->GetLastState().context_lost_reason);
1508 if (context_lost_callback_) {
1509 context_lost_callback_->onContextLost();
1511 if (attributes_.shareResources) {
1512 if (context_for_browser_compositor_) {
1513 ClearSharedContextsIfInShareSetBrowser(this);
1515 ClearSharedContextsIfInShareSet(this);
1518 if (ShouldUseSwapClient())
1519 swap_client_->OnViewContextSwapBuffersAborted();
1522 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage(
1523 const std::string& message, int id) {
1524 if (error_message_callback_) {
1525 WebKit::WebString str = WebKit::WebString::fromUTF8(message.c_str());
1526 error_message_callback_->onErrorMessage(str, id);
1530 } // namespace content