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 <set>
     15 
     16 #include "base/bind.h"
     17 #include "base/command_line.h"
     18 #include "base/debug/trace_event.h"
     19 #include "base/lazy_instance.h"
     20 #include "base/logging.h"
     21 #include "base/message_loop/message_loop.h"
     22 #include "base/metrics/field_trial.h"
     23 #include "base/metrics/histogram.h"
     24 #include "base/synchronization/lock.h"
     25 #include "content/common/gpu/client/gpu_channel_host.h"
     26 #include "content/common/gpu/gpu_memory_allocation.h"
     27 #include "content/common/gpu/gpu_process_launch_causes.h"
     28 #include "content/public/common/content_constants.h"
     29 #include "content/public/common/content_switches.h"
     30 #include "gpu/GLES2/gl2extchromium.h"
     31 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
     32 #include "gpu/command_buffer/client/gles2_implementation.h"
     33 #include "gpu/command_buffer/client/gles2_lib.h"
     34 #include "gpu/command_buffer/client/gles2_trace_implementation.h"
     35 #include "gpu/command_buffer/client/transfer_buffer.h"
     36 #include "gpu/command_buffer/common/constants.h"
     37 #include "gpu/command_buffer/common/mailbox.h"
     38 #include "gpu/ipc/command_buffer_proxy.h"
     39 #include "third_party/skia/include/core/SkTypes.h"
     40 #include "webkit/common/gpu/gl_bindings_skia_cmd_buffer.h"
     41 
     42 namespace content {
     43 static base::LazyInstance<base::Lock>::Leaky
     44     g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
     45 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
     46     g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
     47 
     48 namespace {
     49 
     50 void ClearSharedContextsIfInShareSet(
     51     WebGraphicsContext3DCommandBufferImpl* context) {
     52   // If the given context isn't in the share set, that means that it
     53   // or another context it was previously sharing with already
     54   // provoked a lost context. Other contexts might have since been
     55   // successfully created and added to the share set, so do not clear
     56   // out the share set unless we know that all the contexts in there
     57   // are supposed to be lost simultaneously.
     58   base::AutoLock lock(g_all_shared_contexts_lock.Get());
     59   std::set<WebGraphicsContext3DCommandBufferImpl*>* share_set =
     60       g_all_shared_contexts.Pointer();
     61   for (std::set<WebGraphicsContext3DCommandBufferImpl*>::iterator iter =
     62            share_set->begin(); iter != share_set->end(); ++iter) {
     63     if (context == *iter) {
     64       share_set->clear();
     65       return;
     66     }
     67   }
     68 }
     69 
     70 size_t ClampUint64ToSizeT(uint64 value) {
     71   value = std::min(value,
     72                    static_cast<uint64>(std::numeric_limits<size_t>::max()));
     73   return static_cast<size_t>(value);
     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_4(name, glname, t1, t2, t3, t4)                  \
    143 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    144                                                  t4 a4) {               \
    145   gl_->glname(a1, a2, a3, a4);                                          \
    146 }
    147 
    148 #define DELEGATE_TO_GL_4R(name, glname, t1, t2, t3, t4, rt)             \
    149 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,     \
    150                                                t4 a4) {                 \
    151   return gl_->glname(a1, a2, a3, a4);                                   \
    152 }
    153 
    154 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5)              \
    155 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    156                                                  t4 a4, t5 a5) {        \
    157   gl_->glname(a1, a2, a3, a4, a5);                                      \
    158 }
    159 
    160 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6)          \
    161 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    162                                                  t4 a4, t5 a5, t6 a6) { \
    163   gl_->glname(a1, a2, a3, a4, a5, a6);                                  \
    164 }
    165 
    166 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7)      \
    167 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    168                                                  t4 a4, t5 a5, t6 a6,   \
    169                                                  t7 a7) {               \
    170   gl_->glname(a1, a2, a3, a4, a5, a6, a7);                              \
    171 }
    172 
    173 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8)  \
    174 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    175                                                  t4 a4, t5 a5, t6 a6,   \
    176                                                  t7 a7, t8 a8) {        \
    177   gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8);                          \
    178 }
    179 
    180 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
    181 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3,   \
    182                                                  t4 a4, t5 a5, t6 a6,   \
    183                                                  t7 a7, t8 a8, t9 a9) { \
    184   gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9);                      \
    185 }
    186 
    187 class WebGraphicsContext3DErrorMessageCallback
    188     : public gpu::gles2::GLES2Implementation::ErrorMessageCallback {
    189  public:
    190   WebGraphicsContext3DErrorMessageCallback(
    191       WebGraphicsContext3DCommandBufferImpl* context)
    192       : graphics_context_(context) {
    193   }
    194 
    195   virtual void OnErrorMessage(const char* msg, int id) OVERRIDE;
    196 
    197  private:
    198   WebGraphicsContext3DCommandBufferImpl* graphics_context_;
    199 
    200   DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DErrorMessageCallback);
    201 };
    202 
    203 void WebGraphicsContext3DErrorMessageCallback::OnErrorMessage(
    204     const char* msg, int id) {
    205   graphics_context_->OnErrorMessage(msg, id);
    206 }
    207 
    208 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
    209     int surface_id,
    210     const GURL& active_url,
    211     GpuChannelHostFactory* factory,
    212     const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client)
    213     : initialize_failed_(false),
    214       factory_(factory),
    215       visible_(false),
    216       free_command_buffer_when_invisible_(false),
    217       host_(NULL),
    218       surface_id_(surface_id),
    219       active_url_(active_url),
    220       swap_client_(swap_client),
    221       context_lost_callback_(0),
    222       context_lost_reason_(GL_NO_ERROR),
    223       error_message_callback_(0),
    224       swapbuffers_complete_callback_(0),
    225       gpu_preference_(gfx::PreferIntegratedGpu),
    226       cached_width_(0),
    227       cached_height_(0),
    228       weak_ptr_factory_(this),
    229       initialized_(false),
    230       gl_(NULL),
    231       frame_number_(0),
    232       bind_generates_resources_(false),
    233       use_echo_for_swap_ack_(true),
    234       command_buffer_size_(0),
    235       start_transfer_buffer_size_(0),
    236       min_transfer_buffer_size_(0),
    237       max_transfer_buffer_size_(0) {
    238 #if (defined(OS_MACOSX) || defined(OS_WIN)) && !defined(USE_AURA)
    239   // Get ViewMsg_SwapBuffers_ACK from browser for single-threaded path.
    240   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    241   use_echo_for_swap_ack_ =
    242       command_line.HasSwitch(switches::kEnableThreadedCompositing);
    243 #endif
    244 }
    245 
    246 WebGraphicsContext3DCommandBufferImpl::
    247     ~WebGraphicsContext3DCommandBufferImpl() {
    248   if (real_gl_) {
    249     real_gl_->SetErrorMessageCallback(NULL);
    250   }
    251 
    252   {
    253     base::AutoLock lock(g_all_shared_contexts_lock.Get());
    254     g_all_shared_contexts.Pointer()->erase(this);
    255   }
    256   Destroy();
    257 }
    258 
    259 bool WebGraphicsContext3DCommandBufferImpl::InitializeWithDefaultBufferSizes(
    260     const WebGraphicsContext3D::Attributes& attributes,
    261     bool bind_generates_resources,
    262     CauseForGpuLaunch cause) {
    263   return Initialize(attributes,
    264                     bind_generates_resources,
    265                     cause,
    266                     kDefaultCommandBufferSize,
    267                     kDefaultStartTransferBufferSize,
    268                     kDefaultMinTransferBufferSize,
    269                     kDefaultMaxTransferBufferSize);
    270 }
    271 
    272 bool WebGraphicsContext3DCommandBufferImpl::Initialize(
    273     const WebGraphicsContext3D::Attributes& attributes,
    274     bool bind_generates_resources,
    275     CauseForGpuLaunch cause,
    276     size_t command_buffer_size,
    277     size_t start_transfer_buffer_size,
    278     size_t min_transfer_buffer_size,
    279     size_t max_transfer_buffer_size) {
    280   TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
    281 
    282   attributes_ = attributes;
    283   bind_generates_resources_ = bind_generates_resources;
    284   DCHECK(!command_buffer_);
    285 
    286   if (!factory_)
    287     return false;
    288 
    289   if (attributes.preferDiscreteGPU)
    290     gpu_preference_ = gfx::PreferDiscreteGpu;
    291 
    292   host_ = factory_->EstablishGpuChannelSync(cause);
    293   if (!host_.get())
    294     return false;
    295 
    296   command_buffer_size_ = command_buffer_size;
    297   start_transfer_buffer_size_ = start_transfer_buffer_size;
    298   min_transfer_buffer_size_ = min_transfer_buffer_size;
    299   max_transfer_buffer_size_ = max_transfer_buffer_size;
    300 
    301   return true;
    302 }
    303 
    304 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL(
    305     const char* allowed_extensions) {
    306   if (initialized_)
    307     return true;
    308 
    309   if (initialize_failed_)
    310     return false;
    311 
    312   TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
    313 
    314   const char* preferred_extensions = "*";
    315 
    316   if (!CreateContext(surface_id_ != 0,
    317                      allowed_extensions ?
    318                          allowed_extensions : preferred_extensions)) {
    319     Destroy();
    320     initialize_failed_ = true;
    321     return false;
    322   }
    323 
    324   // TODO(twiz):  This code is too fragile in that it assumes that only WebGL
    325   // contexts will request noExtensions.
    326   if (gl_ && attributes_.noExtensions)
    327     gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation");
    328 
    329   command_buffer_->SetChannelErrorCallback(
    330       base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost,
    331                  weak_ptr_factory_.GetWeakPtr()));
    332 
    333   command_buffer_->SetOnConsoleMessageCallback(
    334       base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnErrorMessage,
    335                  weak_ptr_factory_.GetWeakPtr()));
    336 
    337   client_error_message_callback_.reset(
    338       new WebGraphicsContext3DErrorMessageCallback(this));
    339   real_gl_->SetErrorMessageCallback(client_error_message_callback_.get());
    340 
    341   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    342   free_command_buffer_when_invisible_ =
    343       command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers);
    344 
    345   // Set attributes_ from created offscreen context.
    346   {
    347     static const int pcount = 4;
    348     static const GLenum pnames[pcount] = {
    349       GL_ALPHA_BITS,
    350       GL_DEPTH_BITS,
    351       GL_STENCIL_BITS,
    352       GL_SAMPLE_BUFFERS,
    353     };
    354     GLint pvalues[pcount] = { 0, 0, 0, 0 };
    355 
    356     gl_->GetMultipleIntegervCHROMIUM(pnames, pcount,
    357                                      pvalues, sizeof(pvalues));
    358 
    359     attributes_.alpha = pvalues[0] > 0;
    360     attributes_.depth = pvalues[1] > 0;
    361     attributes_.stencil = pvalues[2] > 0;
    362     attributes_.antialias = pvalues[3] > 0;
    363   }
    364 
    365   visible_ = true;
    366   initialized_ = true;
    367   return true;
    368 }
    369 
    370 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
    371     bool onscreen,
    372     const char* allowed_extensions) {
    373   if (!host_.get())
    374     return false;
    375   // We need to lock g_all_shared_contexts to ensure that the context we picked
    376   // for our share group isn't deleted.
    377   // (There's also a lock in our destructor.)
    378   base::AutoLock lock(g_all_shared_contexts_lock.Get());
    379   CommandBufferProxyImpl* share_group = NULL;
    380   if (attributes_.shareResources) {
    381     WebGraphicsContext3DCommandBufferImpl* share_group_context =
    382         g_all_shared_contexts.Pointer()->empty() ?
    383             NULL : *g_all_shared_contexts.Pointer()->begin();
    384     share_group = share_group_context ?
    385         share_group_context->command_buffer_.get() : NULL;
    386   }
    387 
    388   std::vector<int32> attribs;
    389   attribs.push_back(ALPHA_SIZE);
    390   attribs.push_back(attributes_.alpha ? 8 : 0);
    391   attribs.push_back(DEPTH_SIZE);
    392   attribs.push_back(attributes_.depth ? 24 : 0);
    393   attribs.push_back(STENCIL_SIZE);
    394   attribs.push_back(attributes_.stencil ? 8 : 0);
    395   attribs.push_back(SAMPLES);
    396   attribs.push_back(attributes_.antialias ? 4 : 0);
    397   attribs.push_back(SAMPLE_BUFFERS);
    398   attribs.push_back(attributes_.antialias ? 1 : 0);
    399   attribs.push_back(NONE);
    400 
    401   // Create a proxy to a command buffer in the GPU process.
    402   if (onscreen) {
    403     command_buffer_.reset(host_->CreateViewCommandBuffer(
    404         surface_id_,
    405         share_group,
    406         allowed_extensions,
    407         attribs,
    408         active_url_,
    409         gpu_preference_));
    410   } else {
    411     command_buffer_.reset(host_->CreateOffscreenCommandBuffer(
    412         gfx::Size(1, 1),
    413         share_group,
    414         allowed_extensions,
    415         attribs,
    416         active_url_,
    417         gpu_preference_));
    418   }
    419 
    420   if (!command_buffer_)
    421     return false;
    422 
    423   // Initialize the command buffer.
    424   return command_buffer_->Initialize();
    425 }
    426 
    427 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
    428     bool onscreen,
    429     const char* allowed_extensions) {
    430 
    431   // Ensure the gles2 library is initialized first in a thread safe way.
    432   g_gles2_initializer.Get();
    433 
    434   if (!command_buffer_ &&
    435       !InitializeCommandBuffer(onscreen,
    436                                allowed_extensions)) {
    437     return false;
    438   }
    439 
    440   // Create the GLES2 helper, which writes the command buffer protocol.
    441   gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
    442   if (!gles2_helper_->Initialize(command_buffer_size_))
    443     return false;
    444 
    445   if (attributes_.noAutomaticFlushes)
    446     gles2_helper_->SetAutomaticFlushes(false);
    447 
    448   // Create a transfer buffer used to copy resources between the renderer
    449   // process and the GPU process.
    450   transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get()));
    451 
    452   scoped_ptr<base::AutoLock> lock;
    453   scoped_refptr<gpu::gles2::ShareGroup> share_group;
    454   if (attributes_.shareResources) {
    455     // Make sure two clients don't try to create a new ShareGroup
    456     // simultaneously.
    457     lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
    458     if (!g_all_shared_contexts.Pointer()->empty()) {
    459       share_group = (*g_all_shared_contexts.Pointer()->begin())
    460           ->GetImplementation()->share_group();
    461       DCHECK(share_group);
    462     }
    463   }
    464 
    465   // Create the object exposing the OpenGL API.
    466   real_gl_.reset(new gpu::gles2::GLES2Implementation(
    467       gles2_helper_.get(),
    468       share_group,
    469       transfer_buffer_.get(),
    470       bind_generates_resources_,
    471       NULL));
    472   gl_ = real_gl_.get();
    473 
    474   if (attributes_.shareResources) {
    475     // Don't add ourselves to the list before others can get to our ShareGroup.
    476     g_all_shared_contexts.Pointer()->insert(this);
    477     lock.reset();
    478   }
    479 
    480   if (!real_gl_->Initialize(
    481       start_transfer_buffer_size_,
    482       min_transfer_buffer_size_,
    483       max_transfer_buffer_size_)) {
    484     return false;
    485   }
    486 
    487   if (CommandLine::ForCurrentProcess()->HasSwitch(
    488       switches::kEnableGpuClientTracing)) {
    489     trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_));
    490     gl_ = trace_gl_.get();
    491   }
    492 
    493   return true;
    494 }
    495 
    496 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
    497   if (!MaybeInitializeGL(NULL))
    498     return false;
    499   gles2::SetGLContext(gl_);
    500   if (command_buffer_->GetLastError() != gpu::error::kNoError)
    501     return false;
    502 
    503   return true;
    504 }
    505 
    506 int WebGraphicsContext3DCommandBufferImpl::width() {
    507   return cached_width_;
    508 }
    509 
    510 int WebGraphicsContext3DCommandBufferImpl::height() {
    511   return cached_height_;
    512 }
    513 
    514 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int)
    515 
    516 void WebGraphicsContext3DCommandBufferImpl::Destroy() {
    517   if (gl_) {
    518     // First flush the context to ensure that any pending frees of resources
    519     // are completed. Otherwise, if this context is part of a share group,
    520     // those resources might leak. Also, any remaining side effects of commands
    521     // issued on this context might not be visible to other contexts in the
    522     // share group.
    523     gl_->Flush();
    524     gl_ = NULL;
    525   }
    526 
    527   trace_gl_.reset();
    528   real_gl_.reset();
    529   transfer_buffer_.reset();
    530   gles2_helper_.reset();
    531   real_gl_.reset();
    532 
    533   if (command_buffer_) {
    534     if (host_.get())
    535       host_->DestroyCommandBuffer(command_buffer_.release());
    536     command_buffer_.reset();
    537   }
    538 
    539   host_ = NULL;
    540 }
    541 
    542 // TODO(apatrick,piman): This should be renamed to something clearer.
    543 int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() {
    544   return host_.get() ? host_->gpu_host_id() : 0;
    545 }
    546 
    547 int WebGraphicsContext3DCommandBufferImpl::GetChannelID() {
    548   return host_.get() ? host_->client_id() : 0;
    549 }
    550 
    551 int WebGraphicsContext3DCommandBufferImpl::GetContextID() {
    552   return command_buffer_->GetRouteID();
    553 }
    554 
    555 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
    556   TRACE_EVENT1("gpu",
    557                 "WebGraphicsContext3DCommandBufferImpl::SwapBuffers",
    558                 "frame", frame_number_);
    559   frame_number_++;
    560   // Copies the contents of the off-screen render target into the texture
    561   // used by the compositor.
    562   if (ShouldUseSwapClient())
    563     swap_client_->OnViewContextSwapBuffersPosted();
    564 
    565   if (command_buffer_->GetLastState().error == gpu::error::kNoError)
    566     gl_->SwapBuffers();
    567 
    568   if (use_echo_for_swap_ack_) {
    569     command_buffer_->Echo(base::Bind(
    570         &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
    571         weak_ptr_factory_.GetWeakPtr()));
    572   }
    573 #if defined(OS_MACOSX)
    574   // It appears that making the compositor's on-screen context current on
    575   // other platforms implies this flush. TODO(kbr): this means that the
    576   // TOUCH build and, in the future, other platforms might need this.
    577   gl_->Flush();
    578 #endif
    579 }
    580 
    581 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
    582     int x, int y, int width, int height) {
    583   // Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture
    584   // (see above).
    585   if (ShouldUseSwapClient())
    586     swap_client_->OnViewContextSwapBuffersPosted();
    587   gl_->PostSubBufferCHROMIUM(x, y, width, height);
    588   command_buffer_->Echo(base::Bind(
    589       &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
    590       weak_ptr_factory_.GetWeakPtr()));
    591 }
    592 
    593 void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) {
    594   reshapeWithScaleFactor(width, height, 1.f);
    595 }
    596 
    597 void WebGraphicsContext3DCommandBufferImpl::reshapeWithScaleFactor(
    598     int width, int height, float scale_factor) {
    599   cached_width_ = width;
    600   cached_height_ = height;
    601 
    602   gl_->ResizeCHROMIUM(width, height, scale_factor);
    603 }
    604 
    605 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError(
    606     WGC3Denum error) {
    607   if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
    608       synthetic_errors_.end()) {
    609     synthetic_errors_.push_back(error);
    610   }
    611 }
    612 
    613 DELEGATE_TO_GL_4R(mapBufferSubDataCHROMIUM, MapBufferSubDataCHROMIUM, WGC3Denum,
    614                   WGC3Dintptr, WGC3Dsizeiptr, WGC3Denum, void*)
    615 
    616 DELEGATE_TO_GL_1(unmapBufferSubDataCHROMIUM, UnmapBufferSubDataCHROMIUM,
    617                  const void*)
    618 
    619 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM(
    620     WGC3Denum target,
    621     WGC3Dint level,
    622     WGC3Dint xoffset,
    623     WGC3Dint yoffset,
    624     WGC3Dsizei width,
    625     WGC3Dsizei height,
    626     WGC3Denum format,
    627     WGC3Denum type,
    628     WGC3Denum access) {
    629   return gl_->MapTexSubImage2DCHROMIUM(
    630       target, level, xoffset, yoffset, width, height, format, type, access);
    631 }
    632 
    633 DELEGATE_TO_GL_1(unmapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM,
    634                  const void*)
    635 
    636 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM(
    637     bool visible) {
    638   gl_->Flush();
    639   visible_ = visible;
    640   command_buffer_->SetSurfaceVisible(visible);
    641   if (!visible)
    642     real_gl_->FreeEverything();
    643 }
    644 
    645 DELEGATE_TO_GL_3(discardFramebufferEXT, DiscardFramebufferEXT, WGC3Denum,
    646                  WGC3Dsizei, const WGC3Denum*)
    647 
    648 void WebGraphicsContext3DCommandBufferImpl::discardBackbufferCHROMIUM() {
    649   gl_->Flush();
    650   command_buffer_->DiscardBackbuffer();
    651 }
    652 
    653 void WebGraphicsContext3DCommandBufferImpl::ensureBackbufferCHROMIUM() {
    654   gl_->Flush();
    655   command_buffer_->EnsureBackbuffer();
    656 }
    657 
    658 void WebGraphicsContext3DCommandBufferImpl::sendManagedMemoryStatsCHROMIUM(
    659     const WebGraphicsManagedMemoryStats* stats)
    660 {
    661   CHECK(command_buffer_);
    662   command_buffer_->SendManagedMemoryStats(GpuManagedMemoryStats(
    663       stats->bytesVisible,
    664       stats->bytesVisibleAndNearby,
    665       stats->bytesAllocated,
    666       stats->backbufferRequested));
    667 }
    668 
    669 void WebGraphicsContext3DCommandBufferImpl::
    670     setMemoryAllocationChangedCallbackCHROMIUM(
    671         WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {
    672   if (!command_buffer_)
    673     return;
    674 
    675   if (callback)
    676     command_buffer_->SetMemoryAllocationChangedCallback(base::Bind(
    677         &WebGraphicsContext3DCommandBufferImpl::OnMemoryAllocationChanged,
    678         weak_ptr_factory_.GetWeakPtr(),
    679         callback));
    680   else
    681     command_buffer_->SetMemoryAllocationChangedCallback(
    682         base::Callback<void(const GpuMemoryAllocationForRenderer&)>());
    683 }
    684 
    685 
    686 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM(
    687     WebGLId texture, WebGLId parentTexture) {
    688   NOTIMPLEMENTED();
    689 }
    690 
    691 DELEGATE_TO_GL(rateLimitOffscreenContextCHROMIUM,
    692                RateLimitOffscreenContextCHROMIUM)
    693 
    694 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::
    695     getRequestableExtensionsCHROMIUM() {
    696   return WebKit::WebString::fromUTF8(
    697       gl_->GetRequestableExtensionsCHROMIUM());
    698 }
    699 
    700 DELEGATE_TO_GL_1(requestExtensionCHROMIUM, RequestExtensionCHROMIUM,
    701                  const char*)
    702 
    703 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM(
    704     WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
    705     WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
    706     WGC3Dbitfield mask, WGC3Denum filter) {
    707   gl_->BlitFramebufferEXT(
    708       srcX0, srcY0, srcX1, srcY1,
    709       dstX0, dstY0, dstX1, dstY1,
    710       mask, filter);
    711 }
    712 
    713 DELEGATE_TO_GL_5(renderbufferStorageMultisampleCHROMIUM,
    714                  RenderbufferStorageMultisampleEXT, WGC3Denum, WGC3Dsizei,
    715                  WGC3Denum, WGC3Dsizei, WGC3Dsizei)
    716 
    717 DELEGATE_TO_GL_1R(createStreamTextureCHROMIUM, CreateStreamTextureCHROMIUM,
    718                   WebGLId, WebGLId)
    719 
    720 DELEGATE_TO_GL_1(destroyStreamTextureCHROMIUM, DestroyStreamTextureCHROMIUM,
    721                  WebGLId)
    722 
    723 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
    724 
    725 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
    726 
    727 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId,
    728                  WGC3Duint, const WGC3Dchar*)
    729 
    730 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId)
    731 
    732 DELEGATE_TO_GL_2(bindFramebuffer, BindFramebuffer, WGC3Denum, WebGLId)
    733 
    734 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId)
    735 
    736 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId)
    737 
    738 DELEGATE_TO_GL_4(blendColor, BlendColor,
    739                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
    740 
    741 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
    742 
    743 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
    744                  WGC3Denum, WGC3Denum)
    745 
    746 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
    747 
    748 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
    749                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
    750 
    751 DELEGATE_TO_GL_4(bufferData, BufferData,
    752                  WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
    753 
    754 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
    755                  WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
    756 
    757 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus,
    758                   WGC3Denum, WGC3Denum)
    759 
    760 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
    761 
    762 DELEGATE_TO_GL_4(clearColor, ClearColor,
    763                  WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
    764 
    765 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf)
    766 
    767 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
    768 
    769 DELEGATE_TO_GL_4(colorMask, ColorMask,
    770                  WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
    771 
    772 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId)
    773 
    774 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
    775                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
    776                  WGC3Dsizei, WGC3Dsizei, const void*)
    777 
    778 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
    779                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
    780                  WGC3Denum, WGC3Dsizei, const void*)
    781 
    782 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D,
    783                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
    784                  WGC3Dsizei, WGC3Dsizei, WGC3Dint)
    785 
    786 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D,
    787                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
    788                  WGC3Dsizei, WGC3Dsizei)
    789 
    790 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
    791 
    792 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
    793 
    794 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
    795 
    796 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf)
    797 
    798 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
    799 
    800 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
    801 
    802 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray,
    803                  WGC3Duint)
    804 
    805 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
    806 
    807 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode,
    808                                                          WGC3Dsizei count,
    809                                                          WGC3Denum type,
    810                                                          WGC3Dintptr offset) {
    811   gl_->DrawElements(
    812       mode, count, type,
    813       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
    814 }
    815 
    816 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
    817 
    818 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray,
    819                  WGC3Duint)
    820 
    821 void WebGraphicsContext3DCommandBufferImpl::finish() {
    822   gl_->Finish();
    823   if (!visible_ && free_command_buffer_when_invisible_)
    824     real_gl_->FreeEverything();
    825 }
    826 
    827 void WebGraphicsContext3DCommandBufferImpl::flush() {
    828   gl_->Flush();
    829   if (!visible_ && free_command_buffer_when_invisible_)
    830     real_gl_->FreeEverything();
    831 }
    832 
    833 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer,
    834                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
    835 
    836 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D,
    837                  WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
    838 
    839 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
    840 
    841 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum)
    842 
    843 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib(
    844     WebGLId program, WGC3Duint index, ActiveInfo& info) {
    845   if (!program) {
    846     synthesizeGLError(GL_INVALID_VALUE);
    847     return false;
    848   }
    849   GLint max_name_length = -1;
    850   gl_->GetProgramiv(
    851       program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
    852   if (max_name_length < 0)
    853     return false;
    854   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
    855   if (!name) {
    856     synthesizeGLError(GL_OUT_OF_MEMORY);
    857     return false;
    858   }
    859   GLsizei length = 0;
    860   GLint size = -1;
    861   GLenum type = 0;
    862   gl_->GetActiveAttrib(
    863       program, index, max_name_length, &length, &size, &type, name.get());
    864   if (size < 0) {
    865     return false;
    866   }
    867   info.name = WebKit::WebString::fromUTF8(name.get(), length);
    868   info.type = type;
    869   info.size = size;
    870   return true;
    871 }
    872 
    873 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform(
    874     WebGLId program, WGC3Duint index, ActiveInfo& info) {
    875   GLint max_name_length = -1;
    876   gl_->GetProgramiv(
    877       program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
    878   if (max_name_length < 0)
    879     return false;
    880   scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
    881   if (!name) {
    882     synthesizeGLError(GL_OUT_OF_MEMORY);
    883     return false;
    884   }
    885   GLsizei length = 0;
    886   GLint size = -1;
    887   GLenum type = 0;
    888   gl_->GetActiveUniform(
    889       program, index, max_name_length, &length, &size, &type, name.get());
    890   if (size < 0) {
    891     return false;
    892   }
    893   info.name = WebKit::WebString::fromUTF8(name.get(), length);
    894   info.type = type;
    895   info.size = size;
    896   return true;
    897 }
    898 
    899 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
    900                  WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
    901 
    902 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
    903                   WebGLId, const WGC3Dchar*, WGC3Dint)
    904 
    905 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*)
    906 
    907 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
    908                  WGC3Denum, WGC3Denum, WGC3Dint*)
    909 
    910 WebKit::WebGraphicsContext3D::Attributes
    911 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() {
    912   return attributes_;
    913 }
    914 
    915 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() {
    916   if (!synthetic_errors_.empty()) {
    917     std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
    918     WGC3Denum err = *iter;
    919     synthetic_errors_.erase(iter);
    920     return err;
    921   }
    922 
    923   return gl_->GetError();
    924 }
    925 
    926 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
    927   return initialize_failed_ ||
    928       (command_buffer_ && IsCommandBufferContextLost()) ||
    929       context_lost_reason_ != GL_NO_ERROR;
    930 }
    931 
    932 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
    933 
    934 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
    935                  GetFramebufferAttachmentParameteriv,
    936                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
    937 
    938 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
    939 
    940 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
    941 
    942 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog(
    943     WebGLId program) {
    944   GLint logLength = 0;
    945   gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
    946   if (!logLength)
    947     return WebKit::WebString();
    948   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    949   if (!log)
    950     return WebKit::WebString();
    951   GLsizei returnedLogLength = 0;
    952   gl_->GetProgramInfoLog(
    953       program, logLength, &returnedLogLength, log.get());
    954   DCHECK_EQ(logLength, returnedLogLength + 1);
    955   WebKit::WebString res =
    956       WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
    957   return res;
    958 }
    959 
    960 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv,
    961                  WGC3Denum, WGC3Denum, WGC3Dint*)
    962 
    963 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*)
    964 
    965 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog(
    966     WebGLId shader) {
    967   GLint logLength = 0;
    968   gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
    969   if (!logLength)
    970     return WebKit::WebString();
    971   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    972   if (!log)
    973     return WebKit::WebString();
    974   GLsizei returnedLogLength = 0;
    975   gl_->GetShaderInfoLog(
    976       shader, logLength, &returnedLogLength, log.get());
    977   DCHECK_EQ(logLength, returnedLogLength + 1);
    978   WebKit::WebString res =
    979       WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
    980   return res;
    981 }
    982 
    983 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat,
    984                  WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*)
    985 
    986 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource(
    987     WebGLId shader) {
    988   GLint logLength = 0;
    989   gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
    990   if (!logLength)
    991     return WebKit::WebString();
    992   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
    993   if (!log)
    994     return WebKit::WebString();
    995   GLsizei returnedLogLength = 0;
    996   gl_->GetShaderSource(
    997       shader, logLength, &returnedLogLength, log.get());
    998   if (!returnedLogLength)
    999     return WebKit::WebString();
   1000   DCHECK_EQ(logLength, returnedLogLength + 1);
   1001   WebKit::WebString res =
   1002       WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
   1003   return res;
   1004 }
   1005 
   1006 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::
   1007     getTranslatedShaderSourceANGLE(WebGLId shader) {
   1008   GLint logLength = 0;
   1009   gl_->GetShaderiv(
   1010       shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength);
   1011   if (!logLength)
   1012     return WebKit::WebString();
   1013   scoped_ptr<GLchar[]> log(new GLchar[logLength]);
   1014   if (!log)
   1015     return WebKit::WebString();
   1016   GLsizei returnedLogLength = 0;
   1017   gl_->GetTranslatedShaderSourceANGLE(
   1018       shader, logLength, &returnedLogLength, log.get());
   1019   if (!returnedLogLength)
   1020     return WebKit::WebString();
   1021   DCHECK_EQ(logLength, returnedLogLength + 1);
   1022   WebKit::WebString res =
   1023       WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
   1024   return res;
   1025 }
   1026 
   1027 WebKit::WebString WebGraphicsContext3DCommandBufferImpl::getString(
   1028     WGC3Denum name) {
   1029   return WebKit::WebString::fromUTF8(
   1030       reinterpret_cast<const char*>(gl_->GetString(name)));
   1031 }
   1032 
   1033 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
   1034                  WGC3Denum, WGC3Denum, WGC3Dfloat*)
   1035 
   1036 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
   1037                  WGC3Denum, WGC3Denum, WGC3Dint*)
   1038 
   1039 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
   1040 
   1041 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
   1042 
   1043 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
   1044                   WebGLId, const WGC3Dchar*, WGC3Dint)
   1045 
   1046 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
   1047                  WGC3Duint, WGC3Denum, WGC3Dfloat*)
   1048 
   1049 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
   1050                  WGC3Duint, WGC3Denum, WGC3Dint*)
   1051 
   1052 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset(
   1053     WGC3Duint index, WGC3Denum pname) {
   1054   GLvoid* value = NULL;
   1055   // NOTE: If pname is ever a value that returns more then 1 element
   1056   // this will corrupt memory.
   1057   gl_->GetVertexAttribPointerv(index, pname, &value);
   1058   return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value));
   1059 }
   1060 
   1061 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
   1062 
   1063 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
   1064 
   1065 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
   1066 
   1067 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean)
   1068 
   1069 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
   1070 
   1071 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean)
   1072 
   1073 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
   1074 
   1075 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
   1076 
   1077 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
   1078 
   1079 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
   1080 
   1081 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
   1082 
   1083 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
   1084 
   1085 DELEGATE_TO_GL_7(readPixels, ReadPixels,
   1086                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum,
   1087                  WGC3Denum, void*)
   1088 
   1089 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() {
   1090 }
   1091 
   1092 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage,
   1093                  WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei)
   1094 
   1095 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean)
   1096 
   1097 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
   1098 
   1099 void WebGraphicsContext3DCommandBufferImpl::shaderSource(
   1100     WebGLId shader, const WGC3Dchar* string) {
   1101   GLint length = strlen(string);
   1102   gl_->ShaderSource(shader, 1, &string, &length);
   1103 }
   1104 
   1105 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
   1106 
   1107 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
   1108                  WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
   1109 
   1110 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
   1111 
   1112 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
   1113                  WGC3Denum, WGC3Duint)
   1114 
   1115 DELEGATE_TO_GL_3(stencilOp, StencilOp,
   1116                  WGC3Denum, WGC3Denum, WGC3Denum)
   1117 
   1118 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
   1119                  WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
   1120 
   1121 DELEGATE_TO_GL_9(texImage2D, TexImage2D,
   1122                  WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei,
   1123                  WGC3Dint, WGC3Denum, WGC3Denum, const void*)
   1124 
   1125 DELEGATE_TO_GL_3(texParameterf, TexParameterf,
   1126                  WGC3Denum, WGC3Denum, WGC3Dfloat);
   1127 
   1128 static const unsigned int kTextureWrapR = 0x8072;
   1129 
   1130 void WebGraphicsContext3DCommandBufferImpl::texParameteri(
   1131     WGC3Denum target, WGC3Denum pname, WGC3Dint param) {
   1132   // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in
   1133   // GraphicsContext3D.cpp is strictly necessary to avoid seams at the
   1134   // edge of cube maps, and, if it is, push it into the GLES2 service
   1135   // side code.
   1136   if (pname == kTextureWrapR) {
   1137     return;
   1138   }
   1139   gl_->TexParameteri(target, pname, param);
   1140 }
   1141 
   1142 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
   1143                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
   1144                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
   1145 
   1146 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
   1147 
   1148 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei,
   1149                  const WGC3Dfloat*)
   1150 
   1151 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
   1152 
   1153 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1154 
   1155 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
   1156 
   1157 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei,
   1158                  const WGC3Dfloat*)
   1159 
   1160 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
   1161 
   1162 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1163 
   1164 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint,
   1165                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1166 
   1167 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei,
   1168                  const WGC3Dfloat*)
   1169 
   1170 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
   1171 
   1172 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1173 
   1174 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
   1175                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1176 
   1177 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei,
   1178                  const WGC3Dfloat*)
   1179 
   1180 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
   1181                  WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
   1182 
   1183 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
   1184 
   1185 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
   1186                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1187 
   1188 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
   1189                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1190 
   1191 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
   1192                  WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
   1193 
   1194 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
   1195 
   1196 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
   1197 
   1198 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
   1199 
   1200 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint,
   1201                  const WGC3Dfloat*)
   1202 
   1203 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint,
   1204                  WGC3Dfloat, WGC3Dfloat)
   1205 
   1206 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint,
   1207                  const WGC3Dfloat*)
   1208 
   1209 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint,
   1210                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1211 
   1212 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint,
   1213                  const WGC3Dfloat*)
   1214 
   1215 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint,
   1216                  WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
   1217 
   1218 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint,
   1219                  const WGC3Dfloat*)
   1220 
   1221 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer(
   1222     WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
   1223     WGC3Dsizei stride, WGC3Dintptr offset) {
   1224   gl_->VertexAttribPointer(
   1225       index, size, type, normalized, stride,
   1226       reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
   1227 }
   1228 
   1229 DELEGATE_TO_GL_4(viewport, Viewport,
   1230                  WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
   1231 
   1232 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() {
   1233   GLuint o;
   1234   gl_->GenBuffers(1, &o);
   1235   return o;
   1236 }
   1237 
   1238 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() {
   1239   GLuint o = 0;
   1240   gl_->GenFramebuffers(1, &o);
   1241   return o;
   1242 }
   1243 
   1244 DELEGATE_TO_GL_R(createProgram, CreateProgram, WebGLId)
   1245 
   1246 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() {
   1247   GLuint o;
   1248   gl_->GenRenderbuffers(1, &o);
   1249   return o;
   1250 }
   1251 
   1252 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId)
   1253 
   1254 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() {
   1255   GLuint o;
   1256   gl_->GenTextures(1, &o);
   1257   return o;
   1258 }
   1259 
   1260 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) {
   1261   gl_->DeleteBuffers(1, &buffer);
   1262 }
   1263 
   1264 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer(
   1265     WebGLId framebuffer) {
   1266   gl_->DeleteFramebuffers(1, &framebuffer);
   1267 }
   1268 
   1269 DELEGATE_TO_GL_1(deleteProgram, DeleteProgram, WebGLId)
   1270 
   1271 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer(
   1272     WebGLId renderbuffer) {
   1273   gl_->DeleteRenderbuffers(1, &renderbuffer);
   1274 }
   1275 
   1276 DELEGATE_TO_GL_1(deleteShader, DeleteShader, WebGLId)
   1277 
   1278 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
   1279   gl_->DeleteTextures(1, &texture);
   1280 }
   1281 
   1282 bool WebGraphicsContext3DCommandBufferImpl::ShouldUseSwapClient() {
   1283   return factory_ && factory_->IsMainThread() && swap_client_.get();
   1284 }
   1285 
   1286 void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() {
   1287   typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient;
   1288   // This may be called after tear-down of the RenderView.
   1289   if (ShouldUseSwapClient()) {
   1290     base::MessageLoop::current()->PostTask(
   1291         FROM_HERE,
   1292         base::Bind(&WGC3DSwapClient::OnViewContextSwapBuffersComplete,
   1293                    swap_client_));
   1294   }
   1295 
   1296   if (swapbuffers_complete_callback_)
   1297     swapbuffers_complete_callback_->onSwapBuffersComplete();
   1298 }
   1299 
   1300 WebGraphicsMemoryAllocation::PriorityCutoff
   1301     WebGraphicsContext3DCommandBufferImpl::WebkitPriorityCutoff(
   1302         GpuMemoryAllocationForRenderer::PriorityCutoff priorityCutoff) {
   1303   switch (priorityCutoff) {
   1304   case GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNothing:
   1305     return WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing;
   1306   case GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired:
   1307     return WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly;
   1308   case GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNiceToHave:
   1309     return WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleAndNearby;
   1310   case GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything:
   1311     return WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything;
   1312   }
   1313   NOTREACHED();
   1314   return WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything;
   1315 }
   1316 
   1317 void WebGraphicsContext3DCommandBufferImpl::OnMemoryAllocationChanged(
   1318     WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback,
   1319     const GpuMemoryAllocationForRenderer& allocation) {
   1320 
   1321   // Convert the gpu structure to the WebKit structure.
   1322   WebGraphicsMemoryAllocation web_allocation;
   1323   web_allocation.bytesLimitWhenVisible =
   1324       ClampUint64ToSizeT(allocation.bytes_limit_when_visible);
   1325   web_allocation.priorityCutoffWhenVisible =
   1326       WebkitPriorityCutoff(allocation.priority_cutoff_when_visible);
   1327   web_allocation.bytesLimitWhenNotVisible =
   1328       ClampUint64ToSizeT(allocation.bytes_limit_when_not_visible);
   1329   web_allocation.priorityCutoffWhenNotVisible =
   1330       WebkitPriorityCutoff(allocation.priority_cutoff_when_not_visible);
   1331   web_allocation.haveBackbufferWhenNotVisible =
   1332       allocation.have_backbuffer_when_not_visible;
   1333 
   1334   // Populate deprecated WebKit fields. These may be removed when references to
   1335   // them in WebKit are removed.
   1336   web_allocation.gpuResourceSizeInBytes =
   1337       ClampUint64ToSizeT(allocation.bytes_limit_when_visible);
   1338   web_allocation.suggestHaveBackbuffer =
   1339       allocation.have_backbuffer_when_not_visible;
   1340 
   1341   if (callback)
   1342     callback->onMemoryAllocationChanged(web_allocation);
   1343 
   1344   // We may have allocated transfer buffers in order to free GL resources in a
   1345   // backgrounded tab. Re-free the transfer buffers.
   1346   if (!visible_)
   1347     real_gl_->FreeEverything();
   1348 }
   1349 
   1350 void WebGraphicsContext3DCommandBufferImpl::setErrorMessageCallback(
   1351     WebGraphicsContext3D::WebGraphicsErrorMessageCallback* cb) {
   1352   error_message_callback_ = cb;
   1353 }
   1354 
   1355 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback(
   1356     WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) {
   1357   context_lost_callback_ = cb;
   1358 }
   1359 
   1360 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() {
   1361   if (IsCommandBufferContextLost() &&
   1362       context_lost_reason_ == GL_NO_ERROR) {
   1363     return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1364   }
   1365 
   1366   return context_lost_reason_;
   1367 }
   1368 
   1369 bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
   1370   // If the channel shut down unexpectedly, let that supersede the
   1371   // command buffer's state.
   1372   if (host_.get() && host_->IsLost())
   1373     return true;
   1374   gpu::CommandBuffer::State state = command_buffer_->GetLastState();
   1375   return state.error == gpu::error::kLostContext;
   1376 }
   1377 
   1378 // static
   1379 WebGraphicsContext3DCommandBufferImpl*
   1380 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
   1381     GpuChannelHostFactory* factory,
   1382     const WebGraphicsContext3D::Attributes& attributes,
   1383     const GURL& active_url) {
   1384   if (!factory)
   1385     return NULL;
   1386   base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> null_client;
   1387   scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
   1388       new WebGraphicsContext3DCommandBufferImpl(
   1389           0, active_url, factory, null_client));
   1390   CauseForGpuLaunch cause =
   1391       CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
   1392   if (context->InitializeWithDefaultBufferSizes(attributes, false, cause))
   1393     return context.release();
   1394   return NULL;
   1395 }
   1396 
   1397 void WebGraphicsContext3DCommandBufferImpl::
   1398     setSwapBuffersCompleteCallbackCHROMIUM(
   1399     WebGraphicsContext3D::WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* cb) {
   1400   swapbuffers_complete_callback_ = cb;
   1401 }
   1402 
   1403 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM,
   1404                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint)
   1405 
   1406 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
   1407                  WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
   1408 
   1409 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() {
   1410   GLuint o;
   1411   gl_->GenQueriesEXT(1, &o);
   1412   return o;
   1413 }
   1414 
   1415 void WebGraphicsContext3DCommandBufferImpl::deleteQueryEXT(
   1416     WebGLId query) {
   1417   gl_->DeleteQueriesEXT(1, &query);
   1418 }
   1419 
   1420 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean)
   1421 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId)
   1422 DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum)
   1423 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*)
   1424 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
   1425                  WebGLId, WGC3Denum, WGC3Duint*)
   1426 
   1427 DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM,  WGC3Denum,
   1428                  WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
   1429 
   1430 DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
   1431                  WebGLId, WGC3Dint, const WGC3Dchar*)
   1432 
   1433 DELEGATE_TO_GL(shallowFlushCHROMIUM, ShallowFlushCHROMIUM);
   1434 DELEGATE_TO_GL(shallowFinishCHROMIUM, ShallowFinishCHROMIUM);
   1435 
   1436 DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint)
   1437 
   1438 static void SignalSyncPointCallback(
   1439     scoped_ptr<
   1440       WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) {
   1441   callback->onSyncPointReached();
   1442 }
   1443 
   1444 void WebGraphicsContext3DCommandBufferImpl::signalSyncPoint(
   1445     unsigned sync_point,
   1446     WebGraphicsSyncPointCallback* callback) {
   1447   // Take ownership of the callback.
   1448   scoped_ptr<WebGraphicsSyncPointCallback> own_callback(callback);
   1449   command_buffer_->SignalSyncPoint(
   1450       sync_point,
   1451       base::Bind(&SignalSyncPointCallback, base::Passed(&own_callback)));
   1452 }
   1453 
   1454 void WebGraphicsContext3DCommandBufferImpl::signalQuery(
   1455     unsigned query,
   1456     WebGraphicsSyncPointCallback* callback) {
   1457   // Take ownership of the callback.
   1458   scoped_ptr<WebGraphicsSyncPointCallback> own_callback(callback);
   1459   // Flush any pending commands to make sure that the the query
   1460   // has actually been created/started before we try to attach
   1461   // a callback to it.
   1462   gl_->Flush();
   1463   command_buffer_->SignalQuery(
   1464       query,
   1465       base::Bind(&SignalSyncPointCallback, base::Passed(&own_callback)));
   1466 }
   1467 
   1468 void WebGraphicsContext3DCommandBufferImpl::loseContextCHROMIUM(
   1469     WGC3Denum current, WGC3Denum other) {
   1470   gl_->LoseContextCHROMIUM(current, other);
   1471   gl_->Flush();
   1472 }
   1473 
   1474 void WebGraphicsContext3DCommandBufferImpl::genMailboxCHROMIUM(
   1475     WGC3Dbyte* name) {
   1476   std::vector<gpu::Mailbox> names;
   1477   if (command_buffer_->GenerateMailboxNames(1, &names))
   1478     memcpy(name, names[0].name, GL_MAILBOX_SIZE_CHROMIUM);
   1479   else
   1480     synthesizeGLError(GL_OUT_OF_MEMORY);
   1481 }
   1482 
   1483 DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM,
   1484                  WGC3Denum, const WGC3Dbyte*)
   1485 DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM,
   1486                  WGC3Denum, const WGC3Dbyte*)
   1487 
   1488 void WebGraphicsContext3DCommandBufferImpl::insertEventMarkerEXT(
   1489     const WGC3Dchar* marker) {
   1490   gl_->InsertEventMarkerEXT(0, marker);
   1491 }
   1492 
   1493 void WebGraphicsContext3DCommandBufferImpl::pushGroupMarkerEXT(
   1494     const WGC3Dchar* marker) {
   1495   gl_->PushGroupMarkerEXT(0, marker);
   1496 }
   1497 
   1498 DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT);
   1499 
   1500 WebGLId WebGraphicsContext3DCommandBufferImpl::createVertexArrayOES() {
   1501   GLuint array;
   1502   gl_->GenVertexArraysOES(1, &array);
   1503   return array;
   1504 }
   1505 
   1506 void WebGraphicsContext3DCommandBufferImpl::deleteVertexArrayOES(
   1507     WebGLId array) {
   1508   gl_->DeleteVertexArraysOES(1, &array);
   1509 }
   1510 
   1511 DELEGATE_TO_GL_1R(isVertexArrayOES, IsVertexArrayOES, WebGLId, WGC3Dboolean)
   1512 DELEGATE_TO_GL_1(bindVertexArrayOES, BindVertexArrayOES, WebGLId)
   1513 
   1514 DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM,
   1515                  WGC3Denum, WGC3Dint)
   1516 DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM,
   1517                  WGC3Denum, WGC3Dint)
   1518 
   1519 DELEGATE_TO_GL_2R(mapBufferCHROMIUM, MapBufferCHROMIUM, WGC3Denum, WGC3Denum,
   1520                   void*)
   1521 DELEGATE_TO_GL_1R(unmapBufferCHROMIUM, UnmapBufferCHROMIUM, WGC3Denum,
   1522                   WGC3Dboolean)
   1523 
   1524 DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum,
   1525                  WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint,
   1526                  WGC3Denum, WGC3Denum, const void*)
   1527 DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM,
   1528                  WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
   1529                  WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
   1530 
   1531 DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM,
   1532                  WGC3Denum)
   1533 
   1534 DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*)
   1535 
   1536 DELEGATE_TO_GL_4(drawArraysInstancedANGLE, DrawArraysInstancedANGLE, WGC3Denum,
   1537                  WGC3Dint, WGC3Dsizei, WGC3Dsizei)
   1538 
   1539 void WebGraphicsContext3DCommandBufferImpl::drawElementsInstancedANGLE(
   1540     WGC3Denum mode,
   1541     WGC3Dsizei count,
   1542     WGC3Denum type,
   1543     WGC3Dintptr offset,
   1544     WGC3Dsizei primcount) {
   1545   gl_->DrawElementsInstancedANGLE(
   1546       mode, count, type,
   1547       reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount);
   1548 }
   1549 
   1550 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint,
   1551                  WGC3Duint)
   1552 
   1553 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::onCreateGrGLInterface() {
   1554   return webkit::gpu::CreateCommandBufferSkiaGLBinding();
   1555 }
   1556 
   1557 namespace {
   1558 
   1559 WGC3Denum convertReason(gpu::error::ContextLostReason reason) {
   1560   switch (reason) {
   1561   case gpu::error::kGuilty:
   1562     return GL_GUILTY_CONTEXT_RESET_ARB;
   1563   case gpu::error::kInnocent:
   1564     return GL_INNOCENT_CONTEXT_RESET_ARB;
   1565   case gpu::error::kUnknown:
   1566     return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1567   }
   1568 
   1569   NOTREACHED();
   1570   return GL_UNKNOWN_CONTEXT_RESET_ARB;
   1571 }
   1572 
   1573 }  // anonymous namespace
   1574 
   1575 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() {
   1576   context_lost_reason_ = convertReason(
   1577       command_buffer_->GetLastState().context_lost_reason);
   1578   if (context_lost_callback_) {
   1579     context_lost_callback_->onContextLost();
   1580   }
   1581   if (attributes_.shareResources)
   1582     ClearSharedContextsIfInShareSet(this);
   1583   if (ShouldUseSwapClient())
   1584     swap_client_->OnViewContextSwapBuffersAborted();
   1585 }
   1586 
   1587 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage(
   1588     const std::string& message, int id) {
   1589   if (error_message_callback_) {
   1590     WebKit::WebString str = WebKit::WebString::fromUTF8(message.c_str());
   1591     error_message_callback_->onErrorMessage(str, id);
   1592   }
   1593 }
   1594 
   1595 }  // namespace content
   1596