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