Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / client / webgraphicscontext3d_command_buffer_impl.cc
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/common/gpu/client/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 <map>
15
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 "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
39 #include "third_party/skia/include/core/SkTypes.h"
40
41 namespace content {
42
43 namespace {
44
45 static base::LazyInstance<base::Lock>::Leaky
46     g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
47
48 typedef std::multimap<GpuChannelHost*, WebGraphicsContext3DCommandBufferImpl*>
49     ContextMap;
50 static base::LazyInstance<ContextMap> g_all_shared_contexts =
51     LAZY_INSTANCE_INITIALIZER;
52
53 uint32_t GenFlushID() {
54   static base::subtle::Atomic32 flush_id = 0;
55
56   base::subtle::Atomic32 my_id = base::subtle::Barrier_AtomicIncrement(
57       &flush_id, 1);
58   return static_cast<uint32_t>(my_id);
59 }
60
61 // Singleton used to initialize and terminate the gles2 library.
62 class GLES2Initializer {
63  public:
64   GLES2Initializer() {
65     gles2::Initialize();
66   }
67
68   ~GLES2Initializer() {
69     gles2::Terminate();
70   }
71
72  private:
73   DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
74 };
75
76 ////////////////////////////////////////////////////////////////////////////////
77
78 base::LazyInstance<GLES2Initializer> g_gles2_initializer =
79     LAZY_INSTANCE_INITIALIZER;
80
81 ////////////////////////////////////////////////////////////////////////////////
82
83 } // namespace anonymous
84
85 // Helper macros to reduce the amount of code.
86
87 #define DELEGATE_TO_GL(name, glname)                                    \
88 void WebGraphicsContext3DCommandBufferImpl::name() {                    \
89   gl_->glname();                                                        \
90 }
91
92 #define DELEGATE_TO_GL_R(name, glname, rt)                              \
93 rt WebGraphicsContext3DCommandBufferImpl::name() {                      \
94   return gl_->glname();                                                 \
95 }
96
97 #define DELEGATE_TO_GL_1(name, glname, t1)                              \
98 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1) {               \
99   gl_->glname(a1);                                                      \
100 }
101
102 #define DELEGATE_TO_GL_1R(name, glname, t1, rt)                         \
103 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) {                 \
104   return gl_->glname(a1);                                               \
105 }
106
107 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt)                        \
108 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) {                 \
109   return gl_->glname(a1) ? true : false;                                \
110 }
111
112 #define DELEGATE_TO_GL_2(name, glname, t1, t2)                          \
113 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) {        \
114   gl_->glname(a1, a2);                                                  \
115 }
116
117 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt)                     \
118 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) {          \
119   return gl_->glname(a1, a2);                                           \
120 }
121
122 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3)                      \
123 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \
124   gl_->glname(a1, a2, a3);                                              \
125 }
126
127 #define DELEGATE_TO_GL_3R(name, glname, t1, t2, t3, rt)                 \
128 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) {   \
129   return gl_->glname(a1, a2, a3);                                       \
130 }
131
132 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4)                  \
133 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
134                                                  t4 a4) {               \
135   gl_->glname(a1, a2, a3, a4);                                          \
136 }
137
138 #define DELEGATE_TO_GL_4R(name, glname, t1, t2, t3, t4, rt)             \
139 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,     \
140                                                t4 a4) {                 \
141   return gl_->glname(a1, a2, a3, a4);                                   \
142 }
143
144 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5)              \
145 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
146                                                  t4 a4, t5 a5) {        \
147   gl_->glname(a1, a2, a3, a4, a5);                                      \
148 }
149
150 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6)          \
151 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
152                                                  t4 a4, t5 a5, t6 a6) { \
153   gl_->glname(a1, a2, a3, a4, a5, a6);                                  \
154 }
155
156 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7)      \
157 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
158                                                  t4 a4, t5 a5, t6 a6,   \
159                                                  t7 a7) {               \
160   gl_->glname(a1, a2, a3, a4, a5, a6, a7);                              \
161 }
162
163 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8)  \
164 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
165                                                  t4 a4, t5 a5, t6 a6,   \
166                                                  t7 a7, t8 a8) {        \
167   gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8);                          \
168 }
169
170 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
171 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
172                                                  t4 a4, t5 a5, t6 a6,   \
173                                                  t7 a7, t8 a8, t9 a9) { \
174   gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9);                      \
175 }
176
177 class WebGraphicsContext3DErrorMessageCallback
178     : public gpu::gles2::GLES2Implementation::ErrorMessageCallback {
179  public:
180   WebGraphicsContext3DErrorMessageCallback(
181       WebGraphicsContext3DCommandBufferImpl* context)
182       : graphics_context_(context) {
183   }
184
185   virtual void OnErrorMessage(const char* msg, int id) OVERRIDE;
186
187  private:
188   WebGraphicsContext3DCommandBufferImpl* graphics_context_;
189
190   DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DErrorMessageCallback);
191 };
192
193 void WebGraphicsContext3DErrorMessageCallback::OnErrorMessage(
194     const char* msg, int id) {
195   graphics_context_->OnErrorMessage(msg, id);
196 }
197
198 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits()
199     : command_buffer_size(kDefaultCommandBufferSize),
200       start_transfer_buffer_size(kDefaultStartTransferBufferSize),
201       min_transfer_buffer_size(kDefaultMinTransferBufferSize),
202       max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
203       mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {}
204
205 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
206     int surface_id,
207     const GURL& active_url,
208     GpuChannelHost* host,
209     const Attributes& attributes,
210     bool bind_generates_resources,
211     const SharedMemoryLimits& limits)
212     : initialize_failed_(false),
213       visible_(false),
214       host_(host),
215       surface_id_(surface_id),
216       active_url_(active_url),
217       context_lost_callback_(0),
218       context_lost_reason_(GL_NO_ERROR),
219       error_message_callback_(0),
220       attributes_(attributes),
221       gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu
222                                                    : gfx::PreferIntegratedGpu),
223       weak_ptr_factory_(this),
224       initialized_(false),
225       gl_(NULL),
226       bind_generates_resources_(bind_generates_resources),
227       mem_limits_(limits),
228       flush_id_(0) {
229 }
230
231 WebGraphicsContext3DCommandBufferImpl::
232     ~WebGraphicsContext3DCommandBufferImpl() {
233   if (real_gl_) {
234     real_gl_->SetErrorMessageCallback(NULL);
235   }
236
237   Destroy();
238 }
239
240 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
241   if (initialized_)
242     return true;
243
244   if (initialize_failed_)
245     return false;
246
247   TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
248
249   if (!CreateContext(surface_id_ != 0)) {
250     Destroy();
251     initialize_failed_ = true;
252     return false;
253   }
254
255   // TODO(twiz):  This code is too fragile in that it assumes that only WebGL
256   // contexts will request noExtensions.
257   if (gl_ && attributes_.noExtensions)
258     gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation");
259
260   command_buffer_->SetChannelErrorCallback(
261       base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost,
262                  weak_ptr_factory_.GetWeakPtr()));
263
264   command_buffer_->SetOnConsoleMessageCallback(
265       base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnErrorMessage,
266                  weak_ptr_factory_.GetWeakPtr()));
267
268   client_error_message_callback_.reset(
269       new WebGraphicsContext3DErrorMessageCallback(this));
270   real_gl_->SetErrorMessageCallback(client_error_message_callback_.get());
271
272   // Set attributes_ from created offscreen context.
273   {
274     static const int pcount = 4;
275     static const GLenum pnames[pcount] = {
276       GL_ALPHA_BITS,
277       GL_DEPTH_BITS,
278       GL_STENCIL_BITS,
279       GL_SAMPLE_BUFFERS,
280     };
281     GLint pvalues[pcount] = { 0, 0, 0, 0 };
282
283     gl_->GetMultipleIntegervCHROMIUM(pnames, pcount,
284                                      pvalues, sizeof(pvalues));
285
286     attributes_.alpha = pvalues[0] > 0;
287     attributes_.depth = pvalues[1] > 0;
288     attributes_.stencil = pvalues[2] > 0;
289     attributes_.antialias = pvalues[3] > 0;
290   }
291
292   visible_ = true;
293   initialized_ = true;
294   return true;
295 }
296
297 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
298     bool onscreen) {
299   if (!host_.get())
300     return false;
301   // We need to lock g_all_shared_contexts to ensure that the context we picked
302   // for our share group isn't deleted.
303   // (There's also a lock in our destructor.)
304   base::AutoLock lock(g_all_shared_contexts_lock.Get());
305   CommandBufferProxyImpl* share_group = NULL;
306   if (attributes_.shareResources) {
307     ContextMap& all_contexts = g_all_shared_contexts.Get();
308     ContextMap::const_iterator it = all_contexts.find(host_.get());
309     if (it != all_contexts.end())
310       share_group = it->second->command_buffer_.get();
311   }
312
313   std::vector<int32> attribs;
314   attribs.push_back(ALPHA_SIZE);
315   attribs.push_back(attributes_.alpha ? 8 : 0);
316   attribs.push_back(DEPTH_SIZE);
317   attribs.push_back(attributes_.depth ? 24 : 0);
318   attribs.push_back(STENCIL_SIZE);
319   attribs.push_back(attributes_.stencil ? 8 : 0);
320   attribs.push_back(SAMPLES);
321   attribs.push_back(attributes_.antialias ? 4 : 0);
322   attribs.push_back(SAMPLE_BUFFERS);
323   attribs.push_back(attributes_.antialias ? 1 : 0);
324   attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT);
325   attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0);
326   attribs.push_back(NONE);
327
328   // Create a proxy to a command buffer in the GPU process.
329   if (onscreen) {
330     command_buffer_.reset(host_->CreateViewCommandBuffer(
331         surface_id_,
332         share_group,
333         attribs,
334         active_url_,
335         gpu_preference_));
336   } else {
337     command_buffer_.reset(host_->CreateOffscreenCommandBuffer(
338         gfx::Size(1, 1),
339         share_group,
340         attribs,
341         active_url_,
342         gpu_preference_));
343   }
344
345   if (!command_buffer_)
346     return false;
347
348   // Initialize the command buffer.
349   return command_buffer_->Initialize();
350 }
351
352 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
353     bool onscreen) {
354   // Ensure the gles2 library is initialized first in a thread safe way.
355   g_gles2_initializer.Get();
356
357   if (!command_buffer_ &&
358       !InitializeCommandBuffer(onscreen)) {
359     return false;
360   }
361
362   // Create the GLES2 helper, which writes the command buffer protocol.
363   gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
364   if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size))
365     return false;
366
367   if (attributes_.noAutomaticFlushes)
368     gles2_helper_->SetAutomaticFlushes(false);
369
370   // Create a transfer buffer used to copy resources between the renderer
371   // process and the GPU process.
372   transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get()));
373
374   DCHECK(host_.get());
375   scoped_ptr<base::AutoLock> lock;
376   scoped_refptr<gpu::gles2::ShareGroup> share_group;
377   if (attributes_.shareResources) {
378     // Make sure two clients don't try to create a new ShareGroup
379     // simultaneously.
380     lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
381     ContextMap& all_contexts = g_all_shared_contexts.Get();
382     ContextMap::const_iterator it = all_contexts.find(host_.get());
383     if (it != all_contexts.end()) {
384       share_group = it->second->GetImplementation()->share_group();
385       DCHECK(share_group);
386     }
387   }
388
389   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
390   bool free_command_buffer_when_invisible =
391       command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers);
392
393   // Create the object exposing the OpenGL API.
394   real_gl_.reset(new gpu::gles2::GLES2Implementation(
395       gles2_helper_.get(),
396       share_group,
397       transfer_buffer_.get(),
398       bind_generates_resources_,
399       free_command_buffer_when_invisible,
400       command_buffer_.get()));
401   gl_ = real_gl_.get();
402
403   if (attributes_.shareResources) {
404     // Don't add ourselves to the list before others can get to our ShareGroup.
405     g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this));
406     lock.reset();
407   }
408
409   if (!real_gl_->Initialize(
410       mem_limits_.start_transfer_buffer_size,
411       mem_limits_.min_transfer_buffer_size,
412       mem_limits_.max_transfer_buffer_size,
413       mem_limits_.mapped_memory_reclaim_limit)) {
414     return false;
415   }
416
417   if (CommandLine::ForCurrentProcess()->HasSwitch(
418       switches::kEnableGpuClientTracing)) {
419     trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_));
420     gl_ = trace_gl_.get();
421   }
422
423   return true;
424 }
425
426 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
427   if (!MaybeInitializeGL())
428     return false;
429   gles2::SetGLContext(gl_);
430   if (command_buffer_->GetLastError() != gpu::error::kNoError)
431     return false;
432
433   return true;
434 }
435
436 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() {
437   return flush_id_;
438 }
439
440 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int)
441
442 void WebGraphicsContext3DCommandBufferImpl::Destroy() {
443   if (host_.get()) {
444     base::AutoLock lock(g_all_shared_contexts_lock.Get());
445     ContextMap& all_contexts = g_all_shared_contexts.Get();
446     ContextMap::iterator it = std::find(
447         all_contexts.begin(),
448         all_contexts.end(),
449         std::pair<GpuChannelHost* const,
450                   WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this));
451     if (it != all_contexts.end())
452       all_contexts.erase(it);
453   }
454
455   if (gl_) {
456     // First flush the context to ensure that any pending frees of resources
457     // are completed. Otherwise, if this context is part of a share group,
458     // those resources might leak. Also, any remaining side effects of commands
459     // issued on this context might not be visible to other contexts in the
460     // share group.
461     gl_->Flush();
462     gl_ = NULL;
463   }
464
465   trace_gl_.reset();
466   real_gl_.reset();
467   transfer_buffer_.reset();
468   gles2_helper_.reset();
469   real_gl_.reset();
470
471   if (command_buffer_) {
472     if (host_.get())
473       host_->DestroyCommandBuffer(command_buffer_.release());
474     command_buffer_.reset();
475   }
476
477   host_ = NULL;
478 }
479
480 gpu::ContextSupport*
481 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() {
482   return real_gl_.get();
483 }
484
485 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
486   NOTREACHED();
487 }
488
489 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
490     int x, int y, int width, int height) {
491   NOTREACHED();
492 }
493
494 DELEGATE_TO_GL_3(reshapeWithScaleFactor, ResizeCHROMIUM, int, int, float)
495
496 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError(
497     WGC3Denum error) {
498   if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
499       synthetic_errors_.end()) {
500     synthetic_errors_.push_back(error);
501   }
502 }
503
504 DELEGATE_TO_GL_4R(mapBufferSubDataCHROMIUM, MapBufferSubDataCHROMIUM, WGC3Denum,
505                   WGC3Dintptr, WGC3Dsizeiptr, WGC3Denum, void*)
506
507 DELEGATE_TO_GL_1(unmapBufferSubDataCHROMIUM, UnmapBufferSubDataCHROMIUM,
508                  const void*)
509
510 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM(
511     WGC3Denum target,
512     WGC3Dint level,
513     WGC3Dint xoffset,
514     WGC3Dint yoffset,
515     WGC3Dsizei width,
516     WGC3Dsizei height,
517     WGC3Denum format,
518     WGC3Denum type,
519     WGC3Denum access) {
520   return gl_->MapTexSubImage2DCHROMIUM(
521       target, level, xoffset, yoffset, width, height, format, type, access);
522 }
523
524 DELEGATE_TO_GL_1(unmapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM,
525                  const void*)
526
527 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM(
528     bool visible) {
529   NOTREACHED();
530 }
531
532 DELEGATE_TO_GL_3(discardFramebufferEXT, DiscardFramebufferEXT, WGC3Denum,
533                  WGC3Dsizei, const WGC3Denum*)
534
535 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM(
536     WebGLId texture, WebGLId parentTexture) {
537   NOTIMPLEMENTED();
538 }
539
540 blink::WebString WebGraphicsContext3DCommandBufferImpl::
541     getRequestableExtensionsCHROMIUM() {
542   return blink::WebString::fromUTF8(
543       gl_->GetRequestableExtensionsCHROMIUM());
544 }
545
546 DELEGATE_TO_GL_1(requestExtensionCHROMIUM, RequestExtensionCHROMIUM,
547                  const char*)
548
549 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM(
550     WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
551     WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
552     WGC3Dbitfield mask, WGC3Denum filter) {
553   gl_->BlitFramebufferCHROMIUM(
554       srcX0, srcY0, srcX1, srcY1,
555       dstX0, dstY0, dstX1, dstY1,
556       mask, filter);
557 }
558
559 DELEGATE_TO_GL_5(renderbufferStorageMultisampleCHROMIUM,
560                  RenderbufferStorageMultisampleCHROMIUM, WGC3Denum, WGC3Dsizei,
561                  WGC3Denum, WGC3Dsizei, WGC3Dsizei)
562
563 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
564
565 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
566
567 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId,
568                  WGC3Duint, const WGC3Dchar*)
569
570 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId)
571
572 DELEGATE_TO_GL_2(bindFramebuffer, BindFramebuffer, WGC3Denum, WebGLId)
573
574 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId)
575
576 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId)
577
578 DELEGATE_TO_GL_4(blendColor, BlendColor,
579                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
580
581 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
582
583 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
584                  WGC3Denum, WGC3Denum)
585
586 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
587
588 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
589                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
590
591 DELEGATE_TO_GL_4(bufferData, BufferData,
592                  WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
593
594 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
595                  WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
596
597 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus,
598                   WGC3Denum, WGC3Denum)
599
600 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
601
602 DELEGATE_TO_GL_4(clearColor, ClearColor,
603                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
604
605 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf)
606
607 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
608
609 DELEGATE_TO_GL_4(colorMask, ColorMask,
610                  WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
611
612 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId)
613
614 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
615                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
616                  WGC3Dsizei, WGC3Dsizei, const void*)
617
618 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
619                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
620                  WGC3Denum, WGC3Dsizei, const void*)
621
622 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D,
623                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
624                  WGC3Dsizei, WGC3Dsizei, WGC3Dint)
625
626 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D,
627                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
628                  WGC3Dsizei, WGC3Dsizei)
629
630 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
631
632 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
633
634 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
635
636 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf)
637
638 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
639
640 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
641
642 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray,
643                  WGC3Duint)
644
645 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
646
647 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode,
648                                                          WGC3Dsizei count,
649                                                          WGC3Denum type,
650                                                          WGC3Dintptr offset) {
651   gl_->DrawElements(
652       mode, count, type,
653       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
654 }
655
656 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
657
658 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray,
659                  WGC3Duint)
660
661 void WebGraphicsContext3DCommandBufferImpl::finish() {
662   flush_id_ = GenFlushID();
663   gl_->Finish();
664 }
665
666 void WebGraphicsContext3DCommandBufferImpl::flush() {
667   flush_id_ = GenFlushID();
668   gl_->Flush();
669 }
670
671 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer,
672                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
673
674 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D,
675                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
676
677 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
678
679 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum)
680
681 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib(
682     WebGLId program, WGC3Duint index, ActiveInfo& info) {
683   if (!program) {
684     synthesizeGLError(GL_INVALID_VALUE);
685     return false;
686   }
687   GLint max_name_length = -1;
688   gl_->GetProgramiv(
689       program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
690   if (max_name_length < 0)
691     return false;
692   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
693   if (!name) {
694     synthesizeGLError(GL_OUT_OF_MEMORY);
695     return false;
696   }
697   GLsizei length = 0;
698   GLint size = -1;
699   GLenum type = 0;
700   gl_->GetActiveAttrib(
701       program, index, max_name_length, &length, &size, &type, name.get());
702   if (size < 0) {
703     return false;
704   }
705   info.name = blink::WebString::fromUTF8(name.get(), length);
706   info.type = type;
707   info.size = size;
708   return true;
709 }
710
711 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform(
712     WebGLId program, WGC3Duint index, ActiveInfo& info) {
713   GLint max_name_length = -1;
714   gl_->GetProgramiv(
715       program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
716   if (max_name_length < 0)
717     return false;
718   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
719   if (!name) {
720     synthesizeGLError(GL_OUT_OF_MEMORY);
721     return false;
722   }
723   GLsizei length = 0;
724   GLint size = -1;
725   GLenum type = 0;
726   gl_->GetActiveUniform(
727       program, index, max_name_length, &length, &size, &type, name.get());
728   if (size < 0) {
729     return false;
730   }
731   info.name = blink::WebString::fromUTF8(name.get(), length);
732   info.type = type;
733   info.size = size;
734   return true;
735 }
736
737 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
738                  WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
739
740 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
741                   WebGLId, const WGC3Dchar*, WGC3Dint)
742
743 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*)
744
745 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
746                  WGC3Denum, WGC3Denum, WGC3Dint*)
747
748 blink::WebGraphicsContext3D::Attributes
749 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() {
750   return attributes_;
751 }
752
753 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() {
754   if (!synthetic_errors_.empty()) {
755     std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
756     WGC3Denum err = *iter;
757     synthetic_errors_.erase(iter);
758     return err;
759   }
760
761   return gl_->GetError();
762 }
763
764 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
765   return initialize_failed_ ||
766       (command_buffer_ && IsCommandBufferContextLost()) ||
767       context_lost_reason_ != GL_NO_ERROR;
768 }
769
770 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
771
772 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
773                  GetFramebufferAttachmentParameteriv,
774                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
775
776 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
777
778 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
779
780 blink::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog(
781     WebGLId program) {
782   GLint logLength = 0;
783   gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
784   if (!logLength)
785     return blink::WebString();
786   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
787   if (!log)
788     return blink::WebString();
789   GLsizei returnedLogLength = 0;
790   gl_->GetProgramInfoLog(
791       program, logLength, &returnedLogLength, log.get());
792   DCHECK_EQ(logLength, returnedLogLength + 1);
793   blink::WebString res =
794       blink::WebString::fromUTF8(log.get(), returnedLogLength);
795   return res;
796 }
797
798 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv,
799                  WGC3Denum, WGC3Denum, WGC3Dint*)
800
801 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*)
802
803 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog(
804     WebGLId shader) {
805   GLint logLength = 0;
806   gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
807   if (!logLength)
808     return blink::WebString();
809   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
810   if (!log)
811     return blink::WebString();
812   GLsizei returnedLogLength = 0;
813   gl_->GetShaderInfoLog(
814       shader, logLength, &returnedLogLength, log.get());
815   DCHECK_EQ(logLength, returnedLogLength + 1);
816   blink::WebString res =
817       blink::WebString::fromUTF8(log.get(), returnedLogLength);
818   return res;
819 }
820
821 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat,
822                  WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*)
823
824 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource(
825     WebGLId shader) {
826   GLint logLength = 0;
827   gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
828   if (!logLength)
829     return blink::WebString();
830   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
831   if (!log)
832     return blink::WebString();
833   GLsizei returnedLogLength = 0;
834   gl_->GetShaderSource(
835       shader, logLength, &returnedLogLength, log.get());
836   if (!returnedLogLength)
837     return blink::WebString();
838   DCHECK_EQ(logLength, returnedLogLength + 1);
839   blink::WebString res =
840       blink::WebString::fromUTF8(log.get(), returnedLogLength);
841   return res;
842 }
843
844 blink::WebString WebGraphicsContext3DCommandBufferImpl::
845     getTranslatedShaderSourceANGLE(WebGLId shader) {
846   GLint logLength = 0;
847   gl_->GetShaderiv(
848       shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength);
849   if (!logLength)
850     return blink::WebString();
851   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
852   if (!log)
853     return blink::WebString();
854   GLsizei returnedLogLength = 0;
855   gl_->GetTranslatedShaderSourceANGLE(
856       shader, logLength, &returnedLogLength, log.get());
857   if (!returnedLogLength)
858     return blink::WebString();
859   DCHECK_EQ(logLength, returnedLogLength + 1);
860   blink::WebString res =
861       blink::WebString::fromUTF8(log.get(), returnedLogLength);
862   return res;
863 }
864
865 blink::WebString WebGraphicsContext3DCommandBufferImpl::getString(
866     WGC3Denum name) {
867   return blink::WebString::fromUTF8(
868       reinterpret_cast<const char*>(gl_->GetString(name)));
869 }
870
871 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
872                  WGC3Denum, WGC3Denum, WGC3Dfloat*)
873
874 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
875                  WGC3Denum, WGC3Denum, WGC3Dint*)
876
877 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
878
879 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
880
881 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
882                   WebGLId, const WGC3Dchar*, WGC3Dint)
883
884 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
885                  WGC3Duint, WGC3Denum, WGC3Dfloat*)
886
887 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
888                  WGC3Duint, WGC3Denum, WGC3Dint*)
889
890 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset(
891     WGC3Duint index, WGC3Denum pname) {
892   GLvoid* value = NULL;
893   // NOTE: If pname is ever a value that returns more then 1 element
894   // this will corrupt memory.
895   gl_->GetVertexAttribPointerv(index, pname, &value);
896   return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value));
897 }
898
899 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
900
901 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
902
903 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
904
905 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean)
906
907 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
908
909 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean)
910
911 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
912
913 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
914
915 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
916
917 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
918
919 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
920
921 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
922
923 DELEGATE_TO_GL_7(readPixels, ReadPixels,
924                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum,
925                  WGC3Denum, void*)
926
927 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() {
928 }
929
930 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage,
931                  WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei)
932
933 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean)
934
935 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
936
937 void WebGraphicsContext3DCommandBufferImpl::shaderSource(
938     WebGLId shader, const WGC3Dchar* string) {
939   GLint length = strlen(string);
940   gl_->ShaderSource(shader, 1, &string, &length);
941 }
942
943 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
944
945 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
946                  WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
947
948 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
949
950 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
951                  WGC3Denum, WGC3Duint)
952
953 DELEGATE_TO_GL_3(stencilOp, StencilOp,
954                  WGC3Denum, WGC3Denum, WGC3Denum)
955
956 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
957                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
958
959 DELEGATE_TO_GL_9(texImage2D, TexImage2D,
960                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei,
961                  WGC3Dint, WGC3Denum, WGC3Denum, const void*)
962
963 DELEGATE_TO_GL_3(texParameterf, TexParameterf,
964                  WGC3Denum, WGC3Denum, WGC3Dfloat);
965
966 static const unsigned int kTextureWrapR = 0x8072;
967
968 void WebGraphicsContext3DCommandBufferImpl::texParameteri(
969     WGC3Denum target, WGC3Denum pname, WGC3Dint param) {
970   // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in
971   // GraphicsContext3D.cpp is strictly necessary to avoid seams at the
972   // edge of cube maps, and, if it is, push it into the GLES2 service
973   // side code.
974   if (pname == kTextureWrapR) {
975     return;
976   }
977   gl_->TexParameteri(target, pname, param);
978 }
979
980 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
981                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
982                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
983
984 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
985
986 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei,
987                  const WGC3Dfloat*)
988
989 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
990
991 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
992
993 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
994
995 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei,
996                  const WGC3Dfloat*)
997
998 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
999
1000 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1001
1002 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint,
1003                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1004
1005 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei,
1006                  const WGC3Dfloat*)
1007
1008 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1009
1010 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1011
1012 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
1013                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1014
1015 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei,
1016                  const WGC3Dfloat*)
1017
1018 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
1019                  WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1020
1021 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1022
1023 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
1024                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1025
1026 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
1027                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1028
1029 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
1030                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1031
1032 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
1033
1034 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
1035
1036 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
1037
1038 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint,
1039                  const WGC3Dfloat*)
1040
1041 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint,
1042                  WGC3Dfloat, WGC3Dfloat)
1043
1044 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint,
1045                  const WGC3Dfloat*)
1046
1047 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint,
1048                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1049
1050 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint,
1051                  const WGC3Dfloat*)
1052
1053 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint,
1054                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1055
1056 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint,
1057                  const WGC3Dfloat*)
1058
1059 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer(
1060     WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
1061     WGC3Dsizei stride, WGC3Dintptr offset) {
1062   gl_->VertexAttribPointer(
1063       index, size, type, normalized, stride,
1064       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1065 }
1066
1067 DELEGATE_TO_GL_4(viewport, Viewport,
1068                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1069
1070 DELEGATE_TO_GL_2(genBuffers, GenBuffers, WGC3Dsizei, WebGLId*);
1071
1072 DELEGATE_TO_GL_2(genFramebuffers, GenFramebuffers, WGC3Dsizei, WebGLId*);
1073
1074 DELEGATE_TO_GL_2(genRenderbuffers, GenRenderbuffers, WGC3Dsizei, WebGLId*);
1075
1076 DELEGATE_TO_GL_2(genTextures, GenTextures, WGC3Dsizei, WebGLId*);
1077
1078 DELEGATE_TO_GL_2(deleteBuffers, DeleteBuffers, WGC3Dsizei, WebGLId*);
1079
1080 DELEGATE_TO_GL_2(deleteFramebuffers, DeleteFramebuffers, WGC3Dsizei, WebGLId*);
1081
1082 DELEGATE_TO_GL_2(deleteRenderbuffers, DeleteRenderbuffers, WGC3Dsizei,
1083                  WebGLId*);
1084
1085 DELEGATE_TO_GL_2(deleteTextures, DeleteTextures, WGC3Dsizei, WebGLId*);
1086
1087 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() {
1088   GLuint o;
1089   gl_->GenBuffers(1, &o);
1090   return o;
1091 }
1092
1093 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() {
1094   GLuint o = 0;
1095   gl_->GenFramebuffers(1, &o);
1096   return o;
1097 }
1098
1099 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() {
1100   GLuint o;
1101   gl_->GenRenderbuffers(1, &o);
1102   return o;
1103 }
1104
1105 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() {
1106   GLuint o;
1107   gl_->GenTextures(1, &o);
1108   return o;
1109 }
1110
1111 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) {
1112   gl_->DeleteBuffers(1, &buffer);
1113 }
1114
1115 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer(
1116     WebGLId framebuffer) {
1117   gl_->DeleteFramebuffers(1, &framebuffer);
1118 }
1119
1120 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer(
1121     WebGLId renderbuffer) {
1122   gl_->DeleteRenderbuffers(1, &renderbuffer);
1123 }
1124
1125 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
1126   gl_->DeleteTextures(1, &texture);
1127 }
1128
1129 DELEGATE_TO_GL_R(createProgram, CreateProgram, WebGLId)
1130
1131 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId)
1132
1133 DELEGATE_TO_GL_1(deleteProgram, DeleteProgram, WebGLId)
1134
1135 DELEGATE_TO_GL_1(deleteShader, DeleteShader, WebGLId)
1136
1137 void WebGraphicsContext3DCommandBufferImpl::setErrorMessageCallback(
1138     WebGraphicsContext3D::WebGraphicsErrorMessageCallback* cb) {
1139   error_message_callback_ = cb;
1140 }
1141
1142 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback(
1143     WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) {
1144   context_lost_callback_ = cb;
1145 }
1146
1147 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() {
1148   if (IsCommandBufferContextLost() &&
1149       context_lost_reason_ == GL_NO_ERROR) {
1150     return GL_UNKNOWN_CONTEXT_RESET_ARB;
1151   }
1152
1153   return context_lost_reason_;
1154 }
1155
1156 bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
1157   // If the channel shut down unexpectedly, let that supersede the
1158   // command buffer's state.
1159   if (host_.get() && host_->IsLost())
1160     return true;
1161   gpu::CommandBuffer::State state = command_buffer_->GetLastState();
1162   return state.error == gpu::error::kLostContext;
1163 }
1164
1165 // static
1166 WebGraphicsContext3DCommandBufferImpl*
1167 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
1168     GpuChannelHost* host,
1169     const WebGraphicsContext3D::Attributes& attributes,
1170     const GURL& active_url,
1171     const SharedMemoryLimits& limits) {
1172   if (!host)
1173     return NULL;
1174   return new WebGraphicsContext3DCommandBufferImpl(0,
1175                                                    active_url,
1176                                                    host,
1177                                                    attributes,
1178                                                    false,
1179                                                    limits);
1180 }
1181
1182 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM,
1183                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint)
1184
1185 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
1186                  WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
1187
1188 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() {
1189   GLuint o;
1190   gl_->GenQueriesEXT(1, &o);
1191   return o;
1192 }
1193
1194 void WebGraphicsContext3DCommandBufferImpl::deleteQueryEXT(
1195     WebGLId query) {
1196   gl_->DeleteQueriesEXT(1, &query);
1197 }
1198
1199 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean)
1200 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId)
1201 DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum)
1202 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*)
1203 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
1204                  WebGLId, WGC3Denum, WGC3Duint*)
1205
1206 DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM,  WGC3Denum,
1207                  WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
1208
1209 DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
1210                  WebGLId, WGC3Dint, const WGC3Dchar*)
1211
1212 void WebGraphicsContext3DCommandBufferImpl::shallowFlushCHROMIUM() {
1213   flush_id_ = GenFlushID();
1214   gl_->ShallowFlushCHROMIUM();
1215 }
1216
1217 void WebGraphicsContext3DCommandBufferImpl::shallowFinishCHROMIUM() {
1218   flush_id_ = GenFlushID();
1219   gl_->ShallowFinishCHROMIUM();
1220 }
1221
1222 DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint)
1223
1224 void WebGraphicsContext3DCommandBufferImpl::loseContextCHROMIUM(
1225     WGC3Denum current, WGC3Denum other) {
1226   gl_->LoseContextCHROMIUM(current, other);
1227   gl_->Flush();
1228 }
1229
1230 DELEGATE_TO_GL_1(genMailboxCHROMIUM, GenMailboxCHROMIUM, WGC3Dbyte*)
1231 DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM,
1232                  WGC3Denum, const WGC3Dbyte*)
1233 DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM,
1234                  WGC3Denum, const WGC3Dbyte*)
1235
1236 void WebGraphicsContext3DCommandBufferImpl::insertEventMarkerEXT(
1237     const WGC3Dchar* marker) {
1238   gl_->InsertEventMarkerEXT(0, marker);
1239 }
1240
1241 void WebGraphicsContext3DCommandBufferImpl::pushGroupMarkerEXT(
1242     const WGC3Dchar* marker) {
1243   gl_->PushGroupMarkerEXT(0, marker);
1244 }
1245
1246 DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT);
1247
1248 WebGLId WebGraphicsContext3DCommandBufferImpl::createVertexArrayOES() {
1249   GLuint array;
1250   gl_->GenVertexArraysOES(1, &array);
1251   return array;
1252 }
1253
1254 void WebGraphicsContext3DCommandBufferImpl::deleteVertexArrayOES(
1255     WebGLId array) {
1256   gl_->DeleteVertexArraysOES(1, &array);
1257 }
1258
1259 DELEGATE_TO_GL_1R(isVertexArrayOES, IsVertexArrayOES, WebGLId, WGC3Dboolean)
1260 DELEGATE_TO_GL_1(bindVertexArrayOES, BindVertexArrayOES, WebGLId)
1261
1262 DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM,
1263                  WGC3Denum, WGC3Dint)
1264 DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM,
1265                  WGC3Denum, WGC3Dint)
1266
1267 DELEGATE_TO_GL_2R(mapBufferCHROMIUM, MapBufferCHROMIUM, WGC3Denum, WGC3Denum,
1268                   void*)
1269 DELEGATE_TO_GL_1R(unmapBufferCHROMIUM, UnmapBufferCHROMIUM, WGC3Denum,
1270                   WGC3Dboolean)
1271
1272 DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum,
1273                  WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint,
1274                  WGC3Denum, WGC3Denum, const void*)
1275 DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM,
1276                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1277                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1278
1279 DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM,
1280                  WGC3Denum)
1281
1282 DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*)
1283
1284 DELEGATE_TO_GL_4(drawArraysInstancedANGLE, DrawArraysInstancedANGLE, WGC3Denum,
1285                  WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1286
1287 void WebGraphicsContext3DCommandBufferImpl::drawElementsInstancedANGLE(
1288     WGC3Denum mode,
1289     WGC3Dsizei count,
1290     WGC3Denum type,
1291     WGC3Dintptr offset,
1292     WGC3Dsizei primcount) {
1293   gl_->DrawElementsInstancedANGLE(
1294       mode, count, type,
1295       reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount);
1296 }
1297
1298 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint,
1299                  WGC3Duint)
1300
1301 DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM,
1302                   WGC3Dsizei, WGC3Dsizei, WGC3Denum,
1303                   WGC3Duint);
1304
1305 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint);
1306
1307 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM,
1308                  WGC3Duint, WGC3Denum, GLint*);
1309
1310 DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM,
1311                   WGC3Duint, WGC3Denum, void*);
1312
1313 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint);
1314
1315 DELEGATE_TO_GL_6(framebufferTexture2DMultisampleEXT,
1316                  FramebufferTexture2DMultisampleEXT,
1317                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint, WGC3Dsizei)
1318
1319 DELEGATE_TO_GL_5(renderbufferStorageMultisampleEXT,
1320                  RenderbufferStorageMultisampleEXT, WGC3Denum, WGC3Dsizei,
1321                  WGC3Denum, WGC3Dsizei, WGC3Dsizei)
1322
1323 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::createGrGLInterface() {
1324   return skia_bindings::CreateCommandBufferSkiaGLBinding();
1325 }
1326
1327 namespace {
1328
1329 WGC3Denum convertReason(gpu::error::ContextLostReason reason) {
1330   switch (reason) {
1331   case gpu::error::kGuilty:
1332     return GL_GUILTY_CONTEXT_RESET_ARB;
1333   case gpu::error::kInnocent:
1334     return GL_INNOCENT_CONTEXT_RESET_ARB;
1335   case gpu::error::kUnknown:
1336     return GL_UNKNOWN_CONTEXT_RESET_ARB;
1337   }
1338
1339   NOTREACHED();
1340   return GL_UNKNOWN_CONTEXT_RESET_ARB;
1341 }
1342
1343 }  // anonymous namespace
1344
1345 void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() {
1346   context_lost_reason_ = convertReason(
1347       command_buffer_->GetLastState().context_lost_reason);
1348   if (context_lost_callback_) {
1349     context_lost_callback_->onContextLost();
1350   }
1351
1352   DCHECK(host_.get());
1353   {
1354     base::AutoLock lock(g_all_shared_contexts_lock.Get());
1355     g_all_shared_contexts.Get().erase(host_.get());
1356   }
1357 }
1358
1359 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage(
1360     const std::string& message, int id) {
1361   if (error_message_callback_) {
1362     blink::WebString str = blink::WebString::fromUTF8(message.c_str());
1363     error_message_callback_->onErrorMessage(str, id);
1364   }
1365 }
1366
1367 }  // namespace content