Home | History | Annotate | Download | only in client
      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 // TODO(apatrick,piman): This should be renamed to something clearer.
    481 int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() {
    482   return host_.get() ? host_->gpu_host_id() : 0;
    483 }
    484 
    485 gpu::ContextSupport*
    486 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() {
    487   return real_gl_.get();
    488 }
    489 
    490 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
    491   NOTREACHED();
    492 }
    493 
    494 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
    495     int x, int y, int width, int height) {
    496   NOTREACHED();
    497 }
    498 
    499 DELEGATE_TO_GL_3(reshapeWithScaleFactor, ResizeCHROMIUM, int, int, float)
    500 
    501 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError(
    502     WGC3Denum error) {
    503   if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
    504       synthetic_errors_.end()) {
    505     synthetic_errors_.push_back(error);
    506   }
    507 }
    508 
    509 DELEGATE_TO_GL_4R(mapBufferSubDataCHROMIUM, MapBufferSubDataCHROMIUM, WGC3Denum,
    510                   WGC3Dintptr, WGC3Dsizeiptr, WGC3Denum, void*)
    511 
    512 DELEGATE_TO_GL_1(unmapBufferSubDataCHROMIUM, UnmapBufferSubDataCHROMIUM,
    513                  const void*)
    514 
    515 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM(
    516     WGC3Denum target,
    517     WGC3Dint level,
    518     WGC3Dint xoffset,
    519     WGC3Dint yoffset,
    520     WGC3Dsizei width,
    521     WGC3Dsizei height,
    522     WGC3Denum format,
    523     WGC3Denum type,
    524     WGC3Denum access) {
    525   return gl_->MapTexSubImage2DCHROMIUM(
    526       target, level, xoffset, yoffset, width, height, format, type, access);
    527 }
    528 
    529 DELEGATE_TO_GL_1(unmapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM,
    530                  const void*)
    531 
    532 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM(
    533     bool visible) {
    534   NOTREACHED();
    535 }
    536 
    537 DELEGATE_TO_GL_3(discardFramebufferEXT, DiscardFramebufferEXT, WGC3Denum,
    538                  WGC3Dsizei, const WGC3Denum*)
    539 
    540 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM(
    541     WebGLId texture, WebGLId parentTexture) {
    542   NOTIMPLEMENTED();
    543 }
    544 
    545 DELEGATE_TO_GL(rateLimitOffscreenContextCHROMIUM,
    546                RateLimitOffscreenContextCHROMIUM)
    547 
    548 blink::WebString WebGraphicsContext3DCommandBufferImpl::
    549     getRequestableExtensionsCHROMIUM() {
    550   return blink::WebString::fromUTF8(
    551       gl_->GetRequestableExtensionsCHROMIUM());
    552 }
    553 
    554 DELEGATE_TO_GL_1(requestExtensionCHROMIUM, RequestExtensionCHROMIUM,
    555                  const char*)
    556 
    557 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM(
    558     WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
    559     WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
    560     WGC3Dbitfield mask, WGC3Denum filter) {
    561   gl_->BlitFramebufferCHROMIUM(
    562       srcX0, srcY0, srcX1, srcY1,
    563       dstX0, dstY0, dstX1, dstY1,
    564       mask, filter);
    565 }
    566 
    567 DELEGATE_TO_GL_5(renderbufferStorageMultisampleCHROMIUM,
    568                  RenderbufferStorageMultisampleCHROMIUM, WGC3Denum, WGC3Dsizei,
    569                  WGC3Denum, WGC3Dsizei, WGC3Dsizei)
    570 
    571 DELEGATE_TO_GL_1R(createStreamTextureCHROMIUM, CreateStreamTextureCHROMIUM,
    572                   WebGLId, WebGLId)
    573 
    574 DELEGATE_TO_GL_1(destroyStreamTextureCHROMIUM, DestroyStreamTextureCHROMIUM,
    575                  WebGLId)
    576 
    577 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
    578 
    579 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
    580 
    581 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId,
    582                  WGC3Duint, const WGC3Dchar*)
    583 
    584 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId)
    585 
    586 DELEGATE_TO_GL_2(bindFramebuffer, BindFramebuffer, WGC3Denum, WebGLId)
    587 
    588 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId)
    589 
    590 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId)
    591 
    592 DELEGATE_TO_GL_4(blendColor, BlendColor,
    593                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
    594 
    595 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
    596 
    597 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
    598                  WGC3Denum, WGC3Denum)
    599 
    600 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
    601 
    602 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
    603                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
    604 
    605 DELEGATE_TO_GL_4(bufferData, BufferData,
    606                  WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
    607 
    608 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
    609                  WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
    610 
    611 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus,
    612                   WGC3Denum, WGC3Denum)
    613 
    614 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
    615 
    616 DELEGATE_TO_GL_4(clearColor, ClearColor,
    617                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
    618 
    619 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf)
    620 
    621 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
    622 
    623 DELEGATE_TO_GL_4(colorMask, ColorMask,
    624                  WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
    625 
    626 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId)
    627 
    628 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
    629                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
    630                  WGC3Dsizei, WGC3Dsizei, const void*)
    631 
    632 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
    633                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
    634                  WGC3Denum, WGC3Dsizei, const void*)
    635 
    636 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D,
    637                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
    638                  WGC3Dsizei, WGC3Dsizei, WGC3Dint)
    639 
    640 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D,
    641                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
    642                  WGC3Dsizei, WGC3Dsizei)
    643 
    644 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
    645 
    646 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
    647 
    648 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
    649 
    650 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf)
    651 
    652 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
    653 
    654 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
    655 
    656 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray,
    657                  WGC3Duint)
    658 
    659 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
    660 
    661 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode,
    662                                                          WGC3Dsizei count,
    663                                                          WGC3Denum type,
    664                                                          WGC3Dintptr offset) {
    665   gl_->DrawElements(
    666       mode, count, type,
    667       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
    668 }
    669 
    670 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
    671 
    672 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray,
    673                  WGC3Duint)
    674 
    675 void WebGraphicsContext3DCommandBufferImpl::finish() {
    676   flush_id_ = GenFlushID();
    677   gl_->Finish();
    678 }
    679 
    680 void WebGraphicsContext3DCommandBufferImpl::flush() {
    681   flush_id_ = GenFlushID();
    682   gl_->Flush();
    683 }
    684 
    685 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer,
    686                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
    687 
    688 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D,
    689                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
    690 
    691 DELEGATE_TO_GL_6(framebufferTexture2DMultisampleEXT,
    692                  FramebufferTexture2DMultisampleEXT,
    693                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint, WGC3Dsizei)
    694 
    695 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
    696 
    697 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum)
    698 
    699 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib(
    700     WebGLId program, WGC3Duint index, ActiveInfo& info) {
    701   if (!program) {
    702     synthesizeGLError(GL_INVALID_VALUE);
    703     return false;
    704   }
    705   GLint max_name_length = -1;
    706   gl_->GetProgramiv(
    707       program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
    708   if (max_name_length < 0)
    709     return false;
    710   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
    711   if (!name) {
    712     synthesizeGLError(GL_OUT_OF_MEMORY);
    713     return false;
    714   }
    715   GLsizei length = 0;
    716   GLint size = -1;
    717   GLenum type = 0;
    718   gl_->GetActiveAttrib(
    719       program, index, max_name_length, &length, &size, &type, name.get());
    720   if (size < 0) {
    721     return false;
    722   }
    723   info.name = blink::WebString::fromUTF8(name.get(), length);
    724   info.type = type;
    725   info.size = size;
    726   return true;
    727 }
    728 
    729 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform(
    730     WebGLId program, WGC3Duint index, ActiveInfo& info) {
    731   GLint max_name_length = -1;
    732   gl_->GetProgramiv(
    733       program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
    734   if (max_name_length < 0)
    735     return false;
    736   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
    737   if (!name) {
    738     synthesizeGLError(GL_OUT_OF_MEMORY);
    739     return false;
    740   }
    741   GLsizei length = 0;
    742   GLint size = -1;
    743   GLenum type = 0;
    744   gl_->GetActiveUniform(
    745       program, index, max_name_length, &length, &size, &type, name.get());
    746   if (size < 0) {
    747     return false;
    748   }
    749   info.name = blink::WebString::fromUTF8(name.get(), length);
    750   info.type = type;
    751   info.size = size;
    752   return true;
    753 }
    754 
    755 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
    756                  WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
    757 
    758 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
    759                   WebGLId, const WGC3Dchar*, WGC3Dint)
    760 
    761 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*)
    762 
    763 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
    764                  WGC3Denum, WGC3Denum, WGC3Dint*)
    765 
    766 blink::WebGraphicsContext3D::Attributes
    767 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() {
    768   return attributes_;
    769 }
    770 
    771 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() {
    772   if (!synthetic_errors_.empty()) {
    773     std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
    774     WGC3Denum err = *iter;
    775     synthetic_errors_.erase(iter);
    776     return err;
    777   }
    778 
    779   return gl_->GetError();
    780 }
    781 
    782 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
    783   return initialize_failed_ ||
    784       (command_buffer_ && IsCommandBufferContextLost()) ||
    785       context_lost_reason_ != GL_NO_ERROR;
    786 }
    787 
    788 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
    789 
    790 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
    791                  GetFramebufferAttachmentParameteriv,
    792                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
    793 
    794 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
    795 
    796 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
    797 
    798 blink::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog(
    799     WebGLId program) {
    800   GLint logLength = 0;
    801   gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
    802   if (!logLength)
    803     return blink::WebString();
    804   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    805   if (!log)
    806     return blink::WebString();
    807   GLsizei returnedLogLength = 0;
    808   gl_->GetProgramInfoLog(
    809       program, logLength, &returnedLogLength, log.get());
    810   DCHECK_EQ(logLength, returnedLogLength + 1);
    811   blink::WebString res =
    812       blink::WebString::fromUTF8(log.get(), returnedLogLength);
    813   return res;
    814 }
    815 
    816 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv,
    817                  WGC3Denum, WGC3Denum, WGC3Dint*)
    818 
    819 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*)
    820 
    821 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog(
    822     WebGLId shader) {
    823   GLint logLength = 0;
    824   gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
    825   if (!logLength)
    826     return blink::WebString();
    827   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    828   if (!log)
    829     return blink::WebString();
    830   GLsizei returnedLogLength = 0;
    831   gl_->GetShaderInfoLog(
    832       shader, logLength, &returnedLogLength, log.get());
    833   DCHECK_EQ(logLength, returnedLogLength + 1);
    834   blink::WebString res =
    835       blink::WebString::fromUTF8(log.get(), returnedLogLength);
    836   return res;
    837 }
    838 
    839 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat,
    840                  WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*)
    841 
    842 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource(
    843     WebGLId shader) {
    844   GLint logLength = 0;
    845   gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
    846   if (!logLength)
    847     return blink::WebString();
    848   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    849   if (!log)
    850     return blink::WebString();
    851   GLsizei returnedLogLength = 0;
    852   gl_->GetShaderSource(
    853       shader, logLength, &returnedLogLength, log.get());
    854   if (!returnedLogLength)
    855     return blink::WebString();
    856   DCHECK_EQ(logLength, returnedLogLength + 1);
    857   blink::WebString res =
    858       blink::WebString::fromUTF8(log.get(), returnedLogLength);
    859   return res;
    860 }
    861 
    862 blink::WebString WebGraphicsContext3DCommandBufferImpl::
    863     getTranslatedShaderSourceANGLE(WebGLId shader) {
    864   GLint logLength = 0;
    865   gl_->GetShaderiv(
    866       shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength);
    867   if (!logLength)
    868     return blink::WebString();
    869   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    870   if (!log)
    871     return blink::WebString();
    872   GLsizei returnedLogLength = 0;
    873   gl_->GetTranslatedShaderSourceANGLE(
    874       shader, logLength, &returnedLogLength, log.get());
    875   if (!returnedLogLength)
    876     return blink::WebString();
    877   DCHECK_EQ(logLength, returnedLogLength + 1);
    878   blink::WebString res =
    879       blink::WebString::fromUTF8(log.get(), returnedLogLength);
    880   return res;
    881 }
    882 
    883 blink::WebString WebGraphicsContext3DCommandBufferImpl::getString(
    884     WGC3Denum name) {
    885   return blink::WebString::fromUTF8(
    886       reinterpret_cast<const char*>(gl_->GetString(name)));
    887 }
    888 
    889 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
    890                  WGC3Denum, WGC3Denum, WGC3Dfloat*)
    891 
    892 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
    893                  WGC3Denum, WGC3Denum, WGC3Dint*)
    894 
    895 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
    896 
    897 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
    898 
    899 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
    900                   WebGLId, const WGC3Dchar*, WGC3Dint)
    901 
    902 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
    903                  WGC3Duint, WGC3Denum, WGC3Dfloat*)
    904 
    905 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
    906                  WGC3Duint, WGC3Denum, WGC3Dint*)
    907 
    908 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset(
    909     WGC3Duint index, WGC3Denum pname) {
    910   GLvoid* value = NULL;
    911   // NOTE: If pname is ever a value that returns more then 1 element
    912   // this will corrupt memory.
    913   gl_->GetVertexAttribPointerv(index, pname, &value);
    914   return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value));
    915 }
    916 
    917 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
    918 
    919 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
    920 
    921 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
    922 
    923 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean)
    924 
    925 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
    926 
    927 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean)
    928 
    929 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
    930 
    931 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
    932 
    933 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
    934 
    935 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
    936 
    937 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
    938 
    939 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
    940 
    941 DELEGATE_TO_GL_7(readPixels, ReadPixels,
    942                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum,
    943                  WGC3Denum, void*)
    944 
    945 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() {
    946 }
    947 
    948 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage,
    949                  WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei)
    950 
    951 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean)
    952 
    953 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
    954 
    955 void WebGraphicsContext3DCommandBufferImpl::shaderSource(
    956     WebGLId shader, const WGC3Dchar* string) {
    957   GLint length = strlen(string);
    958   gl_->ShaderSource(shader, 1, &string, &length);
    959 }
    960 
    961 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
    962 
    963 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
    964                  WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
    965 
    966 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
    967 
    968 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
    969                  WGC3Denum, WGC3Duint)
    970 
    971 DELEGATE_TO_GL_3(stencilOp, StencilOp,
    972                  WGC3Denum, WGC3Denum, WGC3Denum)
    973 
    974 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
    975                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
    976 
    977 DELEGATE_TO_GL_9(texImage2D, TexImage2D,
    978                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei,
    979                  WGC3Dint, WGC3Denum, WGC3Denum, const void*)
    980 
    981 DELEGATE_TO_GL_3(texParameterf, TexParameterf,
    982                  WGC3Denum, WGC3Denum, WGC3Dfloat);
    983 
    984 static const unsigned int kTextureWrapR = 0x8072;
    985 
    986 void WebGraphicsContext3DCommandBufferImpl::texParameteri(
    987     WGC3Denum target, WGC3Denum pname, WGC3Dint param) {
    988   // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in
    989   // GraphicsContext3D.cpp is strictly necessary to avoid seams at the
    990   // edge of cube maps, and, if it is, push it into the GLES2 service
    991   // side code.
    992   if (pname == kTextureWrapR) {
    993     return;
    994   }
    995   gl_->TexParameteri(target, pname, param);
    996 }
    997 
    998 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
    999                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
   1000                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
   1001 
   1002 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
   1003 
   1004 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei,
   1005                  const WGC3Dfloat*)
   1006 
   1007 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
   1008 
   1009 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1010 
   1011 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
   1012 
   1013 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei,
   1014                  const WGC3Dfloat*)
   1015 
   1016 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
   1017 
   1018 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1019 
   1020 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint,
   1021                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1022 
   1023 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei,
   1024                  const WGC3Dfloat*)
   1025 
   1026 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
   1027 
   1028 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1029 
   1030 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
   1031                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1032 
   1033 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei,
   1034                  const WGC3Dfloat*)
   1035 
   1036 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
   1037                  WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
   1038 
   1039 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1040 
   1041 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
   1042                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1043 
   1044 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
   1045                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1046 
   1047 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
   1048                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1049 
   1050 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
   1051 
   1052 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
   1053 
   1054 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
   1055 
   1056 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint,
   1057                  const WGC3Dfloat*)
   1058 
   1059 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint,
   1060                  WGC3Dfloat, WGC3Dfloat)
   1061 
   1062 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint,
   1063                  const WGC3Dfloat*)
   1064 
   1065 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint,
   1066                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1067 
   1068 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint,
   1069                  const WGC3Dfloat*)
   1070 
   1071 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint,
   1072                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1073 
   1074 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint,
   1075                  const WGC3Dfloat*)
   1076 
   1077 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer(
   1078     WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
   1079     WGC3Dsizei stride, WGC3Dintptr offset) {
   1080   gl_->VertexAttribPointer(
   1081       index, size, type, normalized, stride,
   1082       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
   1083 }
   1084 
   1085 DELEGATE_TO_GL_4(viewport, Viewport,
   1086                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
   1087 
   1088 DELEGATE_TO_GL_2(genBuffers, GenBuffers, WGC3Dsizei, WebGLId*);
   1089 
   1090 DELEGATE_TO_GL_2(genFramebuffers, GenFramebuffers, WGC3Dsizei, WebGLId*);
   1091 
   1092 DELEGATE_TO_GL_2(genRenderbuffers, GenRenderbuffers, WGC3Dsizei, WebGLId*);
   1093 
   1094 DELEGATE_TO_GL_2(genTextures, GenTextures, WGC3Dsizei, WebGLId*);
   1095 
   1096 DELEGATE_TO_GL_2(deleteBuffers, DeleteBuffers, WGC3Dsizei, WebGLId*);
   1097 
   1098 DELEGATE_TO_GL_2(deleteFramebuffers, DeleteFramebuffers, WGC3Dsizei, WebGLId*);
   1099 
   1100 DELEGATE_TO_GL_2(deleteRenderbuffers, DeleteRenderbuffers, WGC3Dsizei,
   1101                  WebGLId*);
   1102 
   1103 DELEGATE_TO_GL_2(deleteTextures, DeleteTextures, WGC3Dsizei, WebGLId*);
   1104 
   1105 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() {
   1106   GLuint o;
   1107   gl_->GenBuffers(1, &o);
   1108   return o;
   1109 }
   1110 
   1111 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() {
   1112   GLuint o = 0;
   1113   gl_->GenFramebuffers(1, &o);
   1114   return o;
   1115 }
   1116 
   1117 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() {
   1118   GLuint o;
   1119   gl_->GenRenderbuffers(1, &o);
   1120   return o;
   1121 }
   1122 
   1123 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() {
   1124   GLuint o;
   1125   gl_->GenTextures(1, &o);
   1126   return o;
   1127 }
   1128 
   1129 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) {
   1130   gl_->DeleteBuffers(1, &buffer);
   1131 }
   1132 
   1133 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer(
   1134     WebGLId framebuffer) {
   1135   gl_->DeleteFramebuffers(1, &framebuffer);
   1136 }
   1137 
   1138 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer(
   1139     WebGLId renderbuffer) {
   1140   gl_->DeleteRenderbuffers(1, &renderbuffer);
   1141 }
   1142 
   1143 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
   1144   gl_->DeleteTextures(1, &texture);
   1145 }
   1146 
   1147 DELEGATE_TO_GL_R(createProgram, CreateProgram, WebGLId)
   1148 
   1149 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId)
   1150 
   1151 DELEGATE_TO_GL_1(deleteProgram, DeleteProgram, WebGLId)
   1152 
   1153 DELEGATE_TO_GL_1(deleteShader, DeleteShader, WebGLId)
   1154 
   1155 void WebGraphicsContext3DCommandBufferImpl::setErrorMessageCallback(
   1156     WebGraphicsContext3D::WebGraphicsErrorMessageCallback* cb) {
   1157   error_message_callback_ = cb;
   1158 }
   1159 
   1160 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback(
   1161     WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) {
   1162   context_lost_callback_ = cb;
   1163 }
   1164 
   1165 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() {
   1166   if (IsCommandBufferContextLost() &&
   1167       context_lost_reason_ == GL_NO_ERROR) {
   1168     return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1169   }
   1170 
   1171   return context_lost_reason_;
   1172 }
   1173 
   1174 bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
   1175   // If the channel shut down unexpectedly, let that supersede the
   1176   // command buffer's state.
   1177   if (host_.get() && host_->IsLost())
   1178     return true;
   1179   gpu::CommandBuffer::State state = command_buffer_->GetLastState();
   1180   return state.error == gpu::error::kLostContext;
   1181 }
   1182 
   1183 // static
   1184 WebGraphicsContext3DCommandBufferImpl*
   1185 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
   1186     GpuChannelHost* host,
   1187     const WebGraphicsContext3D::Attributes& attributes,
   1188     const GURL& active_url,
   1189     const SharedMemoryLimits& limits) {
   1190   if (!host)
   1191     return NULL;
   1192   return new WebGraphicsContext3DCommandBufferImpl(0,
   1193                                                    active_url,
   1194                                                    host,
   1195                                                    attributes,
   1196                                                    false,
   1197                                                    limits);
   1198 }
   1199 
   1200 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM,
   1201                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint)
   1202 
   1203 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
   1204                  WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
   1205 
   1206 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() {
   1207   GLuint o;
   1208   gl_->GenQueriesEXT(1, &o);
   1209   return o;
   1210 }
   1211 
   1212 void WebGraphicsContext3DCommandBufferImpl::deleteQueryEXT(
   1213     WebGLId query) {
   1214   gl_->DeleteQueriesEXT(1, &query);
   1215 }
   1216 
   1217 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean)
   1218 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId)
   1219 DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum)
   1220 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*)
   1221 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
   1222                  WebGLId, WGC3Denum, WGC3Duint*)
   1223 
   1224 DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM,  WGC3Denum,
   1225                  WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
   1226 
   1227 DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
   1228                  WebGLId, WGC3Dint, const WGC3Dchar*)
   1229 
   1230 void WebGraphicsContext3DCommandBufferImpl::shallowFlushCHROMIUM() {
   1231   flush_id_ = GenFlushID();
   1232   gl_->ShallowFlushCHROMIUM();
   1233 }
   1234 
   1235 void WebGraphicsContext3DCommandBufferImpl::shallowFinishCHROMIUM() {
   1236   flush_id_ = GenFlushID();
   1237   gl_->ShallowFinishCHROMIUM();
   1238 }
   1239 
   1240 DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint)
   1241 
   1242 void WebGraphicsContext3DCommandBufferImpl::loseContextCHROMIUM(
   1243     WGC3Denum current, WGC3Denum other) {
   1244   gl_->LoseContextCHROMIUM(current, other);
   1245   gl_->Flush();
   1246 }
   1247 
   1248 DELEGATE_TO_GL_1(genMailboxCHROMIUM, GenMailboxCHROMIUM, WGC3Dbyte*)
   1249 DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM,
   1250                  WGC3Denum, const WGC3Dbyte*)
   1251 DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM,
   1252                  WGC3Denum, const WGC3Dbyte*)
   1253 
   1254 void WebGraphicsContext3DCommandBufferImpl::insertEventMarkerEXT(
   1255     const WGC3Dchar* marker) {
   1256   gl_->InsertEventMarkerEXT(0, marker);
   1257 }
   1258 
   1259 void WebGraphicsContext3DCommandBufferImpl::pushGroupMarkerEXT(
   1260     const WGC3Dchar* marker) {
   1261   gl_->PushGroupMarkerEXT(0, marker);
   1262 }
   1263 
   1264 DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT);
   1265 
   1266 WebGLId WebGraphicsContext3DCommandBufferImpl::createVertexArrayOES() {
   1267   GLuint array;
   1268   gl_->GenVertexArraysOES(1, &array);
   1269   return array;
   1270 }
   1271 
   1272 void WebGraphicsContext3DCommandBufferImpl::deleteVertexArrayOES(
   1273     WebGLId array) {
   1274   gl_->DeleteVertexArraysOES(1, &array);
   1275 }
   1276 
   1277 DELEGATE_TO_GL_1R(isVertexArrayOES, IsVertexArrayOES, WebGLId, WGC3Dboolean)
   1278 DELEGATE_TO_GL_1(bindVertexArrayOES, BindVertexArrayOES, WebGLId)
   1279 
   1280 DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM,
   1281                  WGC3Denum, WGC3Dint)
   1282 DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM,
   1283                  WGC3Denum, WGC3Dint)
   1284 
   1285 DELEGATE_TO_GL_2R(mapBufferCHROMIUM, MapBufferCHROMIUM, WGC3Denum, WGC3Denum,
   1286                   void*)
   1287 DELEGATE_TO_GL_1R(unmapBufferCHROMIUM, UnmapBufferCHROMIUM, WGC3Denum,
   1288                   WGC3Dboolean)
   1289 
   1290 DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum,
   1291                  WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint,
   1292                  WGC3Denum, WGC3Denum, const void*)
   1293 DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM,
   1294                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
   1295                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
   1296 
   1297 DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM,
   1298                  WGC3Denum)
   1299 
   1300 DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*)
   1301 
   1302 DELEGATE_TO_GL_4(drawArraysInstancedANGLE, DrawArraysInstancedANGLE, WGC3Denum,
   1303                  WGC3Dint, WGC3Dsizei, WGC3Dsizei)
   1304 
   1305 void WebGraphicsContext3DCommandBufferImpl::drawElementsInstancedANGLE(
   1306     WGC3Denum mode,
   1307     WGC3Dsizei count,
   1308     WGC3Denum type,
   1309     WGC3Dintptr offset,
   1310     WGC3Dsizei primcount) {
   1311   gl_->DrawElementsInstancedANGLE(
   1312       mode, count, type,
   1313       reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount);
   1314 }
   1315 
   1316 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint,
   1317                  WGC3Duint)
   1318 
   1319 DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM,
   1320                   WGC3Dsizei, WGC3Dsizei, WGC3Denum,
   1321                   WGC3Duint);
   1322 
   1323 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint);
   1324 
   1325 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM,
   1326                  WGC3Duint, WGC3Denum, GLint*);
   1327 
   1328 DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM,
   1329                   WGC3Duint, WGC3Denum, void*);
   1330 
   1331 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint);
   1332 
   1333 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::createGrGLInterface() {
   1334   return skia_bindings::CreateCommandBufferSkiaGLBinding();
   1335 }
   1336 
   1337 namespace {
   1338 
   1339 WGC3Denum convertReason(gpu::error::ContextLostReason reason) {
   1340   switch (reason) {
   1341   case gpu::error::kGuilty:
   1342     return GL_GUILTY_CONTEXT_RESET_ARB;
   1343   case gpu::error::kInnocent:
   1344     return GL_INNOCENT_CONTEXT_RESET_ARB;
   1345   case gpu::error::kUnknown:
   1346     return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1347   }
   1348 
   1349   NOTREACHED();
   1350   return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1351 }
   1352 
   1353 }  // anonymous namespace
   1354 
   1355 void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() {
   1356   context_lost_reason_ = convertReason(
   1357       command_buffer_->GetLastState().context_lost_reason);
   1358   if (context_lost_callback_) {
   1359     context_lost_callback_->onContextLost();
   1360   }
   1361 
   1362   DCHECK(host_.get());
   1363   {
   1364     base::AutoLock lock(g_all_shared_contexts_lock.Get());
   1365     g_all_shared_contexts.Get().erase(host_.get());
   1366   }
   1367 }
   1368 
   1369 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage(
   1370     const std::string& message, int id) {
   1371   if (error_message_callback_) {
   1372     blink::WebString str = blink::WebString::fromUTF8(message.c_str());
   1373     error_message_callback_->onErrorMessage(str, id);
   1374   }
   1375 }
   1376 
   1377 }  // namespace content
   1378