Home | History | Annotate | Download | only in service
      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 "gpu/command_buffer/service/gles2_cmd_decoder.h"
      6 
      7 #include <stdio.h>
      8 
      9 #include <algorithm>
     10 #include <list>
     11 #include <map>
     12 #include <stack>
     13 #include <string>
     14 #include <vector>
     15 
     16 #include "base/at_exit.h"
     17 #include "base/bind.h"
     18 #include "base/callback_helpers.h"
     19 #include "base/command_line.h"
     20 #include "base/debug/trace_event.h"
     21 #include "base/debug/trace_event_synthetic_delay.h"
     22 #include "base/float_util.h"
     23 #include "base/memory/scoped_ptr.h"
     24 #include "base/numerics/safe_math.h"
     25 #include "base/strings/string_number_conversions.h"
     26 #include "base/strings/string_split.h"
     27 #include "build/build_config.h"
     28 #define GLES2_GPU_SERVICE 1
     29 #include "gpu/command_buffer/common/debug_marker_manager.h"
     30 #include "gpu/command_buffer/common/gles2_cmd_format.h"
     31 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
     32 #include "gpu/command_buffer/common/id_allocator.h"
     33 #include "gpu/command_buffer/common/mailbox.h"
     34 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
     35 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
     36 #include "gpu/command_buffer/service/buffer_manager.h"
     37 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
     38 #include "gpu/command_buffer/service/context_group.h"
     39 #include "gpu/command_buffer/service/context_state.h"
     40 #include "gpu/command_buffer/service/error_state.h"
     41 #include "gpu/command_buffer/service/feature_info.h"
     42 #include "gpu/command_buffer/service/framebuffer_manager.h"
     43 #include "gpu/command_buffer/service/gl_utils.h"
     44 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
     45 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
     46 #include "gpu/command_buffer/service/gpu_state_tracer.h"
     47 #include "gpu/command_buffer/service/gpu_switches.h"
     48 #include "gpu/command_buffer/service/gpu_tracer.h"
     49 #include "gpu/command_buffer/service/image_manager.h"
     50 #include "gpu/command_buffer/service/mailbox_manager.h"
     51 #include "gpu/command_buffer/service/memory_tracking.h"
     52 #include "gpu/command_buffer/service/program_manager.h"
     53 #include "gpu/command_buffer/service/query_manager.h"
     54 #include "gpu/command_buffer/service/renderbuffer_manager.h"
     55 #include "gpu/command_buffer/service/shader_manager.h"
     56 #include "gpu/command_buffer/service/shader_translator.h"
     57 #include "gpu/command_buffer/service/shader_translator_cache.h"
     58 #include "gpu/command_buffer/service/texture_manager.h"
     59 #include "gpu/command_buffer/service/vertex_array_manager.h"
     60 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
     61 #include "third_party/smhasher/src/City.h"
     62 #include "ui/gl/gl_fence.h"
     63 #include "ui/gl/gl_image.h"
     64 #include "ui/gl/gl_implementation.h"
     65 #include "ui/gl/gl_surface.h"
     66 
     67 #if defined(OS_MACOSX)
     68 #include <IOSurface/IOSurfaceAPI.h>
     69 // Note that this must be included after gl_bindings.h to avoid conflicts.
     70 #include <OpenGL/CGLIOSurface.h>
     71 #endif
     72 
     73 #if defined(OS_WIN)
     74 #include "base/win/win_util.h"
     75 #endif
     76 
     77 namespace gpu {
     78 namespace gles2 {
     79 
     80 namespace {
     81 
     82 static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
     83 static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
     84 static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
     85 static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
     86 
     87 static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
     88                                             GLint rangeMax,
     89                                             GLint precision) {
     90   return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
     91 }
     92 
     93 static void GetShaderPrecisionFormatImpl(GLenum shader_type,
     94                                          GLenum precision_type,
     95                                          GLint *range, GLint *precision) {
     96   switch (precision_type) {
     97     case GL_LOW_INT:
     98     case GL_MEDIUM_INT:
     99     case GL_HIGH_INT:
    100       // These values are for a 32-bit twos-complement integer format.
    101       range[0] = 31;
    102       range[1] = 30;
    103       *precision = 0;
    104       break;
    105     case GL_LOW_FLOAT:
    106     case GL_MEDIUM_FLOAT:
    107     case GL_HIGH_FLOAT:
    108       // These values are for an IEEE single-precision floating-point format.
    109       range[0] = 127;
    110       range[1] = 127;
    111       *precision = 23;
    112       break;
    113     default:
    114       NOTREACHED();
    115       break;
    116   }
    117 
    118   if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
    119       gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
    120     // This function is sometimes defined even though it's really just
    121     // a stub, so we need to set range and precision as if it weren't
    122     // defined before calling it.
    123     // On Mac OS with some GPUs, calling this generates a
    124     // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
    125     // platforms.
    126     glGetShaderPrecisionFormat(shader_type, precision_type,
    127                                range, precision);
    128 
    129     // TODO(brianderson): Make the following official workarounds.
    130 
    131     // Some drivers have bugs where they report the ranges as a negative number.
    132     // Taking the absolute value here shouldn't hurt because negative numbers
    133     // aren't expected anyway.
    134     range[0] = abs(range[0]);
    135     range[1] = abs(range[1]);
    136 
    137     // If the driver reports a precision for highp float that isn't actually
    138     // highp, don't pretend like it's supported because shader compilation will
    139     // fail anyway.
    140     if (precision_type == GL_HIGH_FLOAT &&
    141         !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
    142       range[0] = 0;
    143       range[1] = 0;
    144       *precision = 0;
    145     }
    146   }
    147 }
    148 
    149 static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
    150   switch (plane_transform) {
    151     case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
    152       return gfx::OVERLAY_TRANSFORM_NONE;
    153     case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
    154       return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
    155     case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
    156       return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
    157     case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
    158       return gfx::OVERLAY_TRANSFORM_ROTATE_90;
    159     case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
    160       return gfx::OVERLAY_TRANSFORM_ROTATE_180;
    161     case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
    162       return gfx::OVERLAY_TRANSFORM_ROTATE_270;
    163     default:
    164       return gfx::OVERLAY_TRANSFORM_INVALID;
    165   }
    166 }
    167 
    168 }  // namespace
    169 
    170 class GLES2DecoderImpl;
    171 
    172 // Local versions of the SET_GL_ERROR macros
    173 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
    174     ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
    175 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
    176     ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
    177                                          function_name, value, label)
    178 #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
    179     ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
    180                                           function_name, pname)
    181 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
    182     ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
    183                                               function_name)
    184 #define LOCAL_PEEK_GL_ERROR(function_name) \
    185     ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
    186 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
    187     ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
    188 #define LOCAL_PERFORMANCE_WARNING(msg) \
    189     PerformanceWarning(__FILE__, __LINE__, msg)
    190 #define LOCAL_RENDER_WARNING(msg) \
    191     RenderWarning(__FILE__, __LINE__, msg)
    192 
    193 // Check that certain assumptions the code makes are true. There are places in
    194 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
    195 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
    196 // a few others) are 32bits. If they are not 32bits the code will have to change
    197 // to call those GL functions with service side memory and then copy the results
    198 // to shared memory, converting the sizes.
    199 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32),  // NOLINT
    200                GLint_not_same_size_as_uint32);
    201 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32),  // NOLINT
    202                GLint_not_same_size_as_uint32);
    203 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float),  // NOLINT
    204                GLfloat_not_same_size_as_float);
    205 
    206 // TODO(kbr): the use of this anonymous namespace core dumps the
    207 // linker on Mac OS X 10.6 when the symbol ordering file is used
    208 // namespace {
    209 
    210 // Returns the address of the first byte after a struct.
    211 template <typename T>
    212 const void* AddressAfterStruct(const T& pod) {
    213   return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
    214 }
    215 
    216 // Returns the address of the frst byte after the struct or NULL if size >
    217 // immediate_data_size.
    218 template <typename RETURN_TYPE, typename COMMAND_TYPE>
    219 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
    220                                uint32 size,
    221                                uint32 immediate_data_size) {
    222   return (size <= immediate_data_size) ?
    223       static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
    224       NULL;
    225 }
    226 
    227 // Computes the data size for certain gl commands like glUniform.
    228 bool ComputeDataSize(
    229     GLuint count,
    230     size_t size,
    231     unsigned int elements_per_unit,
    232     uint32* dst) {
    233   uint32 value;
    234   if (!SafeMultiplyUint32(count, size, &value)) {
    235     return false;
    236   }
    237   if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
    238     return false;
    239   }
    240   *dst = value;
    241   return true;
    242 }
    243 
    244 // Return true if a character belongs to the ASCII subset as defined in
    245 // GLSL ES 1.0 spec section 3.1.
    246 static bool CharacterIsValidForGLES(unsigned char c) {
    247   // Printing characters are valid except " $ ` @ \ ' DEL.
    248   if (c >= 32 && c <= 126 &&
    249       c != '"' &&
    250       c != '$' &&
    251       c != '`' &&
    252       c != '@' &&
    253       c != '\\' &&
    254       c != '\'') {
    255     return true;
    256   }
    257   // Horizontal tab, line feed, vertical tab, form feed, carriage return
    258   // are also valid.
    259   if (c >= 9 && c <= 13) {
    260     return true;
    261   }
    262 
    263   return false;
    264 }
    265 
    266 static bool StringIsValidForGLES(const char* str) {
    267   for (; *str; ++str) {
    268     if (!CharacterIsValidForGLES(*str)) {
    269       return false;
    270     }
    271   }
    272   return true;
    273 }
    274 
    275 // This class prevents any GL errors that occur when it is in scope from
    276 // being reported to the client.
    277 class ScopedGLErrorSuppressor {
    278  public:
    279   explicit ScopedGLErrorSuppressor(
    280       const char* function_name, ErrorState* error_state);
    281   ~ScopedGLErrorSuppressor();
    282  private:
    283   const char* function_name_;
    284   ErrorState* error_state_;
    285   DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
    286 };
    287 
    288 // Temporarily changes a decoder's bound texture and restore it when this
    289 // object goes out of scope. Also temporarily switches to using active texture
    290 // unit zero in case the client has changed that to something invalid.
    291 class ScopedTextureBinder {
    292  public:
    293   explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
    294   ~ScopedTextureBinder();
    295 
    296  private:
    297   ContextState* state_;
    298   GLenum target_;
    299   DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
    300 };
    301 
    302 // Temporarily changes a decoder's bound render buffer and restore it when this
    303 // object goes out of scope.
    304 class ScopedRenderBufferBinder {
    305  public:
    306   explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
    307   ~ScopedRenderBufferBinder();
    308 
    309  private:
    310   ContextState* state_;
    311   DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
    312 };
    313 
    314 // Temporarily changes a decoder's bound frame buffer and restore it when this
    315 // object goes out of scope.
    316 class ScopedFrameBufferBinder {
    317  public:
    318   explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
    319   ~ScopedFrameBufferBinder();
    320 
    321  private:
    322   GLES2DecoderImpl* decoder_;
    323   DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
    324 };
    325 
    326 // Temporarily changes a decoder's bound frame buffer to a resolved version of
    327 // the multisampled offscreen render buffer if that buffer is multisampled, and,
    328 // if it is bound or enforce_internal_framebuffer is true. If internal is
    329 // true, the resolved framebuffer is not visible to the parent.
    330 class ScopedResolvedFrameBufferBinder {
    331  public:
    332   explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
    333                                            bool enforce_internal_framebuffer,
    334                                            bool internal);
    335   ~ScopedResolvedFrameBufferBinder();
    336 
    337  private:
    338   GLES2DecoderImpl* decoder_;
    339   bool resolve_and_bind_;
    340   DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
    341 };
    342 
    343 class ScopedModifyPixels {
    344  public:
    345   explicit ScopedModifyPixels(TextureRef* ref);
    346   ~ScopedModifyPixels();
    347 
    348  private:
    349   TextureRef* ref_;
    350 };
    351 
    352 ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
    353   if (ref_)
    354     ref_->texture()->OnWillModifyPixels();
    355 }
    356 
    357 ScopedModifyPixels::~ScopedModifyPixels() {
    358   if (ref_)
    359     ref_->texture()->OnDidModifyPixels();
    360 }
    361 
    362 class ScopedRenderTo {
    363  public:
    364   explicit ScopedRenderTo(Framebuffer* framebuffer);
    365   ~ScopedRenderTo();
    366 
    367  private:
    368   const Framebuffer* framebuffer_;
    369 };
    370 
    371 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
    372     : framebuffer_(framebuffer) {
    373   if (framebuffer)
    374     framebuffer_->OnWillRenderTo();
    375 }
    376 
    377 ScopedRenderTo::~ScopedRenderTo() {
    378   if (framebuffer_)
    379     framebuffer_->OnDidRenderTo();
    380 }
    381 
    382 // Encapsulates an OpenGL texture.
    383 class BackTexture {
    384  public:
    385   explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
    386   ~BackTexture();
    387 
    388   // Create a new render texture.
    389   void Create();
    390 
    391   // Set the initial size and format of a render texture or resize it.
    392   bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
    393 
    394   // Copy the contents of the currently bound frame buffer.
    395   void Copy(const gfx::Size& size, GLenum format);
    396 
    397   // Destroy the render texture. This must be explicitly called before
    398   // destroying this object.
    399   void Destroy();
    400 
    401   // Invalidate the texture. This can be used when a context is lost and it is
    402   // not possible to make it current in order to free the resource.
    403   void Invalidate();
    404 
    405   GLuint id() const {
    406     return id_;
    407   }
    408 
    409   gfx::Size size() const {
    410     return size_;
    411   }
    412 
    413  private:
    414   MemoryTypeTracker memory_tracker_;
    415   ContextState* state_;
    416   size_t bytes_allocated_;
    417   GLuint id_;
    418   gfx::Size size_;
    419   DISALLOW_COPY_AND_ASSIGN(BackTexture);
    420 };
    421 
    422 // Encapsulates an OpenGL render buffer of any format.
    423 class BackRenderbuffer {
    424  public:
    425   explicit BackRenderbuffer(
    426       RenderbufferManager* renderbuffer_manager,
    427       MemoryTracker* memory_tracker,
    428       ContextState* state);
    429   ~BackRenderbuffer();
    430 
    431   // Create a new render buffer.
    432   void Create();
    433 
    434   // Set the initial size and format of a render buffer or resize it.
    435   bool AllocateStorage(const FeatureInfo* feature_info,
    436                        const gfx::Size& size,
    437                        GLenum format,
    438                        GLsizei samples);
    439 
    440   // Destroy the render buffer. This must be explicitly called before destroying
    441   // this object.
    442   void Destroy();
    443 
    444   // Invalidate the render buffer. This can be used when a context is lost and
    445   // it is not possible to make it current in order to free the resource.
    446   void Invalidate();
    447 
    448   GLuint id() const {
    449     return id_;
    450   }
    451 
    452  private:
    453   RenderbufferManager* renderbuffer_manager_;
    454   MemoryTypeTracker memory_tracker_;
    455   ContextState* state_;
    456   size_t bytes_allocated_;
    457   GLuint id_;
    458   DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
    459 };
    460 
    461 // Encapsulates an OpenGL frame buffer.
    462 class BackFramebuffer {
    463  public:
    464   explicit BackFramebuffer(GLES2DecoderImpl* decoder);
    465   ~BackFramebuffer();
    466 
    467   // Create a new frame buffer.
    468   void Create();
    469 
    470   // Attach a color render buffer to a frame buffer.
    471   void AttachRenderTexture(BackTexture* texture);
    472 
    473   // Attach a render buffer to a frame buffer. Note that this unbinds any
    474   // currently bound frame buffer.
    475   void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
    476 
    477   // Destroy the frame buffer. This must be explicitly called before destroying
    478   // this object.
    479   void Destroy();
    480 
    481   // Invalidate the frame buffer. This can be used when a context is lost and it
    482   // is not possible to make it current in order to free the resource.
    483   void Invalidate();
    484 
    485   // See glCheckFramebufferStatusEXT.
    486   GLenum CheckStatus();
    487 
    488   GLuint id() const {
    489     return id_;
    490   }
    491 
    492  private:
    493   GLES2DecoderImpl* decoder_;
    494   GLuint id_;
    495   DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
    496 };
    497 
    498 struct FenceCallback {
    499   explicit FenceCallback()
    500       : fence(gfx::GLFence::Create()) {
    501     DCHECK(fence);
    502   }
    503   std::vector<base::Closure> callbacks;
    504   scoped_ptr<gfx::GLFence> fence;
    505 };
    506 
    507 class AsyncUploadTokenCompletionObserver
    508     : public AsyncPixelTransferCompletionObserver {
    509  public:
    510   explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
    511       : async_upload_token_(async_upload_token) {
    512   }
    513 
    514   virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
    515     DCHECK(mem_params.buffer().get());
    516     void* data = mem_params.GetDataAddress();
    517     AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
    518     sync->SetAsyncUploadToken(async_upload_token_);
    519   }
    520 
    521  private:
    522   virtual ~AsyncUploadTokenCompletionObserver() {
    523   }
    524 
    525   uint32 async_upload_token_;
    526 
    527   DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
    528 };
    529 
    530 // }  // anonymous namespace.
    531 
    532 // static
    533 const unsigned int GLES2Decoder::kDefaultStencilMask =
    534     static_cast<unsigned int>(-1);
    535 
    536 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
    537                                        uint32* service_texture_id) {
    538   return false;
    539 }
    540 
    541 GLES2Decoder::GLES2Decoder()
    542     : initialized_(false),
    543       debug_(false),
    544       log_commands_(false) {
    545 }
    546 
    547 GLES2Decoder::~GLES2Decoder() {
    548 }
    549 
    550 void GLES2Decoder::BeginDecoding() {}
    551 
    552 void GLES2Decoder::EndDecoding() {}
    553 
    554 // This class implements GLES2Decoder so we don't have to expose all the GLES2
    555 // cmd stuff to outside this class.
    556 class GLES2DecoderImpl : public GLES2Decoder,
    557                          public FramebufferManager::TextureDetachObserver,
    558                          public ErrorStateClient {
    559  public:
    560   explicit GLES2DecoderImpl(ContextGroup* group);
    561   virtual ~GLES2DecoderImpl();
    562 
    563   // Overridden from AsyncAPIInterface.
    564   virtual Error DoCommand(unsigned int command,
    565                           unsigned int arg_count,
    566                           const void* args) OVERRIDE;
    567 
    568   virtual error::Error DoCommands(unsigned int num_commands,
    569                                   const void* buffer,
    570                                   int num_entries,
    571                                   int* entries_processed) OVERRIDE;
    572 
    573   template <bool DebugImpl>
    574   error::Error DoCommandsImpl(unsigned int num_commands,
    575                               const void* buffer,
    576                               int num_entries,
    577                               int* entries_processed);
    578 
    579   // Overridden from AsyncAPIInterface.
    580   virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
    581 
    582   // Overridden from GLES2Decoder.
    583   virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
    584                           const scoped_refptr<gfx::GLContext>& context,
    585                           bool offscreen,
    586                           const gfx::Size& size,
    587                           const DisallowedFeatures& disallowed_features,
    588                           const std::vector<int32>& attribs) OVERRIDE;
    589   virtual void Destroy(bool have_context) OVERRIDE;
    590   virtual void SetSurface(
    591       const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
    592   virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
    593   virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
    594   void UpdateParentTextureInfo();
    595   virtual bool MakeCurrent() OVERRIDE;
    596   virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
    597   virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
    598   virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
    599   virtual Capabilities GetCapabilities() OVERRIDE;
    600   virtual void RestoreState(const ContextState* prev_state) OVERRIDE;
    601 
    602   virtual void RestoreActiveTexture() const OVERRIDE {
    603     state_.RestoreActiveTexture();
    604   }
    605   virtual void RestoreAllTextureUnitBindings(
    606       const ContextState* prev_state) const OVERRIDE {
    607     state_.RestoreAllTextureUnitBindings(prev_state);
    608   }
    609   virtual void RestoreActiveTextureUnitBinding(
    610       unsigned int target) const OVERRIDE {
    611     state_.RestoreActiveTextureUnitBinding(target);
    612   }
    613   virtual void RestoreBufferBindings() const OVERRIDE {
    614     state_.RestoreBufferBindings();
    615   }
    616   virtual void RestoreGlobalState() const OVERRIDE {
    617     state_.RestoreGlobalState(NULL);
    618   }
    619   virtual void RestoreProgramBindings() const OVERRIDE {
    620     state_.RestoreProgramBindings();
    621   }
    622   virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
    623     state_.RestoreTextureUnitBindings(unit, NULL);
    624   }
    625   virtual void RestoreFramebufferBindings() const OVERRIDE;
    626   virtual void RestoreRenderbufferBindings() OVERRIDE;
    627   virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
    628 
    629   virtual void ClearAllAttributes() const OVERRIDE;
    630   virtual void RestoreAllAttributes() const OVERRIDE;
    631 
    632   virtual QueryManager* GetQueryManager() OVERRIDE {
    633     return query_manager_.get();
    634   }
    635   virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
    636     return vertex_array_manager_.get();
    637   }
    638   virtual ImageManager* GetImageManager() OVERRIDE {
    639     return image_manager_.get();
    640   }
    641   virtual bool ProcessPendingQueries() OVERRIDE;
    642   virtual bool HasMoreIdleWork() OVERRIDE;
    643   virtual void PerformIdleWork() OVERRIDE;
    644 
    645   virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
    646 
    647   virtual void SetResizeCallback(
    648       const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
    649 
    650   virtual Logger* GetLogger() OVERRIDE;
    651 
    652   virtual void BeginDecoding() OVERRIDE;
    653   virtual void EndDecoding() OVERRIDE;
    654 
    655   virtual ErrorState* GetErrorState() OVERRIDE;
    656   virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
    657 
    658   virtual void SetShaderCacheCallback(
    659       const ShaderCacheCallback& callback) OVERRIDE;
    660   virtual void SetWaitSyncPointCallback(
    661       const WaitSyncPointCallback& callback) OVERRIDE;
    662 
    663   virtual AsyncPixelTransferManager*
    664       GetAsyncPixelTransferManager() OVERRIDE;
    665   virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
    666   virtual void SetAsyncPixelTransferManagerForTest(
    667       AsyncPixelTransferManager* manager) OVERRIDE;
    668   virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
    669   void ProcessFinishedAsyncTransfers();
    670 
    671   virtual bool GetServiceTextureId(uint32 client_texture_id,
    672                                    uint32* service_texture_id) OVERRIDE;
    673 
    674   virtual uint32 GetTextureUploadCount() OVERRIDE;
    675   virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
    676   virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
    677   virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
    678 
    679   // Restores the current state to the user's settings.
    680   void RestoreCurrentFramebufferBindings();
    681 
    682   // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
    683   void ApplyDirtyState();
    684 
    685   // These check the state of the currently bound framebuffer or the
    686   // backbuffer if no framebuffer is bound.
    687   // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
    688   // check with all attached and enabled color attachments.
    689   bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
    690   bool BoundFramebufferHasDepthAttachment();
    691   bool BoundFramebufferHasStencilAttachment();
    692 
    693   virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
    694 
    695   // Overridden from FramebufferManager::TextureDetachObserver:
    696   virtual void OnTextureRefDetachedFromFramebuffer(
    697       TextureRef* texture) OVERRIDE;
    698 
    699   // Overriden from ErrorStateClient.
    700   virtual void OnOutOfMemoryError() OVERRIDE;
    701 
    702   // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
    703   void EnsureRenderbufferBound();
    704 
    705   // Helpers to facilitate calling into compatible extensions.
    706   static void RenderbufferStorageMultisampleHelper(
    707       const FeatureInfo* feature_info,
    708       GLenum target,
    709       GLsizei samples,
    710       GLenum internal_format,
    711       GLsizei width,
    712       GLsizei height);
    713 
    714   void BlitFramebufferHelper(GLint srcX0,
    715                              GLint srcY0,
    716                              GLint srcX1,
    717                              GLint srcY1,
    718                              GLint dstX0,
    719                              GLint dstY0,
    720                              GLint dstX1,
    721                              GLint dstY1,
    722                              GLbitfield mask,
    723                              GLenum filter);
    724 
    725  private:
    726   friend class ScopedFrameBufferBinder;
    727   friend class ScopedResolvedFrameBufferBinder;
    728   friend class BackFramebuffer;
    729 
    730   // Initialize or re-initialize the shader translator.
    731   bool InitializeShaderTranslator();
    732 
    733   void UpdateCapabilities();
    734 
    735   // Helpers for the glGen and glDelete functions.
    736   bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
    737   void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
    738   bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
    739   void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
    740   bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
    741   void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
    742   bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
    743   void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
    744   bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
    745   void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
    746   bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
    747   void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
    748 
    749   // Helper for async upload token completion notification callback.
    750   base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
    751                                                   uint32 sync_data_shm_id,
    752                                                   uint32 sync_data_shm_offset);
    753 
    754 
    755 
    756   // Workarounds
    757   void OnFboChanged() const;
    758   void OnUseFramebuffer() const;
    759 
    760   // TODO(gman): Cache these pointers?
    761   BufferManager* buffer_manager() {
    762     return group_->buffer_manager();
    763   }
    764 
    765   RenderbufferManager* renderbuffer_manager() {
    766     return group_->renderbuffer_manager();
    767   }
    768 
    769   FramebufferManager* framebuffer_manager() {
    770     return group_->framebuffer_manager();
    771   }
    772 
    773   ProgramManager* program_manager() {
    774     return group_->program_manager();
    775   }
    776 
    777   ShaderManager* shader_manager() {
    778     return group_->shader_manager();
    779   }
    780 
    781   ShaderTranslatorCache* shader_translator_cache() {
    782     return group_->shader_translator_cache();
    783   }
    784 
    785   const TextureManager* texture_manager() const {
    786     return group_->texture_manager();
    787   }
    788 
    789   TextureManager* texture_manager() {
    790     return group_->texture_manager();
    791   }
    792 
    793   MailboxManager* mailbox_manager() {
    794     return group_->mailbox_manager();
    795   }
    796 
    797   ImageManager* image_manager() { return image_manager_.get(); }
    798 
    799   VertexArrayManager* vertex_array_manager() {
    800     return vertex_array_manager_.get();
    801   }
    802 
    803   MemoryTracker* memory_tracker() {
    804     return group_->memory_tracker();
    805   }
    806 
    807   bool EnsureGPUMemoryAvailable(size_t estimated_size) {
    808     MemoryTracker* tracker = memory_tracker();
    809     if (tracker) {
    810       return tracker->EnsureGPUMemoryAvailable(estimated_size);
    811     }
    812     return true;
    813   }
    814 
    815   bool IsOffscreenBufferMultisampled() const {
    816     return offscreen_target_samples_ > 1;
    817   }
    818 
    819   // Creates a Texture for the given texture.
    820   TextureRef* CreateTexture(
    821       GLuint client_id, GLuint service_id) {
    822     return texture_manager()->CreateTexture(client_id, service_id);
    823   }
    824 
    825   // Gets the texture info for the given texture. Returns NULL if none exists.
    826   TextureRef* GetTexture(GLuint client_id) const {
    827     return texture_manager()->GetTexture(client_id);
    828   }
    829 
    830   // Deletes the texture info for the given texture.
    831   void RemoveTexture(GLuint client_id) {
    832     texture_manager()->RemoveTexture(client_id);
    833   }
    834 
    835   // Get the size (in pixels) of the currently bound frame buffer (either FBO
    836   // or regular back buffer).
    837   gfx::Size GetBoundReadFrameBufferSize();
    838 
    839   // Get the format of the currently bound frame buffer (either FBO or regular
    840   // back buffer)
    841   GLenum GetBoundReadFrameBufferTextureType();
    842   GLenum GetBoundReadFrameBufferInternalFormat();
    843   GLenum GetBoundDrawFrameBufferInternalFormat();
    844 
    845   // Wrapper for CompressedTexImage2D commands.
    846   error::Error DoCompressedTexImage2D(
    847       GLenum target,
    848       GLint level,
    849       GLenum internal_format,
    850       GLsizei width,
    851       GLsizei height,
    852       GLint border,
    853       GLsizei image_size,
    854       const void* data);
    855 
    856   // Wrapper for CompressedTexSubImage2D.
    857   void DoCompressedTexSubImage2D(
    858       GLenum target,
    859       GLint level,
    860       GLint xoffset,
    861       GLint yoffset,
    862       GLsizei width,
    863       GLsizei height,
    864       GLenum format,
    865       GLsizei imageSize,
    866       const void * data);
    867 
    868   // Wrapper for CopyTexImage2D.
    869   void DoCopyTexImage2D(
    870       GLenum target,
    871       GLint level,
    872       GLenum internal_format,
    873       GLint x,
    874       GLint y,
    875       GLsizei width,
    876       GLsizei height,
    877       GLint border);
    878 
    879   // Wrapper for SwapBuffers.
    880   void DoSwapBuffers();
    881 
    882   // Wrapper for CopyTexSubImage2D.
    883   void DoCopyTexSubImage2D(
    884       GLenum target,
    885       GLint level,
    886       GLint xoffset,
    887       GLint yoffset,
    888       GLint x,
    889       GLint y,
    890       GLsizei width,
    891       GLsizei height);
    892 
    893   // Validation for TexSubImage2D.
    894   bool ValidateTexSubImage2D(
    895       error::Error* error,
    896       const char* function_name,
    897       GLenum target,
    898       GLint level,
    899       GLint xoffset,
    900       GLint yoffset,
    901       GLsizei width,
    902       GLsizei height,
    903       GLenum format,
    904       GLenum type,
    905       const void * data);
    906 
    907   // Wrapper for TexSubImage2D.
    908   error::Error DoTexSubImage2D(
    909       GLenum target,
    910       GLint level,
    911       GLint xoffset,
    912       GLint yoffset,
    913       GLsizei width,
    914       GLsizei height,
    915       GLenum format,
    916       GLenum type,
    917       const void * data);
    918 
    919   // Extra validation for async tex(Sub)Image2D.
    920   bool ValidateAsyncTransfer(
    921       const char* function_name,
    922       TextureRef* texture_ref,
    923       GLenum target,
    924       GLint level,
    925       const void * data);
    926 
    927   // Wrapper for TexImageIOSurface2DCHROMIUM.
    928   void DoTexImageIOSurface2DCHROMIUM(
    929       GLenum target,
    930       GLsizei width,
    931       GLsizei height,
    932       GLuint io_surface_id,
    933       GLuint plane);
    934 
    935   void DoCopyTextureCHROMIUM(
    936       GLenum target,
    937       GLuint source_id,
    938       GLuint target_id,
    939       GLint level,
    940       GLenum internal_format,
    941       GLenum dest_type);
    942 
    943   // Wrapper for TexStorage2DEXT.
    944   void DoTexStorage2DEXT(
    945       GLenum target,
    946       GLint levels,
    947       GLenum internal_format,
    948       GLsizei width,
    949       GLsizei height);
    950 
    951   void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
    952   void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
    953       const GLbyte* key);
    954   void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
    955       GLenum target, const GLbyte* data);
    956 
    957   void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
    958   void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
    959     GLuint client_id);
    960 
    961   void DoBindTexImage2DCHROMIUM(
    962       GLenum target,
    963       GLint image_id);
    964   void DoReleaseTexImage2DCHROMIUM(
    965       GLenum target,
    966       GLint image_id);
    967 
    968   void DoTraceEndCHROMIUM(void);
    969 
    970   void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
    971 
    972   void DoLoseContextCHROMIUM(GLenum current, GLenum other);
    973 
    974   void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
    975   void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
    976 
    977   // Creates a Program for the given program.
    978   Program* CreateProgram(
    979       GLuint client_id, GLuint service_id) {
    980     return program_manager()->CreateProgram(client_id, service_id);
    981   }
    982 
    983   // Gets the program info for the given program. Returns NULL if none exists.
    984   Program* GetProgram(GLuint client_id) {
    985     return program_manager()->GetProgram(client_id);
    986   }
    987 
    988 #if defined(NDEBUG)
    989   void LogClientServiceMapping(
    990       const char* /* function_name */,
    991       GLuint /* client_id */,
    992       GLuint /* service_id */) {
    993   }
    994   template<typename T>
    995   void LogClientServiceForInfo(
    996       T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
    997   }
    998 #else
    999   void LogClientServiceMapping(
   1000       const char* function_name, GLuint client_id, GLuint service_id) {
   1001     if (service_logging_) {
   1002       VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
   1003               << ": client_id = " << client_id
   1004               << ", service_id = " << service_id;
   1005     }
   1006   }
   1007   template<typename T>
   1008   void LogClientServiceForInfo(
   1009       T* info, GLuint client_id, const char* function_name) {
   1010     if (info) {
   1011       LogClientServiceMapping(function_name, client_id, info->service_id());
   1012     }
   1013   }
   1014 #endif
   1015 
   1016   // Gets the program info for the given program. If it's not a program
   1017   // generates a GL error. Returns NULL if not program.
   1018   Program* GetProgramInfoNotShader(
   1019       GLuint client_id, const char* function_name) {
   1020     Program* program = GetProgram(client_id);
   1021     if (!program) {
   1022       if (GetShader(client_id)) {
   1023         LOCAL_SET_GL_ERROR(
   1024             GL_INVALID_OPERATION, function_name, "shader passed for program");
   1025       } else {
   1026         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
   1027       }
   1028     }
   1029     LogClientServiceForInfo(program, client_id, function_name);
   1030     return program;
   1031   }
   1032 
   1033 
   1034   // Creates a Shader for the given shader.
   1035   Shader* CreateShader(
   1036       GLuint client_id,
   1037       GLuint service_id,
   1038       GLenum shader_type) {
   1039     return shader_manager()->CreateShader(
   1040         client_id, service_id, shader_type);
   1041   }
   1042 
   1043   // Gets the shader info for the given shader. Returns NULL if none exists.
   1044   Shader* GetShader(GLuint client_id) {
   1045     return shader_manager()->GetShader(client_id);
   1046   }
   1047 
   1048   // Gets the shader info for the given shader. If it's not a shader generates a
   1049   // GL error. Returns NULL if not shader.
   1050   Shader* GetShaderInfoNotProgram(
   1051       GLuint client_id, const char* function_name) {
   1052     Shader* shader = GetShader(client_id);
   1053     if (!shader) {
   1054       if (GetProgram(client_id)) {
   1055         LOCAL_SET_GL_ERROR(
   1056             GL_INVALID_OPERATION, function_name, "program passed for shader");
   1057       } else {
   1058         LOCAL_SET_GL_ERROR(
   1059             GL_INVALID_VALUE, function_name, "unknown shader");
   1060       }
   1061     }
   1062     LogClientServiceForInfo(shader, client_id, function_name);
   1063     return shader;
   1064   }
   1065 
   1066   // Creates a buffer info for the given buffer.
   1067   void CreateBuffer(GLuint client_id, GLuint service_id) {
   1068     return buffer_manager()->CreateBuffer(client_id, service_id);
   1069   }
   1070 
   1071   // Gets the buffer info for the given buffer.
   1072   Buffer* GetBuffer(GLuint client_id) {
   1073     Buffer* buffer = buffer_manager()->GetBuffer(client_id);
   1074     return buffer;
   1075   }
   1076 
   1077   // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
   1078   // on glDeleteBuffers so we can make sure the user does not try to render
   1079   // with deleted buffers.
   1080   void RemoveBuffer(GLuint client_id);
   1081 
   1082   // Creates a framebuffer info for the given framebuffer.
   1083   void CreateFramebuffer(GLuint client_id, GLuint service_id) {
   1084     return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
   1085   }
   1086 
   1087   // Gets the framebuffer info for the given framebuffer.
   1088   Framebuffer* GetFramebuffer(GLuint client_id) {
   1089     return framebuffer_manager()->GetFramebuffer(client_id);
   1090   }
   1091 
   1092   // Removes the framebuffer info for the given framebuffer.
   1093   void RemoveFramebuffer(GLuint client_id) {
   1094     framebuffer_manager()->RemoveFramebuffer(client_id);
   1095   }
   1096 
   1097   // Creates a renderbuffer info for the given renderbuffer.
   1098   void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
   1099     return renderbuffer_manager()->CreateRenderbuffer(
   1100         client_id, service_id);
   1101   }
   1102 
   1103   // Gets the renderbuffer info for the given renderbuffer.
   1104   Renderbuffer* GetRenderbuffer(GLuint client_id) {
   1105     return renderbuffer_manager()->GetRenderbuffer(client_id);
   1106   }
   1107 
   1108   // Removes the renderbuffer info for the given renderbuffer.
   1109   void RemoveRenderbuffer(GLuint client_id) {
   1110     renderbuffer_manager()->RemoveRenderbuffer(client_id);
   1111   }
   1112 
   1113   // Gets the vertex attrib manager for the given vertex array.
   1114   VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
   1115     VertexAttribManager* info =
   1116         vertex_array_manager()->GetVertexAttribManager(client_id);
   1117     return info;
   1118   }
   1119 
   1120   // Removes the vertex attrib manager for the given vertex array.
   1121   void RemoveVertexAttribManager(GLuint client_id) {
   1122     vertex_array_manager()->RemoveVertexAttribManager(client_id);
   1123   }
   1124 
   1125   // Creates a vertex attrib manager for the given vertex array.
   1126   scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
   1127       GLuint client_id,
   1128       GLuint service_id,
   1129       bool client_visible) {
   1130     return vertex_array_manager()->CreateVertexAttribManager(
   1131         client_id, service_id, group_->max_vertex_attribs(), client_visible);
   1132   }
   1133 
   1134   void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
   1135   void DoBindUniformLocationCHROMIUM(
   1136       GLuint client_id, GLint location, const char* name);
   1137 
   1138   error::Error GetAttribLocationHelper(
   1139     GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
   1140     const std::string& name_str);
   1141 
   1142   error::Error GetUniformLocationHelper(
   1143     GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
   1144     const std::string& name_str);
   1145 
   1146   // Helper for glShaderSource.
   1147   error::Error ShaderSourceHelper(
   1148       GLuint client_id, const char* data, uint32 data_size);
   1149 
   1150   // Clear any textures used by the current program.
   1151   bool ClearUnclearedTextures();
   1152 
   1153   // Clears any uncleared attachments attached to the given frame buffer.
   1154   // Returns false if there was a generated GL error.
   1155   void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
   1156 
   1157   // overridden from GLES2Decoder
   1158   virtual bool ClearLevel(unsigned service_id,
   1159                           unsigned bind_target,
   1160                           unsigned target,
   1161                           int level,
   1162                           unsigned internal_format,
   1163                           unsigned format,
   1164                           unsigned type,
   1165                           int width,
   1166                           int height,
   1167                           bool is_texture_immutable) OVERRIDE;
   1168 
   1169   // Restore all GL state that affects clearing.
   1170   void RestoreClearState();
   1171 
   1172   // Remembers the state of some capabilities.
   1173   // Returns: true if glEnable/glDisable should actually be called.
   1174   bool SetCapabilityState(GLenum cap, bool enabled);
   1175 
   1176   // Check that the currently bound framebuffers are valid.
   1177   // Generates GL error if not.
   1178   bool CheckBoundFramebuffersValid(const char* func_name);
   1179 
   1180   // Check that the currently bound read framebuffer has a color image
   1181   // attached. Generates GL error if not.
   1182   bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
   1183 
   1184   // Check if a framebuffer meets our requirements.
   1185   bool CheckFramebufferValid(
   1186       Framebuffer* framebuffer,
   1187       GLenum target,
   1188       const char* func_name);
   1189 
   1190   // Checks if the current program exists and is valid. If not generates the
   1191   // appropriate GL error.  Returns true if the current program is in a usable
   1192   // state.
   1193   bool CheckCurrentProgram(const char* function_name);
   1194 
   1195   // Checks if the current program exists and is valid and that location is not
   1196   // -1. If the current program is not valid generates the appropriate GL
   1197   // error. Returns true if the current program is in a usable state and
   1198   // location is not -1.
   1199   bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
   1200 
   1201   // Gets the type of a uniform for a location in the current program. Sets GL
   1202   // errors if the current program is not valid. Returns true if the current
   1203   // program is valid and the location exists. Adjusts count so it
   1204   // does not overflow the uniform.
   1205   bool PrepForSetUniformByLocation(GLint fake_location,
   1206                                    const char* function_name,
   1207                                    Program::UniformApiType api_type,
   1208                                    GLint* real_location,
   1209                                    GLenum* type,
   1210                                    GLsizei* count);
   1211 
   1212   // Gets the service id for any simulated backbuffer fbo.
   1213   GLuint GetBackbufferServiceId() const;
   1214 
   1215   // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
   1216   bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
   1217 
   1218   // Helper for glGetVertexAttrib
   1219   void GetVertexAttribHelper(
   1220     const VertexAttrib* attrib, GLenum pname, GLint* param);
   1221 
   1222   // Wrapper for glCreateProgram
   1223   bool CreateProgramHelper(GLuint client_id);
   1224 
   1225   // Wrapper for glCreateShader
   1226   bool CreateShaderHelper(GLenum type, GLuint client_id);
   1227 
   1228   // Wrapper for glActiveTexture
   1229   void DoActiveTexture(GLenum texture_unit);
   1230 
   1231   // Wrapper for glAttachShader
   1232   void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
   1233 
   1234   // Wrapper for glBindBuffer since we need to track the current targets.
   1235   void DoBindBuffer(GLenum target, GLuint buffer);
   1236 
   1237   // Wrapper for glBindFramebuffer since we need to track the current targets.
   1238   void DoBindFramebuffer(GLenum target, GLuint framebuffer);
   1239 
   1240   // Wrapper for glBindRenderbuffer since we need to track the current targets.
   1241   void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
   1242 
   1243   // Wrapper for glBindTexture since we need to track the current targets.
   1244   void DoBindTexture(GLenum target, GLuint texture);
   1245 
   1246   // Wrapper for glBindVertexArrayOES
   1247   void DoBindVertexArrayOES(GLuint array);
   1248   void EmulateVertexArrayState();
   1249 
   1250   // Wrapper for glBlitFramebufferCHROMIUM.
   1251   void DoBlitFramebufferCHROMIUM(
   1252       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   1253       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   1254       GLbitfield mask, GLenum filter);
   1255 
   1256   // Wrapper for glBufferSubData.
   1257   void DoBufferSubData(
   1258     GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
   1259 
   1260   // Wrapper for glCheckFramebufferStatus
   1261   GLenum DoCheckFramebufferStatus(GLenum target);
   1262 
   1263   // Wrapper for glClear
   1264   error::Error DoClear(GLbitfield mask);
   1265 
   1266   // Wrappers for various state.
   1267   void DoDepthRangef(GLclampf znear, GLclampf zfar);
   1268   void DoSampleCoverage(GLclampf value, GLboolean invert);
   1269 
   1270   // Wrapper for glCompileShader.
   1271   void DoCompileShader(GLuint shader);
   1272 
   1273   // Helper for DeleteSharedIdsCHROMIUM commands.
   1274   void DoDeleteSharedIdsCHROMIUM(
   1275       GLuint namespace_id, GLsizei n, const GLuint* ids);
   1276 
   1277   // Wrapper for glDetachShader
   1278   void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
   1279 
   1280   // Wrapper for glDisable
   1281   void DoDisable(GLenum cap);
   1282 
   1283   // Wrapper for glDisableVertexAttribArray.
   1284   void DoDisableVertexAttribArray(GLuint index);
   1285 
   1286   // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
   1287   // attachments.
   1288   void DoDiscardFramebufferEXT(GLenum target,
   1289                                GLsizei numAttachments,
   1290                                const GLenum* attachments);
   1291 
   1292   // Wrapper for glEnable
   1293   void DoEnable(GLenum cap);
   1294 
   1295   // Wrapper for glEnableVertexAttribArray.
   1296   void DoEnableVertexAttribArray(GLuint index);
   1297 
   1298   // Wrapper for glFinish.
   1299   void DoFinish();
   1300 
   1301   // Wrapper for glFlush.
   1302   void DoFlush();
   1303 
   1304   // Wrapper for glFramebufferRenderbufffer.
   1305   void DoFramebufferRenderbuffer(
   1306       GLenum target, GLenum attachment, GLenum renderbuffertarget,
   1307       GLuint renderbuffer);
   1308 
   1309   // Wrapper for glFramebufferTexture2D.
   1310   void DoFramebufferTexture2D(
   1311       GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
   1312       GLint level);
   1313 
   1314   // Wrapper for glFramebufferTexture2DMultisampleEXT.
   1315   void DoFramebufferTexture2DMultisample(
   1316       GLenum target, GLenum attachment, GLenum textarget,
   1317       GLuint texture, GLint level, GLsizei samples);
   1318 
   1319   // Common implementation for both DoFramebufferTexture2D wrappers.
   1320   void DoFramebufferTexture2DCommon(const char* name,
   1321       GLenum target, GLenum attachment, GLenum textarget,
   1322       GLuint texture, GLint level, GLsizei samples);
   1323 
   1324   // Wrapper for glGenerateMipmap
   1325   void DoGenerateMipmap(GLenum target);
   1326 
   1327   // Helper for GenSharedIdsCHROMIUM commands.
   1328   void DoGenSharedIdsCHROMIUM(
   1329       GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
   1330 
   1331   // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
   1332   // to account for different pname values defined in different extension
   1333   // variants.
   1334   GLenum AdjustGetPname(GLenum pname);
   1335 
   1336   // Wrapper for DoGetBooleanv.
   1337   void DoGetBooleanv(GLenum pname, GLboolean* params);
   1338 
   1339   // Wrapper for DoGetFloatv.
   1340   void DoGetFloatv(GLenum pname, GLfloat* params);
   1341 
   1342   // Wrapper for glGetFramebufferAttachmentParameteriv.
   1343   void DoGetFramebufferAttachmentParameteriv(
   1344       GLenum target, GLenum attachment, GLenum pname, GLint* params);
   1345 
   1346   // Wrapper for glGetIntegerv.
   1347   void DoGetIntegerv(GLenum pname, GLint* params);
   1348 
   1349   // Gets the max value in a range in a buffer.
   1350   GLuint DoGetMaxValueInBufferCHROMIUM(
   1351       GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
   1352 
   1353   // Wrapper for glGetBufferParameteriv.
   1354   void DoGetBufferParameteriv(
   1355       GLenum target, GLenum pname, GLint* params);
   1356 
   1357   // Wrapper for glGetProgramiv.
   1358   void DoGetProgramiv(
   1359       GLuint program_id, GLenum pname, GLint* params);
   1360 
   1361   // Wrapper for glRenderbufferParameteriv.
   1362   void DoGetRenderbufferParameteriv(
   1363       GLenum target, GLenum pname, GLint* params);
   1364 
   1365   // Wrapper for glGetShaderiv
   1366   void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
   1367 
   1368   // Wrappers for glGetTexParameter.
   1369   void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
   1370   void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
   1371   void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
   1372 
   1373   // Wrappers for glGetVertexAttrib.
   1374   void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
   1375   void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
   1376 
   1377   // Wrappers for glIsXXX functions.
   1378   bool DoIsEnabled(GLenum cap);
   1379   bool DoIsBuffer(GLuint client_id);
   1380   bool DoIsFramebuffer(GLuint client_id);
   1381   bool DoIsProgram(GLuint client_id);
   1382   bool DoIsRenderbuffer(GLuint client_id);
   1383   bool DoIsShader(GLuint client_id);
   1384   bool DoIsTexture(GLuint client_id);
   1385   bool DoIsVertexArrayOES(GLuint client_id);
   1386 
   1387   // Wrapper for glLinkProgram
   1388   void DoLinkProgram(GLuint program);
   1389 
   1390   // Helper for RegisterSharedIdsCHROMIUM.
   1391   void DoRegisterSharedIdsCHROMIUM(
   1392       GLuint namespace_id, GLsizei n, const GLuint* ids);
   1393 
   1394   // Wrapper for glRenderbufferStorage.
   1395   void DoRenderbufferStorage(
   1396       GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
   1397 
   1398   // Handler for glRenderbufferStorageMultisampleCHROMIUM.
   1399   void DoRenderbufferStorageMultisampleCHROMIUM(
   1400       GLenum target, GLsizei samples, GLenum internalformat,
   1401       GLsizei width, GLsizei height);
   1402 
   1403   // Handler for glRenderbufferStorageMultisampleEXT
   1404   // (multisampled_render_to_texture).
   1405   void DoRenderbufferStorageMultisampleEXT(
   1406       GLenum target, GLsizei samples, GLenum internalformat,
   1407       GLsizei width, GLsizei height);
   1408 
   1409   // Common validation for multisample extensions.
   1410   bool ValidateRenderbufferStorageMultisample(GLsizei samples,
   1411                                               GLenum internalformat,
   1412                                               GLsizei width,
   1413                                               GLsizei height);
   1414 
   1415   // Verifies that the currently bound multisample renderbuffer is valid
   1416   // Very slow! Only done on platforms with driver bugs that return invalid
   1417   // buffers under memory pressure
   1418   bool VerifyMultisampleRenderbufferIntegrity(
   1419       GLuint renderbuffer, GLenum format);
   1420 
   1421   // Wrapper for glReleaseShaderCompiler.
   1422   void DoReleaseShaderCompiler() { }
   1423 
   1424   // Wrappers for glTexParameter functions.
   1425   void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
   1426   void DoTexParameteri(GLenum target, GLenum pname, GLint param);
   1427   void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
   1428   void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
   1429 
   1430   // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
   1431   // spec only these 2 functions can be used to set sampler uniforms.
   1432   void DoUniform1i(GLint fake_location, GLint v0);
   1433   void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
   1434   void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
   1435   void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
   1436   void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
   1437 
   1438   // Wrappers for glUniformfv because some drivers don't correctly accept
   1439   // bool uniforms.
   1440   void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
   1441   void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
   1442   void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
   1443   void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
   1444 
   1445   void DoUniformMatrix2fv(
   1446       GLint fake_location, GLsizei count, GLboolean transpose,
   1447       const GLfloat* value);
   1448   void DoUniformMatrix3fv(
   1449       GLint fake_location, GLsizei count, GLboolean transpose,
   1450       const GLfloat* value);
   1451   void DoUniformMatrix4fv(
   1452       GLint fake_location, GLsizei count, GLboolean transpose,
   1453       const GLfloat* value);
   1454 
   1455   bool SetVertexAttribValue(
   1456     const char* function_name, GLuint index, const GLfloat* value);
   1457 
   1458   // Wrappers for glVertexAttrib??
   1459   void DoVertexAttrib1f(GLuint index, GLfloat v0);
   1460   void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
   1461   void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
   1462   void DoVertexAttrib4f(
   1463       GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
   1464   void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
   1465   void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
   1466   void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
   1467   void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
   1468 
   1469   // Wrapper for glViewport
   1470   void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
   1471 
   1472   // Wrapper for glUseProgram
   1473   void DoUseProgram(GLuint program);
   1474 
   1475   // Wrapper for glValidateProgram.
   1476   void DoValidateProgram(GLuint program_client_id);
   1477 
   1478   void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
   1479   void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
   1480   void DoPopGroupMarkerEXT(void);
   1481 
   1482   // Gets the number of values that will be returned by glGetXXX. Returns
   1483   // false if pname is unknown.
   1484   bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
   1485 
   1486   // Checks if the current program and vertex attributes are valid for drawing.
   1487   bool IsDrawValid(
   1488       const char* function_name, GLuint max_vertex_accessed, bool instanced,
   1489       GLsizei primcount);
   1490 
   1491   // Returns true if successful, simulated will be true if attrib0 was
   1492   // simulated.
   1493   bool SimulateAttrib0(
   1494       const char* function_name, GLuint max_vertex_accessed, bool* simulated);
   1495   void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
   1496 
   1497   // If an image is bound to texture, this will call Will/DidUseTexImage
   1498   // if needed.
   1499   void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
   1500   void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
   1501 
   1502   // Returns false if textures were replaced.
   1503   bool PrepareTexturesForRender();
   1504   void RestoreStateForTextures();
   1505 
   1506   // Returns true if GL_FIXED attribs were simulated.
   1507   bool SimulateFixedAttribs(
   1508       const char* function_name,
   1509       GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
   1510   void RestoreStateForSimulatedFixedAttribs();
   1511 
   1512   // Handle DrawArrays and DrawElements for both instanced and non-instanced
   1513   // cases (primcount is always 1 for non-instanced).
   1514   error::Error DoDrawArrays(
   1515       const char* function_name,
   1516       bool instanced, GLenum mode, GLint first, GLsizei count,
   1517       GLsizei primcount);
   1518   error::Error DoDrawElements(
   1519       const char* function_name,
   1520       bool instanced, GLenum mode, GLsizei count, GLenum type,
   1521       int32 offset, GLsizei primcount);
   1522 
   1523   GLenum GetBindTargetForSamplerType(GLenum type) {
   1524     DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
   1525            type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
   1526     switch (type) {
   1527       case GL_SAMPLER_2D:
   1528         return GL_TEXTURE_2D;
   1529       case GL_SAMPLER_CUBE:
   1530         return GL_TEXTURE_CUBE_MAP;
   1531       case GL_SAMPLER_EXTERNAL_OES:
   1532         return GL_TEXTURE_EXTERNAL_OES;
   1533       case GL_SAMPLER_2D_RECT_ARB:
   1534         return GL_TEXTURE_RECTANGLE_ARB;
   1535     }
   1536 
   1537     NOTREACHED();
   1538     return 0;
   1539   }
   1540 
   1541   // Gets the framebuffer info for a particular target.
   1542   Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
   1543     Framebuffer* framebuffer = NULL;
   1544     switch (target) {
   1545       case GL_FRAMEBUFFER:
   1546       case GL_DRAW_FRAMEBUFFER_EXT:
   1547         framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
   1548         break;
   1549       case GL_READ_FRAMEBUFFER_EXT:
   1550         framebuffer = framebuffer_state_.bound_read_framebuffer.get();
   1551         break;
   1552       default:
   1553         NOTREACHED();
   1554         break;
   1555     }
   1556     return framebuffer;
   1557   }
   1558 
   1559   Renderbuffer* GetRenderbufferInfoForTarget(
   1560       GLenum target) {
   1561     Renderbuffer* renderbuffer = NULL;
   1562     switch (target) {
   1563       case GL_RENDERBUFFER:
   1564         renderbuffer = state_.bound_renderbuffer.get();
   1565         break;
   1566       default:
   1567         NOTREACHED();
   1568         break;
   1569     }
   1570     return renderbuffer;
   1571   }
   1572 
   1573   // Validates the program and location for a glGetUniform call and returns
   1574   // a SizeResult setup to receive the result. Returns true if glGetUniform
   1575   // should be called.
   1576   bool GetUniformSetup(
   1577       GLuint program, GLint fake_location,
   1578       uint32 shm_id, uint32 shm_offset,
   1579       error::Error* error, GLint* real_location, GLuint* service_id,
   1580       void** result, GLenum* result_type);
   1581 
   1582   virtual bool WasContextLost() OVERRIDE;
   1583   virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
   1584   virtual void LoseContext(uint32 reset_status) OVERRIDE;
   1585 
   1586 #if defined(OS_MACOSX)
   1587   void ReleaseIOSurfaceForTexture(GLuint texture_id);
   1588 #endif
   1589 
   1590   bool ValidateCompressedTexDimensions(
   1591       const char* function_name,
   1592       GLint level, GLsizei width, GLsizei height, GLenum format);
   1593   bool ValidateCompressedTexFuncData(
   1594       const char* function_name,
   1595       GLsizei width, GLsizei height, GLenum format, size_t size);
   1596   bool ValidateCompressedTexSubDimensions(
   1597     const char* function_name,
   1598     GLenum target, GLint level, GLint xoffset, GLint yoffset,
   1599     GLsizei width, GLsizei height, GLenum format,
   1600     Texture* texture);
   1601 
   1602   void RenderWarning(const char* filename, int line, const std::string& msg);
   1603   void PerformanceWarning(
   1604       const char* filename, int line, const std::string& msg);
   1605 
   1606   const FeatureInfo::FeatureFlags& features() const {
   1607     return feature_info_->feature_flags();
   1608   }
   1609 
   1610   const FeatureInfo::Workarounds& workarounds() const {
   1611     return feature_info_->workarounds();
   1612   }
   1613 
   1614   bool ShouldDeferDraws() {
   1615     return !offscreen_target_frame_buffer_.get() &&
   1616            framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
   1617            surface_->DeferDraws();
   1618   }
   1619 
   1620   bool ShouldDeferReads() {
   1621     return !offscreen_target_frame_buffer_.get() &&
   1622            framebuffer_state_.bound_read_framebuffer.get() == NULL &&
   1623            surface_->DeferDraws();
   1624   }
   1625 
   1626   error::Error WillAccessBoundFramebufferForDraw() {
   1627     if (ShouldDeferDraws())
   1628       return error::kDeferCommandUntilLater;
   1629     if (!offscreen_target_frame_buffer_.get() &&
   1630         !framebuffer_state_.bound_draw_framebuffer.get() &&
   1631         !surface_->SetBackbufferAllocation(true))
   1632       return error::kLostContext;
   1633     return error::kNoError;
   1634   }
   1635 
   1636   error::Error WillAccessBoundFramebufferForRead() {
   1637     if (ShouldDeferReads())
   1638       return error::kDeferCommandUntilLater;
   1639     if (!offscreen_target_frame_buffer_.get() &&
   1640         !framebuffer_state_.bound_read_framebuffer.get() &&
   1641         !surface_->SetBackbufferAllocation(true))
   1642       return error::kLostContext;
   1643     return error::kNoError;
   1644   }
   1645 
   1646   // Set remaining commands to process to 0 to force DoCommands to return
   1647   // and allow context preemption and GPU watchdog checks in GpuScheduler().
   1648   void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
   1649 
   1650   void ProcessPendingReadPixels();
   1651   void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
   1652 
   1653   // Generate a member function prototype for each command in an automated and
   1654   // typesafe way.
   1655 #define GLES2_CMD_OP(name) \
   1656   Error Handle##name(uint32 immediate_data_size, const void* data);
   1657 
   1658   GLES2_COMMAND_LIST(GLES2_CMD_OP)
   1659 
   1660   #undef GLES2_CMD_OP
   1661 
   1662   // The GL context this decoder renders to on behalf of the client.
   1663   scoped_refptr<gfx::GLSurface> surface_;
   1664   scoped_refptr<gfx::GLContext> context_;
   1665 
   1666   // The ContextGroup for this decoder uses to track resources.
   1667   scoped_refptr<ContextGroup> group_;
   1668 
   1669   DebugMarkerManager debug_marker_manager_;
   1670   Logger logger_;
   1671 
   1672   // All the state for this context.
   1673   ContextState state_;
   1674 
   1675   // Current width and height of the offscreen frame buffer.
   1676   gfx::Size offscreen_size_;
   1677 
   1678   // Util to help with GL.
   1679   GLES2Util util_;
   1680 
   1681   // unpack flip y as last set by glPixelStorei
   1682   bool unpack_flip_y_;
   1683 
   1684   // unpack (un)premultiply alpha as last set by glPixelStorei
   1685   bool unpack_premultiply_alpha_;
   1686   bool unpack_unpremultiply_alpha_;
   1687 
   1688   // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
   1689   GLuint attrib_0_buffer_id_;
   1690 
   1691   // The value currently in attrib_0.
   1692   Vec4 attrib_0_value_;
   1693 
   1694   // Whether or not the attrib_0 buffer holds the attrib_0_value.
   1695   bool attrib_0_buffer_matches_value_;
   1696 
   1697   // The size of attrib 0.
   1698   GLsizei attrib_0_size_;
   1699 
   1700   // The buffer used to simulate GL_FIXED attribs.
   1701   GLuint fixed_attrib_buffer_id_;
   1702 
   1703   // The size of fiixed attrib buffer.
   1704   GLsizei fixed_attrib_buffer_size_;
   1705 
   1706   // The offscreen frame buffer that the client renders to. With EGL, the
   1707   // depth and stencil buffers are separate. With regular GL there is a single
   1708   // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
   1709   // offscreen_target_stencil_render_buffer_ is unused.
   1710   scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
   1711   scoped_ptr<BackTexture> offscreen_target_color_texture_;
   1712   scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
   1713   scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
   1714   scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
   1715   GLenum offscreen_target_color_format_;
   1716   GLenum offscreen_target_depth_format_;
   1717   GLenum offscreen_target_stencil_format_;
   1718   GLsizei offscreen_target_samples_;
   1719   GLboolean offscreen_target_buffer_preserved_;
   1720 
   1721   // The copy that is saved when SwapBuffers is called.
   1722   scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
   1723   scoped_ptr<BackTexture> offscreen_saved_color_texture_;
   1724   scoped_refptr<TextureRef>
   1725       offscreen_saved_color_texture_info_;
   1726 
   1727   // The copy that is used as the destination for multi-sample resolves.
   1728   scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
   1729   scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
   1730   GLenum offscreen_saved_color_format_;
   1731 
   1732   scoped_ptr<QueryManager> query_manager_;
   1733 
   1734   scoped_ptr<VertexArrayManager> vertex_array_manager_;
   1735 
   1736   scoped_ptr<ImageManager> image_manager_;
   1737 
   1738   base::Callback<void(gfx::Size, float)> resize_callback_;
   1739 
   1740   WaitSyncPointCallback wait_sync_point_callback_;
   1741 
   1742   ShaderCacheCallback shader_cache_callback_;
   1743 
   1744   scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
   1745 
   1746   // The format of the back buffer_
   1747   GLenum back_buffer_color_format_;
   1748   bool back_buffer_has_depth_;
   1749   bool back_buffer_has_stencil_;
   1750 
   1751   bool surfaceless_;
   1752 
   1753   // Backbuffer attachments that are currently undefined.
   1754   uint32 backbuffer_needs_clear_bits_;
   1755 
   1756   // The current decoder error communicates the decoder error through command
   1757   // processing functions that do not return the error value. Should be set only
   1758   // if not returning an error.
   1759   error::Error current_decoder_error_;
   1760 
   1761   bool use_shader_translator_;
   1762   scoped_refptr<ShaderTranslator> vertex_translator_;
   1763   scoped_refptr<ShaderTranslator> fragment_translator_;
   1764 
   1765   DisallowedFeatures disallowed_features_;
   1766 
   1767   // Cached from ContextGroup
   1768   const Validators* validators_;
   1769   scoped_refptr<FeatureInfo> feature_info_;
   1770 
   1771   int frame_number_;
   1772 
   1773   // Number of commands remaining to be processed in DoCommands().
   1774   int commands_to_process_;
   1775 
   1776   bool has_robustness_extension_;
   1777   GLenum reset_status_;
   1778   bool reset_by_robustness_extension_;
   1779   bool supports_post_sub_buffer_;
   1780 
   1781   // These flags are used to override the state of the shared feature_info_
   1782   // member.  Because the same FeatureInfo instance may be shared among many
   1783   // contexts, the assumptions on the availablity of extensions in WebGL
   1784   // contexts may be broken.  These flags override the shared state to preserve
   1785   // WebGL semantics.
   1786   bool force_webgl_glsl_validation_;
   1787   bool derivatives_explicitly_enabled_;
   1788   bool frag_depth_explicitly_enabled_;
   1789   bool draw_buffers_explicitly_enabled_;
   1790   bool shader_texture_lod_explicitly_enabled_;
   1791 
   1792   bool compile_shader_always_succeeds_;
   1793 
   1794   // An optional behaviour to lose the context and group when OOM.
   1795   bool lose_context_when_out_of_memory_;
   1796 
   1797   // Log extra info.
   1798   bool service_logging_;
   1799 
   1800 #if defined(OS_MACOSX)
   1801   typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
   1802   TextureToIOSurfaceMap texture_to_io_surface_map_;
   1803 #endif
   1804 
   1805   scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
   1806 
   1807   // Cached values of the currently assigned viewport dimensions.
   1808   GLsizei viewport_max_width_;
   1809   GLsizei viewport_max_height_;
   1810 
   1811   // Command buffer stats.
   1812   base::TimeDelta total_processing_commands_time_;
   1813 
   1814   // States related to each manager.
   1815   DecoderTextureState texture_state_;
   1816   DecoderFramebufferState framebuffer_state_;
   1817 
   1818   scoped_ptr<GPUTracer> gpu_tracer_;
   1819   scoped_ptr<GPUStateTracer> gpu_state_tracer_;
   1820   const unsigned char* cb_command_trace_category_;
   1821   int gpu_trace_level_;
   1822   bool gpu_trace_commands_;
   1823   bool gpu_debug_commands_;
   1824 
   1825   std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
   1826 
   1827   // Used to validate multisample renderbuffers if needed
   1828   GLuint validation_texture_;
   1829   GLuint validation_fbo_multisample_;
   1830   GLuint validation_fbo_;
   1831 
   1832   typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
   1833       uint32 immediate_data_size,
   1834       const void* data);
   1835 
   1836   // A struct to hold info about each command.
   1837   struct CommandInfo {
   1838     CmdHandler cmd_handler;
   1839     uint8 arg_flags;   // How to handle the arguments for this command
   1840     uint8 cmd_flags;   // How to handle this command
   1841     uint16 arg_count;  // How many arguments are expected for this command.
   1842   };
   1843 
   1844   // A table of CommandInfo for all the commands.
   1845   static const CommandInfo command_info[kNumCommands - kStartPoint];
   1846 
   1847   DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
   1848 };
   1849 
   1850 const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
   1851 #define GLES2_CMD_OP(name)                                   \
   1852   {                                                          \
   1853     &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags,  \
   1854         cmds::name::cmd_flags,                               \
   1855         sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
   1856   }                                                          \
   1857   , /* NOLINT */
   1858     GLES2_COMMAND_LIST(GLES2_CMD_OP)
   1859 #undef GLES2_CMD_OP
   1860 };
   1861 
   1862 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
   1863     const char* function_name, ErrorState* error_state)
   1864     : function_name_(function_name),
   1865       error_state_(error_state) {
   1866   ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
   1867 }
   1868 
   1869 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
   1870   ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
   1871 }
   1872 
   1873 static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
   1874   TextureUnit& info = state->texture_units[0];
   1875   GLuint last_id;
   1876   scoped_refptr<TextureRef> texture_ref;
   1877   switch (target) {
   1878     case GL_TEXTURE_2D:
   1879       texture_ref = info.bound_texture_2d;
   1880       break;
   1881     case GL_TEXTURE_CUBE_MAP:
   1882       texture_ref = info.bound_texture_cube_map;
   1883       break;
   1884     case GL_TEXTURE_EXTERNAL_OES:
   1885       texture_ref = info.bound_texture_external_oes;
   1886       break;
   1887     case GL_TEXTURE_RECTANGLE_ARB:
   1888       texture_ref = info.bound_texture_rectangle_arb;
   1889       break;
   1890     default:
   1891       NOTREACHED();
   1892       break;
   1893   }
   1894   if (texture_ref.get()) {
   1895     last_id = texture_ref->service_id();
   1896   } else {
   1897     last_id = 0;
   1898   }
   1899 
   1900   glBindTexture(target, last_id);
   1901   glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
   1902 }
   1903 
   1904 ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
   1905                                          GLuint id,
   1906                                          GLenum target)
   1907     : state_(state),
   1908       target_(target) {
   1909   ScopedGLErrorSuppressor suppressor(
   1910       "ScopedTextureBinder::ctor", state_->GetErrorState());
   1911 
   1912   // TODO(apatrick): Check if there are any other states that need to be reset
   1913   // before binding a new texture.
   1914   glActiveTexture(GL_TEXTURE0);
   1915   glBindTexture(target, id);
   1916 }
   1917 
   1918 ScopedTextureBinder::~ScopedTextureBinder() {
   1919   ScopedGLErrorSuppressor suppressor(
   1920       "ScopedTextureBinder::dtor", state_->GetErrorState());
   1921   RestoreCurrentTextureBindings(state_, target_);
   1922 }
   1923 
   1924 ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
   1925                                                    GLuint id)
   1926     : state_(state) {
   1927   ScopedGLErrorSuppressor suppressor(
   1928       "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
   1929   glBindRenderbufferEXT(GL_RENDERBUFFER, id);
   1930 }
   1931 
   1932 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
   1933   ScopedGLErrorSuppressor suppressor(
   1934       "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
   1935   state_->RestoreRenderbufferBindings();
   1936 }
   1937 
   1938 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
   1939                                                  GLuint id)
   1940     : decoder_(decoder) {
   1941   ScopedGLErrorSuppressor suppressor(
   1942       "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
   1943   glBindFramebufferEXT(GL_FRAMEBUFFER, id);
   1944   decoder->OnFboChanged();
   1945 }
   1946 
   1947 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
   1948   ScopedGLErrorSuppressor suppressor(
   1949       "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
   1950   decoder_->RestoreCurrentFramebufferBindings();
   1951 }
   1952 
   1953 ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
   1954     GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
   1955     : decoder_(decoder) {
   1956   resolve_and_bind_ = (
   1957       decoder_->offscreen_target_frame_buffer_.get() &&
   1958       decoder_->IsOffscreenBufferMultisampled() &&
   1959       (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
   1960        enforce_internal_framebuffer));
   1961   if (!resolve_and_bind_)
   1962     return;
   1963 
   1964   ScopedGLErrorSuppressor suppressor(
   1965       "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
   1966   glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
   1967                        decoder_->offscreen_target_frame_buffer_->id());
   1968   GLuint targetid;
   1969   if (internal) {
   1970     if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
   1971       decoder_->offscreen_resolved_frame_buffer_.reset(
   1972           new BackFramebuffer(decoder_));
   1973       decoder_->offscreen_resolved_frame_buffer_->Create();
   1974       decoder_->offscreen_resolved_color_texture_.reset(
   1975           new BackTexture(decoder->memory_tracker(), &decoder->state_));
   1976       decoder_->offscreen_resolved_color_texture_->Create();
   1977 
   1978       DCHECK(decoder_->offscreen_saved_color_format_);
   1979       decoder_->offscreen_resolved_color_texture_->AllocateStorage(
   1980           decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
   1981           false);
   1982       decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
   1983           decoder_->offscreen_resolved_color_texture_.get());
   1984       if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
   1985           GL_FRAMEBUFFER_COMPLETE) {
   1986         LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
   1987                    << "because offscreen resolved FBO was incomplete.";
   1988         return;
   1989       }
   1990     }
   1991     targetid = decoder_->offscreen_resolved_frame_buffer_->id();
   1992   } else {
   1993     targetid = decoder_->offscreen_saved_frame_buffer_->id();
   1994   }
   1995   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
   1996   const int width = decoder_->offscreen_size_.width();
   1997   const int height = decoder_->offscreen_size_.height();
   1998   decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   1999   decoder->BlitFramebufferHelper(0,
   2000                                  0,
   2001                                  width,
   2002                                  height,
   2003                                  0,
   2004                                  0,
   2005                                  width,
   2006                                  height,
   2007                                  GL_COLOR_BUFFER_BIT,
   2008                                  GL_NEAREST);
   2009   glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
   2010 }
   2011 
   2012 ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
   2013   if (!resolve_and_bind_)
   2014     return;
   2015 
   2016   ScopedGLErrorSuppressor suppressor(
   2017       "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
   2018   decoder_->RestoreCurrentFramebufferBindings();
   2019   if (decoder_->state_.enable_flags.scissor_test) {
   2020     decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
   2021   }
   2022 }
   2023 
   2024 BackTexture::BackTexture(
   2025     MemoryTracker* memory_tracker,
   2026     ContextState* state)
   2027     : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
   2028       state_(state),
   2029       bytes_allocated_(0),
   2030       id_(0) {
   2031 }
   2032 
   2033 BackTexture::~BackTexture() {
   2034   // This does not destroy the render texture because that would require that
   2035   // the associated GL context was current. Just check that it was explicitly
   2036   // destroyed.
   2037   DCHECK_EQ(id_, 0u);
   2038 }
   2039 
   2040 void BackTexture::Create() {
   2041   ScopedGLErrorSuppressor suppressor("BackTexture::Create",
   2042                                      state_->GetErrorState());
   2043   Destroy();
   2044   glGenTextures(1, &id_);
   2045   ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
   2046   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   2047   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   2048   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   2049   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   2050 
   2051   // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
   2052   // never called on an offscreen context, no data will ever be uploaded to the
   2053   // saved offscreen color texture (it is deferred until to when SwapBuffers
   2054   // is called). My idea is that some nvidia drivers might have a bug where
   2055   // deleting a texture that has never been populated might cause a
   2056   // crash.
   2057   glTexImage2D(
   2058       GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   2059 
   2060   bytes_allocated_ = 16u * 16u * 4u;
   2061   memory_tracker_.TrackMemAlloc(bytes_allocated_);
   2062 }
   2063 
   2064 bool BackTexture::AllocateStorage(
   2065     const gfx::Size& size, GLenum format, bool zero) {
   2066   DCHECK_NE(id_, 0u);
   2067   ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
   2068                                      state_->GetErrorState());
   2069   ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
   2070   uint32 image_size = 0;
   2071   GLES2Util::ComputeImageDataSizes(
   2072       size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
   2073       NULL, NULL);
   2074 
   2075   if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
   2076     return false;
   2077   }
   2078 
   2079   scoped_ptr<char[]> zero_data;
   2080   if (zero) {
   2081     zero_data.reset(new char[image_size]);
   2082     memset(zero_data.get(), 0, image_size);
   2083   }
   2084 
   2085   glTexImage2D(GL_TEXTURE_2D,
   2086                0,  // mip level
   2087                format,
   2088                size.width(),
   2089                size.height(),
   2090                0,  // border
   2091                format,
   2092                GL_UNSIGNED_BYTE,
   2093                zero_data.get());
   2094 
   2095   size_ = size;
   2096 
   2097   bool success = glGetError() == GL_NO_ERROR;
   2098   if (success) {
   2099     memory_tracker_.TrackMemFree(bytes_allocated_);
   2100     bytes_allocated_ = image_size;
   2101     memory_tracker_.TrackMemAlloc(bytes_allocated_);
   2102   }
   2103   return success;
   2104 }
   2105 
   2106 void BackTexture::Copy(const gfx::Size& size, GLenum format) {
   2107   DCHECK_NE(id_, 0u);
   2108   ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
   2109                                      state_->GetErrorState());
   2110   ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
   2111   glCopyTexImage2D(GL_TEXTURE_2D,
   2112                    0,  // level
   2113                    format,
   2114                    0, 0,
   2115                    size.width(),
   2116                    size.height(),
   2117                    0);  // border
   2118 }
   2119 
   2120 void BackTexture::Destroy() {
   2121   if (id_ != 0) {
   2122     ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
   2123                                        state_->GetErrorState());
   2124     glDeleteTextures(1, &id_);
   2125     id_ = 0;
   2126   }
   2127   memory_tracker_.TrackMemFree(bytes_allocated_);
   2128   bytes_allocated_ = 0;
   2129 }
   2130 
   2131 void BackTexture::Invalidate() {
   2132   id_ = 0;
   2133 }
   2134 
   2135 BackRenderbuffer::BackRenderbuffer(
   2136     RenderbufferManager* renderbuffer_manager,
   2137     MemoryTracker* memory_tracker,
   2138     ContextState* state)
   2139     : renderbuffer_manager_(renderbuffer_manager),
   2140       memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
   2141       state_(state),
   2142       bytes_allocated_(0),
   2143       id_(0) {
   2144 }
   2145 
   2146 BackRenderbuffer::~BackRenderbuffer() {
   2147   // This does not destroy the render buffer because that would require that
   2148   // the associated GL context was current. Just check that it was explicitly
   2149   // destroyed.
   2150   DCHECK_EQ(id_, 0u);
   2151 }
   2152 
   2153 void BackRenderbuffer::Create() {
   2154   ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
   2155                                      state_->GetErrorState());
   2156   Destroy();
   2157   glGenRenderbuffersEXT(1, &id_);
   2158 }
   2159 
   2160 bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
   2161                                        const gfx::Size& size,
   2162                                        GLenum format,
   2163                                        GLsizei samples) {
   2164   ScopedGLErrorSuppressor suppressor(
   2165       "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
   2166   ScopedRenderBufferBinder binder(state_, id_);
   2167 
   2168   uint32 estimated_size = 0;
   2169   if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
   2170            size.width(), size.height(), samples, format, &estimated_size)) {
   2171     return false;
   2172   }
   2173 
   2174   if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
   2175     return false;
   2176   }
   2177 
   2178   if (samples <= 1) {
   2179     glRenderbufferStorageEXT(GL_RENDERBUFFER,
   2180                              format,
   2181                              size.width(),
   2182                              size.height());
   2183   } else {
   2184     GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
   2185                                                            GL_RENDERBUFFER,
   2186                                                            samples,
   2187                                                            format,
   2188                                                            size.width(),
   2189                                                            size.height());
   2190   }
   2191   bool success = glGetError() == GL_NO_ERROR;
   2192   if (success) {
   2193     // Mark the previously allocated bytes as free.
   2194     memory_tracker_.TrackMemFree(bytes_allocated_);
   2195     bytes_allocated_ = estimated_size;
   2196     // Track the newly allocated bytes.
   2197     memory_tracker_.TrackMemAlloc(bytes_allocated_);
   2198   }
   2199   return success;
   2200 }
   2201 
   2202 void BackRenderbuffer::Destroy() {
   2203   if (id_ != 0) {
   2204     ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
   2205                                        state_->GetErrorState());
   2206     glDeleteRenderbuffersEXT(1, &id_);
   2207     id_ = 0;
   2208   }
   2209   memory_tracker_.TrackMemFree(bytes_allocated_);
   2210   bytes_allocated_ = 0;
   2211 }
   2212 
   2213 void BackRenderbuffer::Invalidate() {
   2214   id_ = 0;
   2215 }
   2216 
   2217 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
   2218     : decoder_(decoder),
   2219       id_(0) {
   2220 }
   2221 
   2222 BackFramebuffer::~BackFramebuffer() {
   2223   // This does not destroy the frame buffer because that would require that
   2224   // the associated GL context was current. Just check that it was explicitly
   2225   // destroyed.
   2226   DCHECK_EQ(id_, 0u);
   2227 }
   2228 
   2229 void BackFramebuffer::Create() {
   2230   ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
   2231                                      decoder_->GetErrorState());
   2232   Destroy();
   2233   glGenFramebuffersEXT(1, &id_);
   2234 }
   2235 
   2236 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
   2237   DCHECK_NE(id_, 0u);
   2238   ScopedGLErrorSuppressor suppressor(
   2239       "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
   2240   ScopedFrameBufferBinder binder(decoder_, id_);
   2241   GLuint attach_id = texture ? texture->id() : 0;
   2242   glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
   2243                             GL_COLOR_ATTACHMENT0,
   2244                             GL_TEXTURE_2D,
   2245                             attach_id,
   2246                             0);
   2247 }
   2248 
   2249 void BackFramebuffer::AttachRenderBuffer(GLenum target,
   2250                                          BackRenderbuffer* render_buffer) {
   2251   DCHECK_NE(id_, 0u);
   2252   ScopedGLErrorSuppressor suppressor(
   2253       "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
   2254   ScopedFrameBufferBinder binder(decoder_, id_);
   2255   GLuint attach_id = render_buffer ? render_buffer->id() : 0;
   2256   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
   2257                                target,
   2258                                GL_RENDERBUFFER,
   2259                                attach_id);
   2260 }
   2261 
   2262 void BackFramebuffer::Destroy() {
   2263   if (id_ != 0) {
   2264     ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
   2265                                        decoder_->GetErrorState());
   2266     glDeleteFramebuffersEXT(1, &id_);
   2267     id_ = 0;
   2268   }
   2269 }
   2270 
   2271 void BackFramebuffer::Invalidate() {
   2272   id_ = 0;
   2273 }
   2274 
   2275 GLenum BackFramebuffer::CheckStatus() {
   2276   DCHECK_NE(id_, 0u);
   2277   ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
   2278                                      decoder_->GetErrorState());
   2279   ScopedFrameBufferBinder binder(decoder_, id_);
   2280   return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
   2281 }
   2282 
   2283 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
   2284   return new GLES2DecoderImpl(group);
   2285 }
   2286 
   2287 GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
   2288     : GLES2Decoder(),
   2289       group_(group),
   2290       logger_(&debug_marker_manager_),
   2291       state_(group_->feature_info(), this, &logger_),
   2292       unpack_flip_y_(false),
   2293       unpack_premultiply_alpha_(false),
   2294       unpack_unpremultiply_alpha_(false),
   2295       attrib_0_buffer_id_(0),
   2296       attrib_0_buffer_matches_value_(true),
   2297       attrib_0_size_(0),
   2298       fixed_attrib_buffer_id_(0),
   2299       fixed_attrib_buffer_size_(0),
   2300       offscreen_target_color_format_(0),
   2301       offscreen_target_depth_format_(0),
   2302       offscreen_target_stencil_format_(0),
   2303       offscreen_target_samples_(0),
   2304       offscreen_target_buffer_preserved_(true),
   2305       offscreen_saved_color_format_(0),
   2306       back_buffer_color_format_(0),
   2307       back_buffer_has_depth_(false),
   2308       back_buffer_has_stencil_(false),
   2309       surfaceless_(false),
   2310       backbuffer_needs_clear_bits_(0),
   2311       current_decoder_error_(error::kNoError),
   2312       use_shader_translator_(true),
   2313       validators_(group_->feature_info()->validators()),
   2314       feature_info_(group_->feature_info()),
   2315       frame_number_(0),
   2316       has_robustness_extension_(false),
   2317       reset_status_(GL_NO_ERROR),
   2318       reset_by_robustness_extension_(false),
   2319       supports_post_sub_buffer_(false),
   2320       force_webgl_glsl_validation_(false),
   2321       derivatives_explicitly_enabled_(false),
   2322       frag_depth_explicitly_enabled_(false),
   2323       draw_buffers_explicitly_enabled_(false),
   2324       shader_texture_lod_explicitly_enabled_(false),
   2325       compile_shader_always_succeeds_(false),
   2326       lose_context_when_out_of_memory_(false),
   2327       service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
   2328           switches::kEnableGPUServiceLoggingGPU)),
   2329       viewport_max_width_(0),
   2330       viewport_max_height_(0),
   2331       texture_state_(group_->feature_info()
   2332                          ->workarounds()
   2333                          .texsubimage2d_faster_than_teximage2d),
   2334       cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
   2335           TRACE_DISABLED_BY_DEFAULT("cb_command"))),
   2336       gpu_trace_level_(2),
   2337       gpu_trace_commands_(false),
   2338       gpu_debug_commands_(false),
   2339       validation_texture_(0),
   2340       validation_fbo_multisample_(0),
   2341       validation_fbo_(0) {
   2342   DCHECK(group);
   2343 
   2344   attrib_0_value_.v[0] = 0.0f;
   2345   attrib_0_value_.v[1] = 0.0f;
   2346   attrib_0_value_.v[2] = 0.0f;
   2347   attrib_0_value_.v[3] = 1.0f;
   2348 
   2349   // The shader translator is used for WebGL even when running on EGL
   2350   // because additional restrictions are needed (like only enabling
   2351   // GL_OES_standard_derivatives on demand).  It is used for the unit
   2352   // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
   2353   // the empty string to CompileShader and this is not a valid shader.
   2354   if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
   2355       CommandLine::ForCurrentProcess()->HasSwitch(
   2356           switches::kDisableGLSLTranslator)) {
   2357     use_shader_translator_ = false;
   2358   }
   2359 }
   2360 
   2361 GLES2DecoderImpl::~GLES2DecoderImpl() {
   2362 }
   2363 
   2364 bool GLES2DecoderImpl::Initialize(
   2365     const scoped_refptr<gfx::GLSurface>& surface,
   2366     const scoped_refptr<gfx::GLContext>& context,
   2367     bool offscreen,
   2368     const gfx::Size& size,
   2369     const DisallowedFeatures& disallowed_features,
   2370     const std::vector<int32>& attribs) {
   2371   TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
   2372   DCHECK(context->IsCurrent(surface.get()));
   2373   DCHECK(!context_.get());
   2374 
   2375   surfaceless_ = surface->IsSurfaceless();
   2376 
   2377   set_initialized();
   2378   gpu_tracer_.reset(new GPUTracer(this));
   2379   gpu_state_tracer_ = GPUStateTracer::Create(&state_);
   2380 
   2381   if (CommandLine::ForCurrentProcess()->HasSwitch(
   2382       switches::kEnableGPUDebugging)) {
   2383     set_debug(true);
   2384   }
   2385 
   2386   if (CommandLine::ForCurrentProcess()->HasSwitch(
   2387       switches::kEnableGPUCommandLogging)) {
   2388     set_log_commands(true);
   2389   }
   2390 
   2391   compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
   2392       switches::kCompileShaderAlwaysSucceeds);
   2393 
   2394 
   2395   // Take ownership of the context and surface. The surface can be replaced with
   2396   // SetSurface.
   2397   context_ = context;
   2398   surface_ = surface;
   2399 
   2400   ContextCreationAttribHelper attrib_parser;
   2401   if (!attrib_parser.Parse(attribs))
   2402     return false;
   2403 
   2404   // Save the loseContextWhenOutOfMemory context creation attribute.
   2405   lose_context_when_out_of_memory_ =
   2406       attrib_parser.lose_context_when_out_of_memory;
   2407 
   2408   // If the failIfMajorPerformanceCaveat context creation attribute was true
   2409   // and we are using a software renderer, fail.
   2410   if (attrib_parser.fail_if_major_perf_caveat &&
   2411       feature_info_->feature_flags().is_swiftshader) {
   2412     group_ = NULL;  // Must not destroy ContextGroup if it is not initialized.
   2413     Destroy(true);
   2414     return false;
   2415   }
   2416 
   2417   if (!group_->Initialize(this, disallowed_features)) {
   2418     LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
   2419                << "failed to initialize.";
   2420     group_ = NULL;  // Must not destroy ContextGroup if it is not initialized.
   2421     Destroy(true);
   2422     return false;
   2423   }
   2424   CHECK_GL_ERROR();
   2425 
   2426   disallowed_features_ = disallowed_features;
   2427 
   2428   state_.attrib_values.resize(group_->max_vertex_attribs());
   2429   vertex_array_manager_.reset(new VertexArrayManager());
   2430 
   2431   GLuint default_vertex_attrib_service_id = 0;
   2432   if (features().native_vertex_array_object) {
   2433     glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
   2434     glBindVertexArrayOES(default_vertex_attrib_service_id);
   2435   }
   2436 
   2437   state_.default_vertex_attrib_manager =
   2438       CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
   2439 
   2440   state_.default_vertex_attrib_manager->Initialize(
   2441       group_->max_vertex_attribs(),
   2442       feature_info_->workarounds().init_vertex_attributes);
   2443 
   2444   // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
   2445   DoBindVertexArrayOES(0);
   2446 
   2447   query_manager_.reset(new QueryManager(this, feature_info_.get()));
   2448 
   2449   image_manager_.reset(new ImageManager);
   2450 
   2451   util_.set_num_compressed_texture_formats(
   2452       validators_->compressed_texture_format.GetValues().size());
   2453 
   2454   if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
   2455     // We have to enable vertex array 0 on OpenGL or it won't render. Note that
   2456     // OpenGL ES 2.0 does not have this issue.
   2457     glEnableVertexAttribArray(0);
   2458   }
   2459   glGenBuffersARB(1, &attrib_0_buffer_id_);
   2460   glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
   2461   glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
   2462   glBindBuffer(GL_ARRAY_BUFFER, 0);
   2463   glGenBuffersARB(1, &fixed_attrib_buffer_id_);
   2464 
   2465   state_.texture_units.resize(group_->max_texture_units());
   2466   for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
   2467     glActiveTexture(GL_TEXTURE0 + tt);
   2468     // We want the last bind to be 2D.
   2469     TextureRef* ref;
   2470     if (features().oes_egl_image_external) {
   2471       ref = texture_manager()->GetDefaultTextureInfo(
   2472           GL_TEXTURE_EXTERNAL_OES);
   2473       state_.texture_units[tt].bound_texture_external_oes = ref;
   2474       glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
   2475     }
   2476     if (features().arb_texture_rectangle) {
   2477       ref = texture_manager()->GetDefaultTextureInfo(
   2478           GL_TEXTURE_RECTANGLE_ARB);
   2479       state_.texture_units[tt].bound_texture_rectangle_arb = ref;
   2480       glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
   2481     }
   2482     ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
   2483     state_.texture_units[tt].bound_texture_cube_map = ref;
   2484     glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
   2485     ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
   2486     state_.texture_units[tt].bound_texture_2d = ref;
   2487     glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
   2488   }
   2489   glActiveTexture(GL_TEXTURE0);
   2490   CHECK_GL_ERROR();
   2491 
   2492   if (offscreen) {
   2493     if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
   2494         features().chromium_framebuffer_multisample) {
   2495       // Per ext_framebuffer_multisample spec, need max bound on sample count.
   2496       // max_sample_count must be initialized to a sane value.  If
   2497       // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
   2498       GLint max_sample_count = 1;
   2499       glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
   2500       offscreen_target_samples_ = std::min(attrib_parser.samples,
   2501                                            max_sample_count);
   2502     } else {
   2503       offscreen_target_samples_ = 1;
   2504     }
   2505     offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
   2506 
   2507     if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
   2508       const bool rgb8_supported =
   2509           context_->HasExtension("GL_OES_rgb8_rgba8");
   2510       // The only available default render buffer formats in GLES2 have very
   2511       // little precision.  Don't enable multisampling unless 8-bit render
   2512       // buffer formats are available--instead fall back to 8-bit textures.
   2513       if (rgb8_supported && offscreen_target_samples_ > 1) {
   2514         offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
   2515             GL_RGBA8 : GL_RGB8;
   2516       } else {
   2517         offscreen_target_samples_ = 1;
   2518         offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
   2519             GL_RGBA : GL_RGB;
   2520       }
   2521 
   2522       // ANGLE only supports packed depth/stencil formats, so use it if it is
   2523       // available.
   2524       const bool depth24_stencil8_supported =
   2525           feature_info_->feature_flags().packed_depth24_stencil8;
   2526       VLOG(1) << "GL_OES_packed_depth_stencil "
   2527               << (depth24_stencil8_supported ? "" : "not ") << "supported.";
   2528       if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
   2529           depth24_stencil8_supported) {
   2530         offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
   2531         offscreen_target_stencil_format_ = 0;
   2532       } else {
   2533         // It may be the case that this depth/stencil combination is not
   2534         // supported, but this will be checked later by CheckFramebufferStatus.
   2535         offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
   2536             GL_DEPTH_COMPONENT16 : 0;
   2537         offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
   2538             GL_STENCIL_INDEX8 : 0;
   2539       }
   2540     } else {
   2541       offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
   2542           GL_RGBA : GL_RGB;
   2543 
   2544       // If depth is requested at all, use the packed depth stencil format if
   2545       // it's available, as some desktop GL drivers don't support any non-packed
   2546       // formats for depth attachments.
   2547       const bool depth24_stencil8_supported =
   2548           feature_info_->feature_flags().packed_depth24_stencil8;
   2549       VLOG(1) << "GL_EXT_packed_depth_stencil "
   2550               << (depth24_stencil8_supported ? "" : "not ") << "supported.";
   2551 
   2552       if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
   2553           depth24_stencil8_supported) {
   2554         offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
   2555         offscreen_target_stencil_format_ = 0;
   2556       } else {
   2557         offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
   2558             GL_DEPTH_COMPONENT : 0;
   2559         offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
   2560             GL_STENCIL_INDEX : 0;
   2561       }
   2562     }
   2563 
   2564     offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
   2565         GL_RGBA : GL_RGB;
   2566 
   2567     // Create the target frame buffer. This is the one that the client renders
   2568     // directly to.
   2569     offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
   2570     offscreen_target_frame_buffer_->Create();
   2571     // Due to GLES2 format limitations, either the color texture (for
   2572     // non-multisampling) or the color render buffer (for multisampling) will be
   2573     // attached to the offscreen frame buffer.  The render buffer has more
   2574     // limited formats available to it, but the texture can't do multisampling.
   2575     if (IsOffscreenBufferMultisampled()) {
   2576       offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
   2577           renderbuffer_manager(), memory_tracker(), &state_));
   2578       offscreen_target_color_render_buffer_->Create();
   2579     } else {
   2580       offscreen_target_color_texture_.reset(new BackTexture(
   2581           memory_tracker(), &state_));
   2582       offscreen_target_color_texture_->Create();
   2583     }
   2584     offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
   2585         renderbuffer_manager(), memory_tracker(), &state_));
   2586     offscreen_target_depth_render_buffer_->Create();
   2587     offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
   2588         renderbuffer_manager(), memory_tracker(), &state_));
   2589     offscreen_target_stencil_render_buffer_->Create();
   2590 
   2591     // Create the saved offscreen texture. The target frame buffer is copied
   2592     // here when SwapBuffers is called.
   2593     offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
   2594     offscreen_saved_frame_buffer_->Create();
   2595     //
   2596     offscreen_saved_color_texture_.reset(new BackTexture(
   2597         memory_tracker(), &state_));
   2598     offscreen_saved_color_texture_->Create();
   2599 
   2600     // Allocate the render buffers at their initial size and check the status
   2601     // of the frame buffers is okay.
   2602     if (!ResizeOffscreenFrameBuffer(size)) {
   2603       LOG(ERROR) << "Could not allocate offscreen buffer storage.";
   2604       Destroy(true);
   2605       return false;
   2606     }
   2607 
   2608     // Allocate the offscreen saved color texture.
   2609     DCHECK(offscreen_saved_color_format_);
   2610     offscreen_saved_color_texture_->AllocateStorage(
   2611         gfx::Size(1, 1), offscreen_saved_color_format_, true);
   2612 
   2613     offscreen_saved_frame_buffer_->AttachRenderTexture(
   2614         offscreen_saved_color_texture_.get());
   2615     if (offscreen_saved_frame_buffer_->CheckStatus() !=
   2616         GL_FRAMEBUFFER_COMPLETE) {
   2617       LOG(ERROR) << "Offscreen saved FBO was incomplete.";
   2618       Destroy(true);
   2619       return false;
   2620     }
   2621 
   2622     // Bind to the new default frame buffer (the offscreen target frame buffer).
   2623     // This should now be associated with ID zero.
   2624     DoBindFramebuffer(GL_FRAMEBUFFER, 0);
   2625   } else {
   2626     glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
   2627     // These are NOT if the back buffer has these proprorties. They are
   2628     // if we want the command buffer to enforce them regardless of what
   2629     // the real backbuffer is assuming the real back buffer gives us more than
   2630     // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
   2631     // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
   2632     // can't do anything about that.
   2633 
   2634     if (!surfaceless_) {
   2635       GLint v = 0;
   2636       glGetIntegerv(GL_ALPHA_BITS, &v);
   2637       // This checks if the user requested RGBA and we have RGBA then RGBA. If
   2638       // the user requested RGB then RGB. If the user did not specify a
   2639       // preference than use whatever we were given. Same for DEPTH and STENCIL.
   2640       back_buffer_color_format_ =
   2641           (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
   2642       glGetIntegerv(GL_DEPTH_BITS, &v);
   2643       back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
   2644       glGetIntegerv(GL_STENCIL_BITS, &v);
   2645       back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
   2646     }
   2647   }
   2648 
   2649   // OpenGL ES 2.0 implicitly enables the desktop GL capability
   2650   // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
   2651   // isn't well documented; it was discovered in the Khronos OpenGL ES
   2652   // mailing list archives. It also implicitly enables the desktop GL
   2653   // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
   2654   // variable in fragment shaders.
   2655   if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
   2656     glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
   2657     glEnable(GL_POINT_SPRITE);
   2658   }
   2659 
   2660   has_robustness_extension_ =
   2661       context->HasExtension("GL_ARB_robustness") ||
   2662       context->HasExtension("GL_EXT_robustness");
   2663 
   2664   if (!InitializeShaderTranslator()) {
   2665     return false;
   2666   }
   2667 
   2668   state_.viewport_width = size.width();
   2669   state_.viewport_height = size.height();
   2670 
   2671   GLint viewport_params[4] = { 0 };
   2672   glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
   2673   viewport_max_width_ = viewport_params[0];
   2674   viewport_max_height_ = viewport_params[1];
   2675 
   2676   state_.scissor_width = state_.viewport_width;
   2677   state_.scissor_height = state_.viewport_height;
   2678 
   2679   // Set all the default state because some GL drivers get it wrong.
   2680   state_.InitCapabilities(NULL);
   2681   state_.InitState(NULL);
   2682   glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
   2683 
   2684   DoBindBuffer(GL_ARRAY_BUFFER, 0);
   2685   DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
   2686   DoBindFramebuffer(GL_FRAMEBUFFER, 0);
   2687   DoBindRenderbuffer(GL_RENDERBUFFER, 0);
   2688 
   2689   bool call_gl_clear = !surfaceless_;
   2690 #if defined(OS_ANDROID)
   2691   // Temporary workaround for Android WebView because this clear ignores the
   2692   // clip and corrupts that external UI of the App. Not calling glClear is ok
   2693   // because the system already clears the buffer before each draw. Proper
   2694   // fix might be setting the scissor clip properly before initialize. See
   2695   // crbug.com/259023 for details.
   2696   call_gl_clear = surface_->GetHandle();
   2697 #endif
   2698   if (call_gl_clear) {
   2699     // Clear the backbuffer.
   2700     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
   2701   }
   2702 
   2703   supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
   2704   if (feature_info_->workarounds()
   2705           .disable_post_sub_buffers_for_onscreen_surfaces &&
   2706       !surface->IsOffscreen())
   2707     supports_post_sub_buffer_ = false;
   2708 
   2709   if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
   2710     glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
   2711   }
   2712 
   2713   if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
   2714     context_->SetUnbindFboOnMakeCurrent();
   2715   }
   2716 
   2717   // Only compositor contexts are known to use only the subset of GL
   2718   // that can be safely migrated between the iGPU and the dGPU. Mark
   2719   // those contexts as safe to forcibly transition between the GPUs.
   2720   // http://crbug.com/180876, http://crbug.com/227228
   2721   if (!offscreen)
   2722     context_->SetSafeToForceGpuSwitch();
   2723 
   2724   async_pixel_transfer_manager_.reset(
   2725       AsyncPixelTransferManager::Create(context.get()));
   2726   async_pixel_transfer_manager_->Initialize(texture_manager());
   2727 
   2728   framebuffer_manager()->AddObserver(this);
   2729 
   2730   return true;
   2731 }
   2732 
   2733 Capabilities GLES2DecoderImpl::GetCapabilities() {
   2734   DCHECK(initialized());
   2735 
   2736   Capabilities caps;
   2737 
   2738   caps.egl_image_external =
   2739       feature_info_->feature_flags().oes_egl_image_external;
   2740   caps.texture_format_bgra8888 =
   2741       feature_info_->feature_flags().ext_texture_format_bgra8888;
   2742   caps.texture_format_etc1 =
   2743       feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
   2744   caps.texture_format_etc1_npot =
   2745       caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
   2746   caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
   2747   caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
   2748   caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
   2749   caps.discard_framebuffer =
   2750       feature_info_->feature_flags().ext_discard_framebuffer;
   2751   caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
   2752 
   2753 #if defined(OS_MACOSX)
   2754   // This is unconditionally true on mac, no need to test for it at runtime.
   2755   caps.iosurface = true;
   2756 #endif
   2757 
   2758   caps.post_sub_buffer = supports_post_sub_buffer_;
   2759   caps.map_image = true;
   2760 
   2761   return caps;
   2762 }
   2763 
   2764 void GLES2DecoderImpl::UpdateCapabilities() {
   2765   util_.set_num_compressed_texture_formats(
   2766       validators_->compressed_texture_format.GetValues().size());
   2767   util_.set_num_shader_binary_formats(
   2768       validators_->shader_binary_format.GetValues().size());
   2769 }
   2770 
   2771 bool GLES2DecoderImpl::InitializeShaderTranslator() {
   2772   TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
   2773 
   2774   if (!use_shader_translator_) {
   2775     return true;
   2776   }
   2777   ShBuiltInResources resources;
   2778   ShInitBuiltInResources(&resources);
   2779   resources.MaxVertexAttribs = group_->max_vertex_attribs();
   2780   resources.MaxVertexUniformVectors =
   2781       group_->max_vertex_uniform_vectors();
   2782   resources.MaxVaryingVectors = group_->max_varying_vectors();
   2783   resources.MaxVertexTextureImageUnits =
   2784       group_->max_vertex_texture_image_units();
   2785   resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
   2786   resources.MaxTextureImageUnits = group_->max_texture_image_units();
   2787   resources.MaxFragmentUniformVectors =
   2788       group_->max_fragment_uniform_vectors();
   2789   resources.MaxDrawBuffers = group_->max_draw_buffers();
   2790   resources.MaxExpressionComplexity = 256;
   2791   resources.MaxCallStackDepth = 256;
   2792 
   2793   GLint range[2] = { 0, 0 };
   2794   GLint precision = 0;
   2795   GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
   2796                                range, &precision);
   2797   resources.FragmentPrecisionHigh =
   2798       PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
   2799 
   2800   if (force_webgl_glsl_validation_) {
   2801     resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
   2802     resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
   2803     resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
   2804     if (!draw_buffers_explicitly_enabled_)
   2805       resources.MaxDrawBuffers = 1;
   2806     resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
   2807   } else {
   2808     resources.OES_standard_derivatives =
   2809         features().oes_standard_derivatives ? 1 : 0;
   2810     resources.ARB_texture_rectangle =
   2811         features().arb_texture_rectangle ? 1 : 0;
   2812     resources.OES_EGL_image_external =
   2813         features().oes_egl_image_external ? 1 : 0;
   2814     resources.EXT_draw_buffers =
   2815         features().ext_draw_buffers ? 1 : 0;
   2816     resources.EXT_frag_depth =
   2817         features().ext_frag_depth ? 1 : 0;
   2818     resources.EXT_shader_texture_lod =
   2819         features().ext_shader_texture_lod ? 1 : 0;
   2820   }
   2821 
   2822   ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
   2823                                                           : SH_GLES2_SPEC;
   2824   if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
   2825     resources.HashFunction = &CityHash64;
   2826   else
   2827     resources.HashFunction = NULL;
   2828   ShaderTranslatorInterface::GlslImplementationType implementation_type =
   2829       gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
   2830           ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
   2831   int driver_bug_workarounds = 0;
   2832   if (workarounds().needs_glsl_built_in_function_emulation)
   2833     driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
   2834   if (workarounds().init_gl_position_in_vertex_shader)
   2835     driver_bug_workarounds |= SH_INIT_GL_POSITION;
   2836   if (workarounds().unfold_short_circuit_as_ternary_operation)
   2837     driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
   2838   if (workarounds().init_varyings_without_static_use)
   2839     driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
   2840   if (workarounds().unroll_for_loop_with_sampler_array_index)
   2841     driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
   2842   if (workarounds().scalarize_vec_and_mat_constructor_args)
   2843     driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
   2844   if (workarounds().regenerate_struct_names)
   2845     driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
   2846 
   2847   vertex_translator_ = shader_translator_cache()->GetTranslator(
   2848       GL_VERTEX_SHADER,
   2849       shader_spec,
   2850       &resources,
   2851       implementation_type,
   2852       static_cast<ShCompileOptions>(driver_bug_workarounds));
   2853   if (!vertex_translator_.get()) {
   2854     LOG(ERROR) << "Could not initialize vertex shader translator.";
   2855     Destroy(true);
   2856     return false;
   2857   }
   2858 
   2859   fragment_translator_ = shader_translator_cache()->GetTranslator(
   2860       GL_FRAGMENT_SHADER,
   2861       shader_spec,
   2862       &resources,
   2863       implementation_type,
   2864       static_cast<ShCompileOptions>(driver_bug_workarounds));
   2865   if (!fragment_translator_.get()) {
   2866     LOG(ERROR) << "Could not initialize fragment shader translator.";
   2867     Destroy(true);
   2868     return false;
   2869   }
   2870   return true;
   2871 }
   2872 
   2873 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
   2874   for (GLsizei ii = 0; ii < n; ++ii) {
   2875     if (GetBuffer(client_ids[ii])) {
   2876       return false;
   2877     }
   2878   }
   2879   scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   2880   glGenBuffersARB(n, service_ids.get());
   2881   for (GLsizei ii = 0; ii < n; ++ii) {
   2882     CreateBuffer(client_ids[ii], service_ids[ii]);
   2883   }
   2884   return true;
   2885 }
   2886 
   2887 bool GLES2DecoderImpl::GenFramebuffersHelper(
   2888     GLsizei n, const GLuint* client_ids) {
   2889   for (GLsizei ii = 0; ii < n; ++ii) {
   2890     if (GetFramebuffer(client_ids[ii])) {
   2891       return false;
   2892     }
   2893   }
   2894   scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   2895   glGenFramebuffersEXT(n, service_ids.get());
   2896   for (GLsizei ii = 0; ii < n; ++ii) {
   2897     CreateFramebuffer(client_ids[ii], service_ids[ii]);
   2898   }
   2899   return true;
   2900 }
   2901 
   2902 bool GLES2DecoderImpl::GenRenderbuffersHelper(
   2903     GLsizei n, const GLuint* client_ids) {
   2904   for (GLsizei ii = 0; ii < n; ++ii) {
   2905     if (GetRenderbuffer(client_ids[ii])) {
   2906       return false;
   2907     }
   2908   }
   2909   scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   2910   glGenRenderbuffersEXT(n, service_ids.get());
   2911   for (GLsizei ii = 0; ii < n; ++ii) {
   2912     CreateRenderbuffer(client_ids[ii], service_ids[ii]);
   2913   }
   2914   return true;
   2915 }
   2916 
   2917 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
   2918   for (GLsizei ii = 0; ii < n; ++ii) {
   2919     if (GetTexture(client_ids[ii])) {
   2920       return false;
   2921     }
   2922   }
   2923   scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   2924   glGenTextures(n, service_ids.get());
   2925   for (GLsizei ii = 0; ii < n; ++ii) {
   2926     CreateTexture(client_ids[ii], service_ids[ii]);
   2927   }
   2928   return true;
   2929 }
   2930 
   2931 void GLES2DecoderImpl::DeleteBuffersHelper(
   2932     GLsizei n, const GLuint* client_ids) {
   2933   for (GLsizei ii = 0; ii < n; ++ii) {
   2934     Buffer* buffer = GetBuffer(client_ids[ii]);
   2935     if (buffer && !buffer->IsDeleted()) {
   2936       state_.vertex_attrib_manager->Unbind(buffer);
   2937       if (state_.bound_array_buffer.get() == buffer) {
   2938         state_.bound_array_buffer = NULL;
   2939       }
   2940       RemoveBuffer(client_ids[ii]);
   2941     }
   2942   }
   2943 }
   2944 
   2945 void GLES2DecoderImpl::DeleteFramebuffersHelper(
   2946     GLsizei n, const GLuint* client_ids) {
   2947   bool supports_separate_framebuffer_binds =
   2948      features().chromium_framebuffer_multisample;
   2949 
   2950   for (GLsizei ii = 0; ii < n; ++ii) {
   2951     Framebuffer* framebuffer =
   2952         GetFramebuffer(client_ids[ii]);
   2953     if (framebuffer && !framebuffer->IsDeleted()) {
   2954       if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
   2955         framebuffer_state_.bound_draw_framebuffer = NULL;
   2956         framebuffer_state_.clear_state_dirty = true;
   2957         GLenum target = supports_separate_framebuffer_binds ?
   2958             GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
   2959         glBindFramebufferEXT(target, GetBackbufferServiceId());
   2960       }
   2961       if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
   2962         framebuffer_state_.bound_read_framebuffer = NULL;
   2963         GLenum target = supports_separate_framebuffer_binds ?
   2964             GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
   2965         glBindFramebufferEXT(target, GetBackbufferServiceId());
   2966       }
   2967       OnFboChanged();
   2968       RemoveFramebuffer(client_ids[ii]);
   2969     }
   2970   }
   2971 }
   2972 
   2973 void GLES2DecoderImpl::DeleteRenderbuffersHelper(
   2974     GLsizei n, const GLuint* client_ids) {
   2975   bool supports_separate_framebuffer_binds =
   2976      features().chromium_framebuffer_multisample;
   2977   for (GLsizei ii = 0; ii < n; ++ii) {
   2978     Renderbuffer* renderbuffer =
   2979         GetRenderbuffer(client_ids[ii]);
   2980     if (renderbuffer && !renderbuffer->IsDeleted()) {
   2981       if (state_.bound_renderbuffer.get() == renderbuffer) {
   2982         state_.bound_renderbuffer = NULL;
   2983       }
   2984       // Unbind from current framebuffers.
   2985       if (supports_separate_framebuffer_binds) {
   2986         if (framebuffer_state_.bound_read_framebuffer.get()) {
   2987           framebuffer_state_.bound_read_framebuffer
   2988               ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
   2989         }
   2990         if (framebuffer_state_.bound_draw_framebuffer.get()) {
   2991           framebuffer_state_.bound_draw_framebuffer
   2992               ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
   2993         }
   2994       } else {
   2995         if (framebuffer_state_.bound_draw_framebuffer.get()) {
   2996           framebuffer_state_.bound_draw_framebuffer
   2997               ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
   2998         }
   2999       }
   3000       framebuffer_state_.clear_state_dirty = true;
   3001       RemoveRenderbuffer(client_ids[ii]);
   3002     }
   3003   }
   3004 }
   3005 
   3006 void GLES2DecoderImpl::DeleteTexturesHelper(
   3007     GLsizei n, const GLuint* client_ids) {
   3008   bool supports_separate_framebuffer_binds =
   3009      features().chromium_framebuffer_multisample;
   3010   for (GLsizei ii = 0; ii < n; ++ii) {
   3011     TextureRef* texture_ref = GetTexture(client_ids[ii]);
   3012     if (texture_ref) {
   3013       Texture* texture = texture_ref->texture();
   3014       if (texture->IsAttachedToFramebuffer()) {
   3015         framebuffer_state_.clear_state_dirty = true;
   3016       }
   3017       // Unbind texture_ref from texture_ref units.
   3018       for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
   3019         state_.texture_units[jj].Unbind(texture_ref);
   3020       }
   3021       // Unbind from current framebuffers.
   3022       if (supports_separate_framebuffer_binds) {
   3023         if (framebuffer_state_.bound_read_framebuffer.get()) {
   3024           framebuffer_state_.bound_read_framebuffer
   3025               ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
   3026         }
   3027         if (framebuffer_state_.bound_draw_framebuffer.get()) {
   3028           framebuffer_state_.bound_draw_framebuffer
   3029               ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
   3030         }
   3031       } else {
   3032         if (framebuffer_state_.bound_draw_framebuffer.get()) {
   3033           framebuffer_state_.bound_draw_framebuffer
   3034               ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
   3035         }
   3036       }
   3037 #if defined(OS_MACOSX)
   3038       GLuint service_id = texture->service_id();
   3039       if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
   3040         ReleaseIOSurfaceForTexture(service_id);
   3041       }
   3042 #endif
   3043       RemoveTexture(client_ids[ii]);
   3044     }
   3045   }
   3046 }
   3047 
   3048 // }  // anonymous namespace
   3049 
   3050 bool GLES2DecoderImpl::MakeCurrent() {
   3051   if (!context_.get())
   3052     return false;
   3053 
   3054   if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
   3055     LOG(ERROR) << "  GLES2DecoderImpl: Context lost during MakeCurrent.";
   3056 
   3057     // Some D3D drivers cannot recover from device lost in the GPU process
   3058     // sandbox. Allow a new GPU process to launch.
   3059     if (workarounds().exit_on_context_lost) {
   3060       LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
   3061                  << " a D3D device in the Chrome GPU process sandbox.";
   3062 #if defined(OS_WIN)
   3063       base::win::SetShouldCrashOnProcessDetach(false);
   3064 #endif
   3065       exit(0);
   3066     }
   3067 
   3068     return false;
   3069   }
   3070 
   3071   ProcessFinishedAsyncTransfers();
   3072 
   3073   // Rebind the FBO if it was unbound by the context.
   3074   if (workarounds().unbind_fbo_on_context_switch)
   3075     RestoreFramebufferBindings();
   3076 
   3077   framebuffer_state_.clear_state_dirty = true;
   3078 
   3079   return true;
   3080 }
   3081 
   3082 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
   3083   ProcessPendingReadPixels();
   3084   if (engine() && query_manager_.get())
   3085     query_manager_->ProcessPendingTransferQueries();
   3086 
   3087   // TODO(epenner): Is there a better place to do this?
   3088   // This needs to occur before we execute any batch of commands
   3089   // from the client, as the client may have recieved an async
   3090   // completion while issuing those commands.
   3091   // "DidFlushStart" would be ideal if we had such a callback.
   3092   async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
   3093 }
   3094 
   3095 static void RebindCurrentFramebuffer(
   3096     GLenum target,
   3097     Framebuffer* framebuffer,
   3098     GLuint back_buffer_service_id) {
   3099   GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
   3100 
   3101   if (framebuffer_id == 0) {
   3102     framebuffer_id = back_buffer_service_id;
   3103   }
   3104 
   3105   glBindFramebufferEXT(target, framebuffer_id);
   3106 }
   3107 
   3108 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
   3109   framebuffer_state_.clear_state_dirty = true;
   3110 
   3111   if (!features().chromium_framebuffer_multisample) {
   3112     RebindCurrentFramebuffer(
   3113         GL_FRAMEBUFFER,
   3114         framebuffer_state_.bound_draw_framebuffer.get(),
   3115         GetBackbufferServiceId());
   3116   } else {
   3117     RebindCurrentFramebuffer(
   3118         GL_READ_FRAMEBUFFER_EXT,
   3119         framebuffer_state_.bound_read_framebuffer.get(),
   3120         GetBackbufferServiceId());
   3121     RebindCurrentFramebuffer(
   3122         GL_DRAW_FRAMEBUFFER_EXT,
   3123         framebuffer_state_.bound_draw_framebuffer.get(),
   3124         GetBackbufferServiceId());
   3125   }
   3126   OnFboChanged();
   3127 }
   3128 
   3129 bool GLES2DecoderImpl::CheckFramebufferValid(
   3130     Framebuffer* framebuffer,
   3131     GLenum target, const char* func_name) {
   3132   if (!framebuffer) {
   3133     if (surfaceless_)
   3134       return false;
   3135     if (backbuffer_needs_clear_bits_) {
   3136       glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
   3137           offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
   3138       state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   3139       glClearStencil(0);
   3140       state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
   3141       state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
   3142       glClearDepth(1.0f);
   3143       state_.SetDeviceDepthMask(GL_TRUE);
   3144       state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   3145       bool reset_draw_buffer = false;
   3146       if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
   3147           group_->draw_buffer() == GL_NONE) {
   3148         reset_draw_buffer = true;
   3149         GLenum buf = GL_BACK;
   3150         if (GetBackbufferServiceId() != 0)  // emulated backbuffer
   3151           buf = GL_COLOR_ATTACHMENT0;
   3152         glDrawBuffersARB(1, &buf);
   3153       }
   3154       glClear(backbuffer_needs_clear_bits_);
   3155       if (reset_draw_buffer) {
   3156         GLenum buf = GL_NONE;
   3157         glDrawBuffersARB(1, &buf);
   3158       }
   3159       backbuffer_needs_clear_bits_ = 0;
   3160       RestoreClearState();
   3161     }
   3162     return true;
   3163   }
   3164 
   3165   if (framebuffer_manager()->IsComplete(framebuffer)) {
   3166     return true;
   3167   }
   3168 
   3169   GLenum completeness = framebuffer->IsPossiblyComplete();
   3170   if (completeness != GL_FRAMEBUFFER_COMPLETE) {
   3171     LOCAL_SET_GL_ERROR(
   3172         GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
   3173     return false;
   3174   }
   3175 
   3176   // Are all the attachments cleared?
   3177   if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
   3178       texture_manager()->HaveUnclearedMips()) {
   3179     if (!framebuffer->IsCleared()) {
   3180       // Can we clear them?
   3181       if (framebuffer->GetStatus(texture_manager(), target) !=
   3182           GL_FRAMEBUFFER_COMPLETE) {
   3183         LOCAL_SET_GL_ERROR(
   3184             GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
   3185             "framebuffer incomplete (clear)");
   3186         return false;
   3187       }
   3188       ClearUnclearedAttachments(target, framebuffer);
   3189     }
   3190   }
   3191 
   3192   if (!framebuffer_manager()->IsComplete(framebuffer)) {
   3193     if (framebuffer->GetStatus(texture_manager(), target) !=
   3194         GL_FRAMEBUFFER_COMPLETE) {
   3195       LOCAL_SET_GL_ERROR(
   3196           GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
   3197           "framebuffer incomplete (check)");
   3198       return false;
   3199     }
   3200     framebuffer_manager()->MarkAsComplete(framebuffer);
   3201   }
   3202 
   3203   // NOTE: At this point we don't know if the framebuffer is complete but
   3204   // we DO know that everything that needs to be cleared has been cleared.
   3205   return true;
   3206 }
   3207 
   3208 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
   3209   if (!features().chromium_framebuffer_multisample) {
   3210     bool valid = CheckFramebufferValid(
   3211         framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
   3212         func_name);
   3213 
   3214     if (valid)
   3215       OnUseFramebuffer();
   3216 
   3217     return valid;
   3218   }
   3219   return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
   3220                                GL_DRAW_FRAMEBUFFER_EXT,
   3221                                func_name) &&
   3222          CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
   3223                                GL_READ_FRAMEBUFFER_EXT,
   3224                                func_name);
   3225 }
   3226 
   3227 bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
   3228     const char* func_name) {
   3229   Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
   3230       framebuffer_state_.bound_read_framebuffer.get() :
   3231       framebuffer_state_.bound_draw_framebuffer.get();
   3232   if (!framebuffer)
   3233     return true;
   3234   if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
   3235     LOCAL_SET_GL_ERROR(
   3236         GL_INVALID_OPERATION, func_name, "no color image attached");
   3237     return false;
   3238   }
   3239   return true;
   3240 }
   3241 
   3242 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
   3243   Framebuffer* framebuffer =
   3244       GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
   3245   if (framebuffer != NULL) {
   3246     const Framebuffer::Attachment* attachment =
   3247         framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
   3248     if (attachment) {
   3249       return gfx::Size(attachment->width(), attachment->height());
   3250     }
   3251     return gfx::Size(0, 0);
   3252   } else if (offscreen_target_frame_buffer_.get()) {
   3253     return offscreen_size_;
   3254   } else {
   3255     return surface_->GetSize();
   3256   }
   3257 }
   3258 
   3259 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
   3260   Framebuffer* framebuffer =
   3261     GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
   3262   if (framebuffer != NULL) {
   3263     return framebuffer->GetColorAttachmentTextureType();
   3264   } else {
   3265     return GL_UNSIGNED_BYTE;
   3266   }
   3267 }
   3268 
   3269 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
   3270   Framebuffer* framebuffer =
   3271       GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
   3272   if (framebuffer != NULL) {
   3273     return framebuffer->GetColorAttachmentFormat();
   3274   } else if (offscreen_target_frame_buffer_.get()) {
   3275     return offscreen_target_color_format_;
   3276   } else {
   3277     return back_buffer_color_format_;
   3278   }
   3279 }
   3280 
   3281 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
   3282   Framebuffer* framebuffer =
   3283       GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   3284   if (framebuffer != NULL) {
   3285     return framebuffer->GetColorAttachmentFormat();
   3286   } else if (offscreen_target_frame_buffer_.get()) {
   3287     return offscreen_target_color_format_;
   3288   } else {
   3289     return back_buffer_color_format_;
   3290   }
   3291 }
   3292 
   3293 void GLES2DecoderImpl::UpdateParentTextureInfo() {
   3294   if (!offscreen_saved_color_texture_info_.get())
   3295     return;
   3296   GLenum target = offscreen_saved_color_texture_info_->texture()->target();
   3297   glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
   3298   texture_manager()->SetLevelInfo(
   3299       offscreen_saved_color_texture_info_.get(),
   3300       GL_TEXTURE_2D,
   3301       0,  // level
   3302       GL_RGBA,
   3303       offscreen_size_.width(),
   3304       offscreen_size_.height(),
   3305       1,  // depth
   3306       0,  // border
   3307       GL_RGBA,
   3308       GL_UNSIGNED_BYTE,
   3309       true);
   3310   texture_manager()->SetParameteri(
   3311       "UpdateParentTextureInfo",
   3312       GetErrorState(),
   3313       offscreen_saved_color_texture_info_.get(),
   3314       GL_TEXTURE_MAG_FILTER,
   3315       GL_LINEAR);
   3316   texture_manager()->SetParameteri(
   3317       "UpdateParentTextureInfo",
   3318       GetErrorState(),
   3319       offscreen_saved_color_texture_info_.get(),
   3320       GL_TEXTURE_MIN_FILTER,
   3321       GL_LINEAR);
   3322   texture_manager()->SetParameteri(
   3323       "UpdateParentTextureInfo",
   3324       GetErrorState(),
   3325       offscreen_saved_color_texture_info_.get(),
   3326       GL_TEXTURE_WRAP_S,
   3327       GL_CLAMP_TO_EDGE);
   3328   texture_manager()->SetParameteri(
   3329       "UpdateParentTextureInfo",
   3330       GetErrorState(),
   3331       offscreen_saved_color_texture_info_.get(),
   3332       GL_TEXTURE_WRAP_T,
   3333       GL_CLAMP_TO_EDGE);
   3334   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   3335       &state_, target);
   3336   glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
   3337 }
   3338 
   3339 void GLES2DecoderImpl::SetResizeCallback(
   3340     const base::Callback<void(gfx::Size, float)>& callback) {
   3341   resize_callback_ = callback;
   3342 }
   3343 
   3344 Logger* GLES2DecoderImpl::GetLogger() {
   3345   return &logger_;
   3346 }
   3347 
   3348 void GLES2DecoderImpl::BeginDecoding() {
   3349   gpu_tracer_->BeginDecoding();
   3350   gpu_trace_commands_ = gpu_tracer_->IsTracing();
   3351   gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
   3352                         (*cb_command_trace_category_ != 0);
   3353 }
   3354 
   3355 void GLES2DecoderImpl::EndDecoding() {
   3356   gpu_tracer_->EndDecoding();
   3357 }
   3358 
   3359 ErrorState* GLES2DecoderImpl::GetErrorState() {
   3360   return state_.GetErrorState();
   3361 }
   3362 
   3363 void GLES2DecoderImpl::SetShaderCacheCallback(
   3364     const ShaderCacheCallback& callback) {
   3365   shader_cache_callback_ = callback;
   3366 }
   3367 
   3368 void GLES2DecoderImpl::SetWaitSyncPointCallback(
   3369     const WaitSyncPointCallback& callback) {
   3370   wait_sync_point_callback_ = callback;
   3371 }
   3372 
   3373 AsyncPixelTransferManager*
   3374     GLES2DecoderImpl::GetAsyncPixelTransferManager() {
   3375   return async_pixel_transfer_manager_.get();
   3376 }
   3377 
   3378 void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
   3379   async_pixel_transfer_manager_.reset();
   3380 }
   3381 
   3382 void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
   3383     AsyncPixelTransferManager* manager) {
   3384   async_pixel_transfer_manager_ = make_scoped_ptr(manager);
   3385 }
   3386 
   3387 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
   3388                                            uint32* service_texture_id) {
   3389   TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
   3390   if (texture_ref) {
   3391     *service_texture_id = texture_ref->service_id();
   3392     return true;
   3393   }
   3394   return false;
   3395 }
   3396 
   3397 uint32 GLES2DecoderImpl::GetTextureUploadCount() {
   3398   return texture_state_.texture_upload_count +
   3399          async_pixel_transfer_manager_->GetTextureUploadCount();
   3400 }
   3401 
   3402 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
   3403   return texture_state_.total_texture_upload_time +
   3404          async_pixel_transfer_manager_->GetTotalTextureUploadTime();
   3405 }
   3406 
   3407 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
   3408   return total_processing_commands_time_;
   3409 }
   3410 
   3411 void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
   3412   total_processing_commands_time_ += time;
   3413 }
   3414 
   3415 void GLES2DecoderImpl::Destroy(bool have_context) {
   3416   if (!initialized())
   3417     return;
   3418 
   3419   DCHECK(!have_context || context_->IsCurrent(NULL));
   3420 
   3421   // Unbind everything.
   3422   state_.vertex_attrib_manager = NULL;
   3423   state_.default_vertex_attrib_manager = NULL;
   3424   state_.texture_units.clear();
   3425   state_.bound_array_buffer = NULL;
   3426   state_.current_queries.clear();
   3427   framebuffer_state_.bound_read_framebuffer = NULL;
   3428   framebuffer_state_.bound_draw_framebuffer = NULL;
   3429   state_.bound_renderbuffer = NULL;
   3430 
   3431   if (offscreen_saved_color_texture_info_.get()) {
   3432     DCHECK(offscreen_target_color_texture_);
   3433     DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
   3434               offscreen_saved_color_texture_->id());
   3435     offscreen_saved_color_texture_->Invalidate();
   3436     offscreen_saved_color_texture_info_ = NULL;
   3437   }
   3438   if (have_context) {
   3439     if (copy_texture_CHROMIUM_.get()) {
   3440       copy_texture_CHROMIUM_->Destroy();
   3441       copy_texture_CHROMIUM_.reset();
   3442     }
   3443 
   3444     if (state_.current_program.get()) {
   3445       program_manager()->UnuseProgram(shader_manager(),
   3446                                       state_.current_program.get());
   3447     }
   3448 
   3449     if (attrib_0_buffer_id_) {
   3450       glDeleteBuffersARB(1, &attrib_0_buffer_id_);
   3451     }
   3452     if (fixed_attrib_buffer_id_) {
   3453       glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
   3454     }
   3455 
   3456     if (validation_texture_) {
   3457       glDeleteTextures(1, &validation_texture_);
   3458       glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
   3459       glDeleteFramebuffersEXT(1, &validation_fbo_);
   3460     }
   3461 
   3462     if (offscreen_target_frame_buffer_.get())
   3463       offscreen_target_frame_buffer_->Destroy();
   3464     if (offscreen_target_color_texture_.get())
   3465       offscreen_target_color_texture_->Destroy();
   3466     if (offscreen_target_color_render_buffer_.get())
   3467       offscreen_target_color_render_buffer_->Destroy();
   3468     if (offscreen_target_depth_render_buffer_.get())
   3469       offscreen_target_depth_render_buffer_->Destroy();
   3470     if (offscreen_target_stencil_render_buffer_.get())
   3471       offscreen_target_stencil_render_buffer_->Destroy();
   3472     if (offscreen_saved_frame_buffer_.get())
   3473       offscreen_saved_frame_buffer_->Destroy();
   3474     if (offscreen_saved_color_texture_.get())
   3475       offscreen_saved_color_texture_->Destroy();
   3476     if (offscreen_resolved_frame_buffer_.get())
   3477       offscreen_resolved_frame_buffer_->Destroy();
   3478     if (offscreen_resolved_color_texture_.get())
   3479       offscreen_resolved_color_texture_->Destroy();
   3480   } else {
   3481     if (offscreen_target_frame_buffer_.get())
   3482       offscreen_target_frame_buffer_->Invalidate();
   3483     if (offscreen_target_color_texture_.get())
   3484       offscreen_target_color_texture_->Invalidate();
   3485     if (offscreen_target_color_render_buffer_.get())
   3486       offscreen_target_color_render_buffer_->Invalidate();
   3487     if (offscreen_target_depth_render_buffer_.get())
   3488       offscreen_target_depth_render_buffer_->Invalidate();
   3489     if (offscreen_target_stencil_render_buffer_.get())
   3490       offscreen_target_stencil_render_buffer_->Invalidate();
   3491     if (offscreen_saved_frame_buffer_.get())
   3492       offscreen_saved_frame_buffer_->Invalidate();
   3493     if (offscreen_saved_color_texture_.get())
   3494       offscreen_saved_color_texture_->Invalidate();
   3495     if (offscreen_resolved_frame_buffer_.get())
   3496       offscreen_resolved_frame_buffer_->Invalidate();
   3497     if (offscreen_resolved_color_texture_.get())
   3498       offscreen_resolved_color_texture_->Invalidate();
   3499   }
   3500 
   3501   // Current program must be cleared after calling ProgramManager::UnuseProgram.
   3502   // Otherwise, we can leak objects. http://crbug.com/258772.
   3503   // state_.current_program must be reset before group_ is reset because
   3504   // the later deletes the ProgramManager object that referred by
   3505   // state_.current_program object.
   3506   state_.current_program = NULL;
   3507 
   3508   copy_texture_CHROMIUM_.reset();
   3509 
   3510   if (query_manager_.get()) {
   3511     query_manager_->Destroy(have_context);
   3512     query_manager_.reset();
   3513   }
   3514 
   3515   if (vertex_array_manager_ .get()) {
   3516     vertex_array_manager_->Destroy(have_context);
   3517     vertex_array_manager_.reset();
   3518   }
   3519 
   3520   if (image_manager_.get()) {
   3521     image_manager_->Destroy(have_context);
   3522     image_manager_.reset();
   3523   }
   3524 
   3525   offscreen_target_frame_buffer_.reset();
   3526   offscreen_target_color_texture_.reset();
   3527   offscreen_target_color_render_buffer_.reset();
   3528   offscreen_target_depth_render_buffer_.reset();
   3529   offscreen_target_stencil_render_buffer_.reset();
   3530   offscreen_saved_frame_buffer_.reset();
   3531   offscreen_saved_color_texture_.reset();
   3532   offscreen_resolved_frame_buffer_.reset();
   3533   offscreen_resolved_color_texture_.reset();
   3534 
   3535   // Need to release these before releasing |group_| which may own the
   3536   // ShaderTranslatorCache.
   3537   fragment_translator_ = NULL;
   3538   vertex_translator_ = NULL;
   3539 
   3540   // Should destroy the transfer manager before the texture manager held
   3541   // by the context group.
   3542   async_pixel_transfer_manager_.reset();
   3543 
   3544   if (group_.get()) {
   3545     framebuffer_manager()->RemoveObserver(this);
   3546     group_->Destroy(this, have_context);
   3547     group_ = NULL;
   3548   }
   3549 
   3550   if (context_.get()) {
   3551     context_->ReleaseCurrent(NULL);
   3552     context_ = NULL;
   3553   }
   3554 
   3555 #if defined(OS_MACOSX)
   3556   for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
   3557        it != texture_to_io_surface_map_.end(); ++it) {
   3558     CFRelease(it->second);
   3559   }
   3560   texture_to_io_surface_map_.clear();
   3561 #endif
   3562 }
   3563 
   3564 void GLES2DecoderImpl::SetSurface(
   3565     const scoped_refptr<gfx::GLSurface>& surface) {
   3566   DCHECK(context_->IsCurrent(NULL));
   3567   DCHECK(surface_.get());
   3568   surface_ = surface;
   3569   RestoreCurrentFramebufferBindings();
   3570 }
   3571 
   3572 void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
   3573   if (!offscreen_saved_color_texture_.get()) {
   3574     LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
   3575     return;
   3576   }
   3577   if (!offscreen_saved_color_texture_info_.get()) {
   3578     GLuint service_id = offscreen_saved_color_texture_->id();
   3579     offscreen_saved_color_texture_info_ = TextureRef::Create(
   3580         texture_manager(), 0, service_id);
   3581     texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
   3582                                  GL_TEXTURE_2D);
   3583     UpdateParentTextureInfo();
   3584   }
   3585   mailbox_manager()->ProduceTexture(
   3586       GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
   3587 }
   3588 
   3589 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
   3590   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
   3591   if (!is_offscreen) {
   3592     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
   3593                << " with an onscreen framebuffer.";
   3594     return false;
   3595   }
   3596 
   3597   if (offscreen_size_ == size)
   3598     return true;
   3599 
   3600   offscreen_size_ = size;
   3601   int w = offscreen_size_.width();
   3602   int h = offscreen_size_.height();
   3603   if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
   3604     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3605                << "to allocate storage due to excessive dimensions.";
   3606     return false;
   3607   }
   3608 
   3609   // Reallocate the offscreen target buffers.
   3610   DCHECK(offscreen_target_color_format_);
   3611   if (IsOffscreenBufferMultisampled()) {
   3612     if (!offscreen_target_color_render_buffer_->AllocateStorage(
   3613             feature_info_.get(),
   3614             offscreen_size_,
   3615             offscreen_target_color_format_,
   3616             offscreen_target_samples_)) {
   3617       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3618                  << "to allocate storage for offscreen target color buffer.";
   3619       return false;
   3620     }
   3621   } else {
   3622     if (!offscreen_target_color_texture_->AllocateStorage(
   3623         offscreen_size_, offscreen_target_color_format_, false)) {
   3624       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3625                  << "to allocate storage for offscreen target color texture.";
   3626       return false;
   3627     }
   3628   }
   3629   if (offscreen_target_depth_format_ &&
   3630       !offscreen_target_depth_render_buffer_->AllocateStorage(
   3631           feature_info_.get(),
   3632           offscreen_size_,
   3633           offscreen_target_depth_format_,
   3634           offscreen_target_samples_)) {
   3635     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3636                << "to allocate storage for offscreen target depth buffer.";
   3637     return false;
   3638   }
   3639   if (offscreen_target_stencil_format_ &&
   3640       !offscreen_target_stencil_render_buffer_->AllocateStorage(
   3641           feature_info_.get(),
   3642           offscreen_size_,
   3643           offscreen_target_stencil_format_,
   3644           offscreen_target_samples_)) {
   3645     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3646                << "to allocate storage for offscreen target stencil buffer.";
   3647     return false;
   3648   }
   3649 
   3650   // Attach the offscreen target buffers to the target frame buffer.
   3651   if (IsOffscreenBufferMultisampled()) {
   3652     offscreen_target_frame_buffer_->AttachRenderBuffer(
   3653         GL_COLOR_ATTACHMENT0,
   3654         offscreen_target_color_render_buffer_.get());
   3655   } else {
   3656     offscreen_target_frame_buffer_->AttachRenderTexture(
   3657         offscreen_target_color_texture_.get());
   3658   }
   3659   if (offscreen_target_depth_format_) {
   3660     offscreen_target_frame_buffer_->AttachRenderBuffer(
   3661         GL_DEPTH_ATTACHMENT,
   3662         offscreen_target_depth_render_buffer_.get());
   3663   }
   3664   const bool packed_depth_stencil =
   3665       offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
   3666   if (packed_depth_stencil) {
   3667     offscreen_target_frame_buffer_->AttachRenderBuffer(
   3668         GL_STENCIL_ATTACHMENT,
   3669         offscreen_target_depth_render_buffer_.get());
   3670   } else if (offscreen_target_stencil_format_) {
   3671     offscreen_target_frame_buffer_->AttachRenderBuffer(
   3672         GL_STENCIL_ATTACHMENT,
   3673         offscreen_target_stencil_render_buffer_.get());
   3674   }
   3675 
   3676   if (offscreen_target_frame_buffer_->CheckStatus() !=
   3677       GL_FRAMEBUFFER_COMPLETE) {
   3678       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   3679                  << "because offscreen FBO was incomplete.";
   3680     return false;
   3681   }
   3682 
   3683   // Clear the target frame buffer.
   3684   {
   3685     ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
   3686     glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
   3687         offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
   3688     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   3689     glClearStencil(0);
   3690     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
   3691     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
   3692     glClearDepth(0);
   3693     state_.SetDeviceDepthMask(GL_TRUE);
   3694     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   3695     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
   3696     RestoreClearState();
   3697   }
   3698 
   3699   // Destroy the offscreen resolved framebuffers.
   3700   if (offscreen_resolved_frame_buffer_.get())
   3701     offscreen_resolved_frame_buffer_->Destroy();
   3702   if (offscreen_resolved_color_texture_.get())
   3703     offscreen_resolved_color_texture_->Destroy();
   3704   offscreen_resolved_color_texture_.reset();
   3705   offscreen_resolved_frame_buffer_.reset();
   3706 
   3707   return true;
   3708 }
   3709 
   3710 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
   3711                                                     const void* cmd_data) {
   3712   const gles2::cmds::ResizeCHROMIUM& c =
   3713       *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
   3714   if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
   3715     return error::kDeferCommandUntilLater;
   3716 
   3717   GLuint width = static_cast<GLuint>(c.width);
   3718   GLuint height = static_cast<GLuint>(c.height);
   3719   GLfloat scale_factor = c.scale_factor;
   3720   TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
   3721 
   3722   width = std::max(1U, width);
   3723   height = std::max(1U, height);
   3724 
   3725 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \
   3726     !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
   3727   // Make sure that we are done drawing to the back buffer before resizing.
   3728   glFinish();
   3729 #endif
   3730   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
   3731   if (is_offscreen) {
   3732     if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
   3733       LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
   3734                  << "ResizeOffscreenFrameBuffer failed.";
   3735       return error::kLostContext;
   3736     }
   3737   }
   3738 
   3739   if (!resize_callback_.is_null()) {
   3740     resize_callback_.Run(gfx::Size(width, height), scale_factor);
   3741     DCHECK(context_->IsCurrent(surface_.get()));
   3742     if (!context_->IsCurrent(surface_.get())) {
   3743       LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
   3744                  << "current after resize callback.";
   3745       return error::kLostContext;
   3746     }
   3747   }
   3748 
   3749   return error::kNoError;
   3750 }
   3751 
   3752 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
   3753   if (command_id > kStartPoint && command_id < kNumCommands) {
   3754     return gles2::GetCommandName(static_cast<CommandId>(command_id));
   3755   }
   3756   return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
   3757 }
   3758 
   3759 // Decode a command, and call the corresponding GL functions.
   3760 // NOTE: DoCommand() is slower than calling DoCommands() on larger batches
   3761 // of commands at once, and is now only used for tests that need to track
   3762 // individual commands.
   3763 error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
   3764                                          unsigned int arg_count,
   3765                                          const void* cmd_data) {
   3766   return DoCommands(1, cmd_data, arg_count + 1, 0);
   3767 }
   3768 
   3769 // Decode multiple commands, and call the corresponding GL functions.
   3770 // NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
   3771 // changed by a (malicious) client at any time, so if validation has to happen,
   3772 // it should operate on a copy of them.
   3773 // NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
   3774 // interest of performance in this critical execution loop.
   3775 template <bool DebugImpl>
   3776 error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
   3777                                               const void* buffer,
   3778                                               int num_entries,
   3779                                               int* entries_processed) {
   3780   commands_to_process_ = num_commands;
   3781   error::Error result = error::kNoError;
   3782   const CommandBufferEntry* cmd_data =
   3783       static_cast<const CommandBufferEntry*>(buffer);
   3784   int process_pos = 0;
   3785   unsigned int command = 0;
   3786 
   3787   while (process_pos < num_entries && result == error::kNoError &&
   3788          commands_to_process_--) {
   3789     const unsigned int size = cmd_data->value_header.size;
   3790     command = cmd_data->value_header.command;
   3791 
   3792     if (size == 0) {
   3793       result = error::kInvalidSize;
   3794       break;
   3795     }
   3796 
   3797     if (static_cast<int>(size) + process_pos > num_entries) {
   3798       result = error::kOutOfBounds;
   3799       break;
   3800     }
   3801 
   3802     if (DebugImpl) {
   3803       TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
   3804                          GetCommandName(command));
   3805 
   3806       if (log_commands()) {
   3807         LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
   3808                    << "cmd: " << GetCommandName(command);
   3809       }
   3810     }
   3811 
   3812     const unsigned int arg_count = size - 1;
   3813     unsigned int command_index = command - kStartPoint - 1;
   3814     if (command_index < arraysize(command_info)) {
   3815       const CommandInfo& info = command_info[command_index];
   3816       unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
   3817       if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
   3818           (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
   3819         bool doing_gpu_trace = false;
   3820         if (DebugImpl && gpu_trace_commands_) {
   3821           if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
   3822             doing_gpu_trace = true;
   3823             gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
   3824           }
   3825         }
   3826 
   3827         uint32 immediate_data_size = (arg_count - info_arg_count) *
   3828                                      sizeof(CommandBufferEntry);  // NOLINT
   3829 
   3830         result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
   3831 
   3832         if (DebugImpl && doing_gpu_trace)
   3833           gpu_tracer_->End(kTraceDecoder);
   3834 
   3835         if (DebugImpl && debug()) {
   3836           GLenum error;
   3837           while ((error = glGetError()) != GL_NO_ERROR) {
   3838             LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
   3839                        << "GL ERROR: " << GLES2Util::GetStringEnum(error)
   3840                        << " : " << GetCommandName(command);
   3841             LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
   3842           }
   3843         }
   3844       } else {
   3845         result = error::kInvalidArguments;
   3846       }
   3847     } else {
   3848       result = DoCommonCommand(command, arg_count, cmd_data);
   3849     }
   3850 
   3851     if (DebugImpl) {
   3852       TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
   3853                        GetCommandName(command));
   3854     }
   3855 
   3856     if (result == error::kNoError &&
   3857         current_decoder_error_ != error::kNoError) {
   3858       result = current_decoder_error_;
   3859       current_decoder_error_ = error::kNoError;
   3860     }
   3861 
   3862     if (result != error::kDeferCommandUntilLater) {
   3863       process_pos += size;
   3864       cmd_data += size;
   3865     }
   3866   }
   3867 
   3868   if (entries_processed)
   3869     *entries_processed = process_pos;
   3870 
   3871   if (error::IsError(result)) {
   3872     LOG(ERROR) << "Error: " << result << " for Command "
   3873                << GetCommandName(command);
   3874   }
   3875 
   3876   return result;
   3877 }
   3878 
   3879 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
   3880                                           const void* buffer,
   3881                                           int num_entries,
   3882                                           int* entries_processed) {
   3883   if (gpu_debug_commands_) {
   3884     return DoCommandsImpl<true>(
   3885         num_commands, buffer, num_entries, entries_processed);
   3886   } else {
   3887     return DoCommandsImpl<false>(
   3888         num_commands, buffer, num_entries, entries_processed);
   3889   }
   3890 }
   3891 
   3892 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
   3893   buffer_manager()->RemoveBuffer(client_id);
   3894 }
   3895 
   3896 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
   3897   if (GetProgram(client_id)) {
   3898     return false;
   3899   }
   3900   GLuint service_id = glCreateProgram();
   3901   if (service_id != 0) {
   3902     CreateProgram(client_id, service_id);
   3903   }
   3904   return true;
   3905 }
   3906 
   3907 bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
   3908   if (GetShader(client_id)) {
   3909     return false;
   3910   }
   3911   GLuint service_id = glCreateShader(type);
   3912   if (service_id != 0) {
   3913     CreateShader(client_id, service_id, type);
   3914   }
   3915   return true;
   3916 }
   3917 
   3918 void GLES2DecoderImpl::DoFinish() {
   3919   glFinish();
   3920   ProcessPendingReadPixels();
   3921   ProcessPendingQueries();
   3922 }
   3923 
   3924 void GLES2DecoderImpl::DoFlush() {
   3925   glFlush();
   3926   ProcessPendingQueries();
   3927 }
   3928 
   3929 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
   3930   GLuint texture_index = texture_unit - GL_TEXTURE0;
   3931   if (texture_index >= state_.texture_units.size()) {
   3932     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   3933         "glActiveTexture", texture_unit, "texture_unit");
   3934     return;
   3935   }
   3936   state_.active_texture_unit = texture_index;
   3937   glActiveTexture(texture_unit);
   3938 }
   3939 
   3940 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
   3941   Buffer* buffer = NULL;
   3942   GLuint service_id = 0;
   3943   if (client_id != 0) {
   3944     buffer = GetBuffer(client_id);
   3945     if (!buffer) {
   3946       if (!group_->bind_generates_resource()) {
   3947         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   3948                            "glBindBuffer",
   3949                            "id not generated by glGenBuffers");
   3950         return;
   3951       }
   3952 
   3953       // It's a new id so make a buffer buffer for it.
   3954       glGenBuffersARB(1, &service_id);
   3955       CreateBuffer(client_id, service_id);
   3956       buffer = GetBuffer(client_id);
   3957       IdAllocatorInterface* id_allocator =
   3958           group_->GetIdAllocator(id_namespaces::kBuffers);
   3959       id_allocator->MarkAsUsed(client_id);
   3960     }
   3961   }
   3962   LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
   3963   if (buffer) {
   3964     if (!buffer_manager()->SetTarget(buffer, target)) {
   3965       LOCAL_SET_GL_ERROR(
   3966           GL_INVALID_OPERATION,
   3967           "glBindBuffer", "buffer bound to more than 1 target");
   3968       return;
   3969     }
   3970     service_id = buffer->service_id();
   3971   }
   3972   switch (target) {
   3973     case GL_ARRAY_BUFFER:
   3974       state_.bound_array_buffer = buffer;
   3975       break;
   3976     case GL_ELEMENT_ARRAY_BUFFER:
   3977       state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
   3978       break;
   3979     default:
   3980       NOTREACHED();  // Validation should prevent us getting here.
   3981       break;
   3982   }
   3983   glBindBuffer(target, service_id);
   3984 }
   3985 
   3986 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
   3987     bool all_draw_buffers) {
   3988   Framebuffer* framebuffer =
   3989       GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   3990   if (!all_draw_buffers || !framebuffer) {
   3991     return (GLES2Util::GetChannelsForFormat(
   3992         GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
   3993   }
   3994   return framebuffer->HasAlphaMRT();
   3995 }
   3996 
   3997 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
   3998   Framebuffer* framebuffer =
   3999       GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   4000   if (framebuffer) {
   4001     return framebuffer->HasDepthAttachment();
   4002   }
   4003   if (offscreen_target_frame_buffer_.get()) {
   4004     return offscreen_target_depth_format_ != 0;
   4005   }
   4006   return back_buffer_has_depth_;
   4007 }
   4008 
   4009 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
   4010   Framebuffer* framebuffer =
   4011       GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   4012   if (framebuffer) {
   4013     return framebuffer->HasStencilAttachment();
   4014   }
   4015   if (offscreen_target_frame_buffer_.get()) {
   4016     return offscreen_target_stencil_format_ != 0 ||
   4017            offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
   4018   }
   4019   return back_buffer_has_stencil_;
   4020 }
   4021 
   4022 void GLES2DecoderImpl::ApplyDirtyState() {
   4023   if (framebuffer_state_.clear_state_dirty) {
   4024     bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
   4025     state_.SetDeviceColorMask(state_.color_mask_red,
   4026                               state_.color_mask_green,
   4027                               state_.color_mask_blue,
   4028                               state_.color_mask_alpha && have_alpha);
   4029 
   4030     bool have_depth = BoundFramebufferHasDepthAttachment();
   4031     state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
   4032 
   4033     bool have_stencil = BoundFramebufferHasStencilAttachment();
   4034     state_.SetDeviceStencilMaskSeparate(
   4035         GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
   4036     state_.SetDeviceStencilMaskSeparate(
   4037         GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
   4038 
   4039     state_.SetDeviceCapabilityState(
   4040         GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
   4041     state_.SetDeviceCapabilityState(
   4042         GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
   4043     framebuffer_state_.clear_state_dirty = false;
   4044   }
   4045 }
   4046 
   4047 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
   4048   return (offscreen_target_frame_buffer_.get())
   4049              ? offscreen_target_frame_buffer_->id()
   4050              : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
   4051 }
   4052 
   4053 void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
   4054   TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
   4055                "context", logger_.GetLogPrefix());
   4056   // Restore the Framebuffer first because of bugs in Intel drivers.
   4057   // Intel drivers incorrectly clip the viewport settings to
   4058   // the size of the current framebuffer object.
   4059   RestoreFramebufferBindings();
   4060   state_.RestoreState(prev_state);
   4061 }
   4062 
   4063 void GLES2DecoderImpl::RestoreFramebufferBindings() const {
   4064   GLuint service_id =
   4065       framebuffer_state_.bound_draw_framebuffer.get()
   4066           ? framebuffer_state_.bound_draw_framebuffer->service_id()
   4067           : GetBackbufferServiceId();
   4068   if (!features().chromium_framebuffer_multisample) {
   4069     glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
   4070   } else {
   4071     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
   4072     service_id = framebuffer_state_.bound_read_framebuffer.get()
   4073                      ? framebuffer_state_.bound_read_framebuffer->service_id()
   4074                      : GetBackbufferServiceId();
   4075     glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
   4076   }
   4077   OnFboChanged();
   4078 }
   4079 
   4080 void GLES2DecoderImpl::RestoreRenderbufferBindings() {
   4081   state_.RestoreRenderbufferBindings();
   4082 }
   4083 
   4084 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
   4085   Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
   4086   if (texture) {
   4087     GLenum target = texture->target();
   4088     glBindTexture(target, service_id);
   4089     glTexParameteri(
   4090         target, GL_TEXTURE_WRAP_S, texture->wrap_s());
   4091     glTexParameteri(
   4092         target, GL_TEXTURE_WRAP_T, texture->wrap_t());
   4093     glTexParameteri(
   4094         target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
   4095     glTexParameteri(
   4096         target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
   4097     RestoreTextureUnitBindings(state_.active_texture_unit);
   4098   }
   4099 }
   4100 
   4101 void GLES2DecoderImpl::ClearAllAttributes() const {
   4102   // Must use native VAO 0, as RestoreAllAttributes can't fully restore
   4103   // other VAOs.
   4104   if (feature_info_->feature_flags().native_vertex_array_object)
   4105     glBindVertexArrayOES(0);
   4106 
   4107   for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
   4108     if (i != 0) // Never disable attribute 0
   4109       glDisableVertexAttribArray(i);
   4110     if(features().angle_instanced_arrays)
   4111       glVertexAttribDivisorANGLE(i, 0);
   4112   }
   4113 }
   4114 
   4115 void GLES2DecoderImpl::RestoreAllAttributes() const {
   4116   state_.RestoreVertexAttribs();
   4117 }
   4118 
   4119 void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
   4120   state_.SetIgnoreCachedStateForTest(ignore);
   4121 }
   4122 
   4123 void GLES2DecoderImpl::OnFboChanged() const {
   4124   if (workarounds().restore_scissor_on_fbo_change)
   4125     state_.fbo_binding_for_scissor_workaround_dirty_ = true;
   4126 }
   4127 
   4128 // Called after the FBO is checked for completeness.
   4129 void GLES2DecoderImpl::OnUseFramebuffer() const {
   4130   if (state_.fbo_binding_for_scissor_workaround_dirty_) {
   4131     state_.fbo_binding_for_scissor_workaround_dirty_ = false;
   4132     // The driver forgets the correct scissor when modifying the FBO binding.
   4133     glScissor(state_.scissor_x,
   4134               state_.scissor_y,
   4135               state_.scissor_width,
   4136               state_.scissor_height);
   4137 
   4138     // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
   4139     // it's unclear how this bug works.
   4140     glFlush();
   4141   }
   4142 }
   4143 
   4144 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
   4145   Framebuffer* framebuffer = NULL;
   4146   GLuint service_id = 0;
   4147   if (client_id != 0) {
   4148     framebuffer = GetFramebuffer(client_id);
   4149     if (!framebuffer) {
   4150       if (!group_->bind_generates_resource()) {
   4151         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   4152                            "glBindFramebuffer",
   4153                            "id not generated by glGenFramebuffers");
   4154         return;
   4155       }
   4156 
   4157       // It's a new id so make a framebuffer framebuffer for it.
   4158       glGenFramebuffersEXT(1, &service_id);
   4159       CreateFramebuffer(client_id, service_id);
   4160       framebuffer = GetFramebuffer(client_id);
   4161       IdAllocatorInterface* id_allocator =
   4162           group_->GetIdAllocator(id_namespaces::kFramebuffers);
   4163       id_allocator->MarkAsUsed(client_id);
   4164     } else {
   4165       service_id = framebuffer->service_id();
   4166     }
   4167     framebuffer->MarkAsValid();
   4168   }
   4169   LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
   4170 
   4171   if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
   4172     framebuffer_state_.bound_draw_framebuffer = framebuffer;
   4173   }
   4174 
   4175   // vmiura: This looks like dup code
   4176   if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
   4177     framebuffer_state_.bound_read_framebuffer = framebuffer;
   4178   }
   4179 
   4180   framebuffer_state_.clear_state_dirty = true;
   4181 
   4182   // If we are rendering to the backbuffer get the FBO id for any simulated
   4183   // backbuffer.
   4184   if (framebuffer == NULL) {
   4185     service_id = GetBackbufferServiceId();
   4186   }
   4187 
   4188   glBindFramebufferEXT(target, service_id);
   4189   OnFboChanged();
   4190 }
   4191 
   4192 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
   4193   Renderbuffer* renderbuffer = NULL;
   4194   GLuint service_id = 0;
   4195   if (client_id != 0) {
   4196     renderbuffer = GetRenderbuffer(client_id);
   4197     if (!renderbuffer) {
   4198       if (!group_->bind_generates_resource()) {
   4199         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   4200                            "glBindRenderbuffer",
   4201                            "id not generated by glGenRenderbuffers");
   4202         return;
   4203       }
   4204 
   4205       // It's a new id so make a renderbuffer for it.
   4206       glGenRenderbuffersEXT(1, &service_id);
   4207       CreateRenderbuffer(client_id, service_id);
   4208       renderbuffer = GetRenderbuffer(client_id);
   4209       IdAllocatorInterface* id_allocator =
   4210           group_->GetIdAllocator(id_namespaces::kRenderbuffers);
   4211       id_allocator->MarkAsUsed(client_id);
   4212     } else {
   4213       service_id = renderbuffer->service_id();
   4214     }
   4215     renderbuffer->MarkAsValid();
   4216   }
   4217   LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
   4218   state_.bound_renderbuffer = renderbuffer;
   4219   state_.bound_renderbuffer_valid = true;
   4220   glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
   4221 }
   4222 
   4223 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
   4224   TextureRef* texture_ref = NULL;
   4225   GLuint service_id = 0;
   4226   if (client_id != 0) {
   4227     texture_ref = GetTexture(client_id);
   4228     if (!texture_ref) {
   4229       if (!group_->bind_generates_resource()) {
   4230         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   4231                            "glBindTexture",
   4232                            "id not generated by glGenTextures");
   4233         return;
   4234       }
   4235 
   4236       // It's a new id so make a texture texture for it.
   4237       glGenTextures(1, &service_id);
   4238       DCHECK_NE(0u, service_id);
   4239       CreateTexture(client_id, service_id);
   4240       texture_ref = GetTexture(client_id);
   4241       IdAllocatorInterface* id_allocator =
   4242           group_->GetIdAllocator(id_namespaces::kTextures);
   4243       id_allocator->MarkAsUsed(client_id);
   4244     }
   4245   } else {
   4246     texture_ref = texture_manager()->GetDefaultTextureInfo(target);
   4247   }
   4248 
   4249   // Check the texture exists
   4250   if (texture_ref) {
   4251     Texture* texture = texture_ref->texture();
   4252     // Check that we are not trying to bind it to a different target.
   4253     if (texture->target() != 0 && texture->target() != target) {
   4254       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   4255                          "glBindTexture",
   4256                          "texture bound to more than 1 target.");
   4257       return;
   4258     }
   4259     LogClientServiceForInfo(texture, client_id, "glBindTexture");
   4260     if (texture->target() == 0) {
   4261       texture_manager()->SetTarget(texture_ref, target);
   4262     }
   4263     glBindTexture(target, texture->service_id());
   4264   } else {
   4265     glBindTexture(target, 0);
   4266   }
   4267 
   4268   TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   4269   unit.bind_target = target;
   4270   switch (target) {
   4271     case GL_TEXTURE_2D:
   4272       unit.bound_texture_2d = texture_ref;
   4273       break;
   4274     case GL_TEXTURE_CUBE_MAP:
   4275       unit.bound_texture_cube_map = texture_ref;
   4276       break;
   4277     case GL_TEXTURE_EXTERNAL_OES:
   4278       unit.bound_texture_external_oes = texture_ref;
   4279       break;
   4280     case GL_TEXTURE_RECTANGLE_ARB:
   4281       unit.bound_texture_rectangle_arb = texture_ref;
   4282       break;
   4283     default:
   4284       NOTREACHED();  // Validation should prevent us getting here.
   4285       break;
   4286   }
   4287 }
   4288 
   4289 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
   4290   if (state_.vertex_attrib_manager->Enable(index, false)) {
   4291     if (index != 0 ||
   4292         gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
   4293       glDisableVertexAttribArray(index);
   4294     }
   4295   } else {
   4296     LOCAL_SET_GL_ERROR(
   4297         GL_INVALID_VALUE,
   4298         "glDisableVertexAttribArray", "index out of range");
   4299   }
   4300 }
   4301 
   4302 void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
   4303                                                GLsizei numAttachments,
   4304                                                const GLenum* attachments) {
   4305   Framebuffer* framebuffer =
   4306       GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
   4307 
   4308   // Validates the attachments. If one of them fails
   4309   // the whole command fails.
   4310   for (GLsizei i = 0; i < numAttachments; ++i) {
   4311     if ((framebuffer &&
   4312         !validators_->attachment.IsValid(attachments[i])) ||
   4313        (!framebuffer &&
   4314         !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
   4315       LOCAL_SET_GL_ERROR_INVALID_ENUM(
   4316           "glDiscardFramebufferEXT", attachments[i], "attachments");
   4317       return;
   4318     }
   4319   }
   4320 
   4321   // Marks each one of them as not cleared
   4322   for (GLsizei i = 0; i < numAttachments; ++i) {
   4323     if (framebuffer) {
   4324       framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
   4325                                            texture_manager(),
   4326                                            attachments[i],
   4327                                            false);
   4328     } else {
   4329       switch (attachments[i]) {
   4330         case GL_COLOR_EXT:
   4331           backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
   4332           break;
   4333         case GL_DEPTH_EXT:
   4334           backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
   4335         case GL_STENCIL_EXT:
   4336           backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
   4337           break;
   4338         default:
   4339           NOTREACHED();
   4340           break;
   4341       }
   4342     }
   4343   }
   4344 
   4345   // If the default framebuffer is bound but we are still rendering to an
   4346   // FBO, translate attachment names that refer to default framebuffer
   4347   // channels to corresponding framebuffer attachments.
   4348   scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
   4349   for (GLsizei i = 0; i < numAttachments; ++i) {
   4350     GLenum attachment = attachments[i];
   4351     if (!framebuffer && GetBackbufferServiceId()) {
   4352       switch (attachment) {
   4353         case GL_COLOR_EXT:
   4354           attachment = GL_COLOR_ATTACHMENT0;
   4355           break;
   4356         case GL_DEPTH_EXT:
   4357           attachment = GL_DEPTH_ATTACHMENT;
   4358           break;
   4359         case GL_STENCIL_EXT:
   4360           attachment = GL_STENCIL_ATTACHMENT;
   4361           break;
   4362         default:
   4363           NOTREACHED();
   4364           return;
   4365       }
   4366     }
   4367     translated_attachments[i] = attachment;
   4368   }
   4369 
   4370   ScopedRenderTo do_render(framebuffer);
   4371   glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
   4372 }
   4373 
   4374 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
   4375   if (state_.vertex_attrib_manager->Enable(index, true)) {
   4376     glEnableVertexAttribArray(index);
   4377   } else {
   4378     LOCAL_SET_GL_ERROR(
   4379         GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
   4380   }
   4381 }
   4382 
   4383 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
   4384   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   4385       &state_, target);
   4386   if (!texture_ref ||
   4387       !texture_manager()->CanGenerateMipmaps(texture_ref)) {
   4388     LOCAL_SET_GL_ERROR(
   4389         GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
   4390     return;
   4391   }
   4392 
   4393   if (target == GL_TEXTURE_CUBE_MAP) {
   4394     for (int i = 0; i < 6; ++i) {
   4395       GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
   4396       if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
   4397         LOCAL_SET_GL_ERROR(
   4398             GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
   4399         return;
   4400       }
   4401     }
   4402   } else {
   4403     if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
   4404       LOCAL_SET_GL_ERROR(
   4405           GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
   4406       return;
   4407     }
   4408   }
   4409 
   4410   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
   4411   // Workaround for Mac driver bug. In the large scheme of things setting
   4412   // glTexParamter twice for glGenerateMipmap is probably not a lage performance
   4413   // hit so there's probably no need to make this conditional. The bug appears
   4414   // to be that if the filtering mode is set to something that doesn't require
   4415   // mipmaps for rendering, or is never set to something other than the default,
   4416   // then glGenerateMipmap misbehaves.
   4417   if (workarounds().set_texture_filter_before_generating_mipmap) {
   4418     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   4419   }
   4420   glGenerateMipmapEXT(target);
   4421   if (workarounds().set_texture_filter_before_generating_mipmap) {
   4422     glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
   4423                     texture_ref->texture()->min_filter());
   4424   }
   4425   GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
   4426   if (error == GL_NO_ERROR) {
   4427     texture_manager()->MarkMipmapsGenerated(texture_ref);
   4428   }
   4429 }
   4430 
   4431 bool GLES2DecoderImpl::GetHelper(
   4432     GLenum pname, GLint* params, GLsizei* num_written) {
   4433   DCHECK(num_written);
   4434   if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
   4435     switch (pname) {
   4436       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   4437         *num_written = 1;
   4438         // Return the GL implementation's preferred format and (see below type)
   4439         // if we have the GL extension that exposes this. This allows the GPU
   4440         // client to use the implementation's preferred format for glReadPixels
   4441         // for optimisation.
   4442         //
   4443         // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
   4444         // case when requested on integer/floating point buffers but which is
   4445         // acceptable on GLES2 and with the GL_OES_read_format extension.
   4446         //
   4447         // Therefore if an error occurs we swallow the error and use the
   4448         // internal implementation.
   4449         if (params) {
   4450           if (context_->HasExtension("GL_OES_read_format")) {
   4451             ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
   4452                                                GetErrorState());
   4453             glGetIntegerv(pname, params);
   4454             if (glGetError() == GL_NO_ERROR)
   4455               return true;
   4456           }
   4457           *params = GLES2Util::GetPreferredGLReadPixelsFormat(
   4458               GetBoundReadFrameBufferInternalFormat());
   4459         }
   4460         return true;
   4461       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   4462         *num_written = 1;
   4463         if (params) {
   4464           if (context_->HasExtension("GL_OES_read_format")) {
   4465             ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
   4466                                                GetErrorState());
   4467             glGetIntegerv(pname, params);
   4468             if (glGetError() == GL_NO_ERROR)
   4469               return true;
   4470           }
   4471           *params = GLES2Util::GetPreferredGLReadPixelsType(
   4472               GetBoundReadFrameBufferInternalFormat(),
   4473               GetBoundReadFrameBufferTextureType());
   4474         }
   4475         return true;
   4476       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   4477         *num_written = 1;
   4478         if (params) {
   4479           *params = group_->max_fragment_uniform_vectors();
   4480         }
   4481         return true;
   4482       case GL_MAX_VARYING_VECTORS:
   4483         *num_written = 1;
   4484         if (params) {
   4485           *params = group_->max_varying_vectors();
   4486         }
   4487         return true;
   4488       case GL_MAX_VERTEX_UNIFORM_VECTORS:
   4489         *num_written = 1;
   4490         if (params) {
   4491           *params = group_->max_vertex_uniform_vectors();
   4492         }
   4493         return true;
   4494       }
   4495   }
   4496   switch (pname) {
   4497     case GL_MAX_VIEWPORT_DIMS:
   4498       if (offscreen_target_frame_buffer_.get()) {
   4499         *num_written = 2;
   4500         if (params) {
   4501           params[0] = renderbuffer_manager()->max_renderbuffer_size();
   4502           params[1] = renderbuffer_manager()->max_renderbuffer_size();
   4503         }
   4504         return true;
   4505       }
   4506       return false;
   4507     case GL_MAX_SAMPLES:
   4508       *num_written = 1;
   4509       if (params) {
   4510         params[0] = renderbuffer_manager()->max_samples();
   4511       }
   4512       return true;
   4513     case GL_MAX_RENDERBUFFER_SIZE:
   4514       *num_written = 1;
   4515       if (params) {
   4516         params[0] = renderbuffer_manager()->max_renderbuffer_size();
   4517       }
   4518       return true;
   4519     case GL_MAX_TEXTURE_SIZE:
   4520       *num_written = 1;
   4521       if (params) {
   4522         params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
   4523       }
   4524       return true;
   4525     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   4526       *num_written = 1;
   4527       if (params) {
   4528         params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
   4529       }
   4530       return true;
   4531     case GL_MAX_COLOR_ATTACHMENTS_EXT:
   4532       *num_written = 1;
   4533       if (params) {
   4534         params[0] = group_->max_color_attachments();
   4535       }
   4536       return true;
   4537     case GL_MAX_DRAW_BUFFERS_ARB:
   4538       *num_written = 1;
   4539       if (params) {
   4540         params[0] = group_->max_draw_buffers();
   4541       }
   4542       return true;
   4543     case GL_ALPHA_BITS:
   4544       *num_written = 1;
   4545       if (params) {
   4546         GLint v = 0;
   4547         glGetIntegerv(GL_ALPHA_BITS, &v);
   4548         params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
   4549       }
   4550       return true;
   4551     case GL_DEPTH_BITS:
   4552       *num_written = 1;
   4553       if (params) {
   4554         GLint v = 0;
   4555         glGetIntegerv(GL_DEPTH_BITS, &v);
   4556         params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
   4557       }
   4558       return true;
   4559     case GL_STENCIL_BITS:
   4560       *num_written = 1;
   4561       if (params) {
   4562         GLint v = 0;
   4563         glGetIntegerv(GL_STENCIL_BITS, &v);
   4564         params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
   4565       }
   4566       return true;
   4567     case GL_COMPRESSED_TEXTURE_FORMATS:
   4568       *num_written = validators_->compressed_texture_format.GetValues().size();
   4569       if (params) {
   4570         for (GLint ii = 0; ii < *num_written; ++ii) {
   4571           params[ii] = validators_->compressed_texture_format.GetValues()[ii];
   4572         }
   4573       }
   4574       return true;
   4575     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   4576       *num_written = 1;
   4577       if (params) {
   4578         *params = validators_->compressed_texture_format.GetValues().size();
   4579       }
   4580       return true;
   4581     case GL_NUM_SHADER_BINARY_FORMATS:
   4582       *num_written = 1;
   4583       if (params) {
   4584         *params = validators_->shader_binary_format.GetValues().size();
   4585       }
   4586       return true;
   4587     case GL_SHADER_BINARY_FORMATS:
   4588       *num_written = validators_->shader_binary_format.GetValues().size();
   4589       if (params) {
   4590         for (GLint ii = 0; ii <  *num_written; ++ii) {
   4591           params[ii] = validators_->shader_binary_format.GetValues()[ii];
   4592         }
   4593       }
   4594       return true;
   4595     case GL_SHADER_COMPILER:
   4596       *num_written = 1;
   4597       if (params) {
   4598         *params = GL_TRUE;
   4599       }
   4600       return true;
   4601     case GL_ARRAY_BUFFER_BINDING:
   4602       *num_written = 1;
   4603       if (params) {
   4604         if (state_.bound_array_buffer.get()) {
   4605           GLuint client_id = 0;
   4606           buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
   4607                                         &client_id);
   4608           *params = client_id;
   4609         } else {
   4610           *params = 0;
   4611         }
   4612       }
   4613       return true;
   4614     case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   4615       *num_written = 1;
   4616       if (params) {
   4617         if (state_.vertex_attrib_manager->element_array_buffer()) {
   4618           GLuint client_id = 0;
   4619           buffer_manager()->GetClientId(
   4620               state_.vertex_attrib_manager->element_array_buffer()->
   4621                   service_id(), &client_id);
   4622           *params = client_id;
   4623         } else {
   4624           *params = 0;
   4625         }
   4626       }
   4627       return true;
   4628     case GL_FRAMEBUFFER_BINDING:
   4629     // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
   4630       *num_written = 1;
   4631       if (params) {
   4632         Framebuffer* framebuffer =
   4633             GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
   4634         if (framebuffer) {
   4635           GLuint client_id = 0;
   4636           framebuffer_manager()->GetClientId(
   4637               framebuffer->service_id(), &client_id);
   4638           *params = client_id;
   4639         } else {
   4640           *params = 0;
   4641         }
   4642       }
   4643       return true;
   4644     case GL_READ_FRAMEBUFFER_BINDING_EXT:
   4645       *num_written = 1;
   4646       if (params) {
   4647         Framebuffer* framebuffer =
   4648             GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
   4649         if (framebuffer) {
   4650           GLuint client_id = 0;
   4651           framebuffer_manager()->GetClientId(
   4652               framebuffer->service_id(), &client_id);
   4653           *params = client_id;
   4654         } else {
   4655           *params = 0;
   4656         }
   4657       }
   4658       return true;
   4659     case GL_RENDERBUFFER_BINDING:
   4660       *num_written = 1;
   4661       if (params) {
   4662         Renderbuffer* renderbuffer =
   4663             GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
   4664         if (renderbuffer) {
   4665           *params = renderbuffer->client_id();
   4666         } else {
   4667           *params = 0;
   4668         }
   4669       }
   4670       return true;
   4671     case GL_CURRENT_PROGRAM:
   4672       *num_written = 1;
   4673       if (params) {
   4674         if (state_.current_program.get()) {
   4675           GLuint client_id = 0;
   4676           program_manager()->GetClientId(
   4677               state_.current_program->service_id(), &client_id);
   4678           *params = client_id;
   4679         } else {
   4680           *params = 0;
   4681         }
   4682       }
   4683       return true;
   4684     case GL_VERTEX_ARRAY_BINDING_OES:
   4685       *num_written = 1;
   4686       if (params) {
   4687         if (state_.vertex_attrib_manager.get() !=
   4688             state_.default_vertex_attrib_manager.get()) {
   4689           GLuint client_id = 0;
   4690           vertex_array_manager_->GetClientId(
   4691               state_.vertex_attrib_manager->service_id(), &client_id);
   4692           *params = client_id;
   4693         } else {
   4694           *params = 0;
   4695         }
   4696       }
   4697       return true;
   4698     case GL_TEXTURE_BINDING_2D:
   4699       *num_written = 1;
   4700       if (params) {
   4701         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   4702         if (unit.bound_texture_2d.get()) {
   4703           *params = unit.bound_texture_2d->client_id();
   4704         } else {
   4705           *params = 0;
   4706         }
   4707       }
   4708       return true;
   4709     case GL_TEXTURE_BINDING_CUBE_MAP:
   4710       *num_written = 1;
   4711       if (params) {
   4712         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   4713         if (unit.bound_texture_cube_map.get()) {
   4714           *params = unit.bound_texture_cube_map->client_id();
   4715         } else {
   4716           *params = 0;
   4717         }
   4718       }
   4719       return true;
   4720     case GL_TEXTURE_BINDING_EXTERNAL_OES:
   4721       *num_written = 1;
   4722       if (params) {
   4723         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   4724         if (unit.bound_texture_external_oes.get()) {
   4725           *params = unit.bound_texture_external_oes->client_id();
   4726         } else {
   4727           *params = 0;
   4728         }
   4729       }
   4730       return true;
   4731     case GL_TEXTURE_BINDING_RECTANGLE_ARB:
   4732       *num_written = 1;
   4733       if (params) {
   4734         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   4735         if (unit.bound_texture_rectangle_arb.get()) {
   4736           *params = unit.bound_texture_rectangle_arb->client_id();
   4737         } else {
   4738           *params = 0;
   4739         }
   4740       }
   4741       return true;
   4742     case GL_UNPACK_FLIP_Y_CHROMIUM:
   4743       *num_written = 1;
   4744       if (params) {
   4745         params[0] = unpack_flip_y_;
   4746       }
   4747       return true;
   4748     case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
   4749       *num_written = 1;
   4750       if (params) {
   4751         params[0] = unpack_premultiply_alpha_;
   4752       }
   4753       return true;
   4754     case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
   4755       *num_written = 1;
   4756       if (params) {
   4757         params[0] = unpack_unpremultiply_alpha_;
   4758       }
   4759       return true;
   4760     case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
   4761       *num_written = 1;
   4762       if (params) {
   4763         params[0] = group_->bind_generates_resource() ? 1 : 0;
   4764       }
   4765       return true;
   4766     default:
   4767       if (pname >= GL_DRAW_BUFFER0_ARB &&
   4768           pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
   4769         *num_written = 1;
   4770         if (params) {
   4771           Framebuffer* framebuffer =
   4772               GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
   4773           if (framebuffer) {
   4774             params[0] = framebuffer->GetDrawBuffer(pname);
   4775           } else {  // backbuffer
   4776             if (pname == GL_DRAW_BUFFER0_ARB)
   4777               params[0] = group_->draw_buffer();
   4778             else
   4779               params[0] = GL_NONE;
   4780           }
   4781         }
   4782         return true;
   4783       }
   4784       *num_written = util_.GLGetNumValuesReturned(pname);
   4785       return false;
   4786   }
   4787 }
   4788 
   4789 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
   4790     GLenum pname, GLsizei* num_values) {
   4791   if (state_.GetStateAsGLint(pname, NULL, num_values)) {
   4792     return true;
   4793   }
   4794   return GetHelper(pname, NULL, num_values);
   4795 }
   4796 
   4797 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
   4798   if (GL_MAX_SAMPLES == pname &&
   4799       features().use_img_for_multisampled_render_to_texture) {
   4800     return GL_MAX_SAMPLES_IMG;
   4801   }
   4802   return pname;
   4803 }
   4804 
   4805 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
   4806   DCHECK(params);
   4807   GLsizei num_written = 0;
   4808   if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
   4809     scoped_ptr<GLint[]> values(new GLint[num_written]);
   4810     if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
   4811       GetHelper(pname, values.get(), &num_written);
   4812     }
   4813     for (GLsizei ii = 0; ii < num_written; ++ii) {
   4814       params[ii] = static_cast<GLboolean>(values[ii]);
   4815     }
   4816   } else {
   4817     pname = AdjustGetPname(pname);
   4818     glGetBooleanv(pname, params);
   4819   }
   4820 }
   4821 
   4822 void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
   4823   DCHECK(params);
   4824   GLsizei num_written = 0;
   4825   if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
   4826     if (GetHelper(pname, NULL, &num_written)) {
   4827       scoped_ptr<GLint[]> values(new GLint[num_written]);
   4828       GetHelper(pname, values.get(), &num_written);
   4829       for (GLsizei ii = 0; ii < num_written; ++ii) {
   4830         params[ii] = static_cast<GLfloat>(values[ii]);
   4831       }
   4832     } else {
   4833       pname = AdjustGetPname(pname);
   4834       glGetFloatv(pname, params);
   4835     }
   4836   }
   4837 }
   4838 
   4839 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
   4840   DCHECK(params);
   4841   GLsizei num_written;
   4842   if (!state_.GetStateAsGLint(pname, params, &num_written) &&
   4843       !GetHelper(pname, params, &num_written)) {
   4844     pname = AdjustGetPname(pname);
   4845     glGetIntegerv(pname, params);
   4846   }
   4847 }
   4848 
   4849 void GLES2DecoderImpl::DoGetProgramiv(
   4850     GLuint program_id, GLenum pname, GLint* params) {
   4851   Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
   4852   if (!program) {
   4853     return;
   4854   }
   4855   program->GetProgramiv(pname, params);
   4856 }
   4857 
   4858 void GLES2DecoderImpl::DoGetBufferParameteriv(
   4859     GLenum target, GLenum pname, GLint* params) {
   4860   // Just delegate it. Some validation is actually done before this.
   4861   buffer_manager()->ValidateAndDoGetBufferParameteriv(
   4862       &state_, target, pname, params);
   4863 }
   4864 
   4865 void GLES2DecoderImpl::DoBindAttribLocation(
   4866     GLuint program_id, GLuint index, const char* name) {
   4867   if (!StringIsValidForGLES(name)) {
   4868     LOCAL_SET_GL_ERROR(
   4869         GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
   4870     return;
   4871   }
   4872   if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
   4873     LOCAL_SET_GL_ERROR(
   4874         GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
   4875     return;
   4876   }
   4877   if (index >= group_->max_vertex_attribs()) {
   4878     LOCAL_SET_GL_ERROR(
   4879         GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
   4880     return;
   4881   }
   4882   Program* program = GetProgramInfoNotShader(
   4883       program_id, "glBindAttribLocation");
   4884   if (!program) {
   4885     return;
   4886   }
   4887   program->SetAttribLocationBinding(name, static_cast<GLint>(index));
   4888   glBindAttribLocation(program->service_id(), index, name);
   4889 }
   4890 
   4891 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
   4892     uint32 immediate_data_size,
   4893     const void* cmd_data) {
   4894   const gles2::cmds::BindAttribLocationBucket& c =
   4895       *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
   4896   GLuint program = static_cast<GLuint>(c.program);
   4897   GLuint index = static_cast<GLuint>(c.index);
   4898   Bucket* bucket = GetBucket(c.name_bucket_id);
   4899   if (!bucket || bucket->size() == 0) {
   4900     return error::kInvalidArguments;
   4901   }
   4902   std::string name_str;
   4903   if (!bucket->GetAsString(&name_str)) {
   4904     return error::kInvalidArguments;
   4905   }
   4906   DoBindAttribLocation(program, index, name_str.c_str());
   4907   return error::kNoError;
   4908 }
   4909 
   4910 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
   4911     GLuint program_id, GLint location, const char* name) {
   4912   if (!StringIsValidForGLES(name)) {
   4913     LOCAL_SET_GL_ERROR(
   4914         GL_INVALID_VALUE,
   4915         "glBindUniformLocationCHROMIUM", "Invalid character");
   4916     return;
   4917   }
   4918   if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
   4919     LOCAL_SET_GL_ERROR(
   4920         GL_INVALID_OPERATION,
   4921         "glBindUniformLocationCHROMIUM", "reserved prefix");
   4922     return;
   4923   }
   4924   if (location < 0 || static_cast<uint32>(location) >=
   4925       (group_->max_fragment_uniform_vectors() +
   4926        group_->max_vertex_uniform_vectors()) * 4) {
   4927     LOCAL_SET_GL_ERROR(
   4928         GL_INVALID_VALUE,
   4929         "glBindUniformLocationCHROMIUM", "location out of range");
   4930     return;
   4931   }
   4932   Program* program = GetProgramInfoNotShader(
   4933       program_id, "glBindUniformLocationCHROMIUM");
   4934   if (!program) {
   4935     return;
   4936   }
   4937   if (!program->SetUniformLocationBinding(name, location)) {
   4938     LOCAL_SET_GL_ERROR(
   4939         GL_INVALID_VALUE,
   4940         "glBindUniformLocationCHROMIUM", "location out of range");
   4941   }
   4942 }
   4943 
   4944 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
   4945     uint32 immediate_data_size,
   4946     const void* cmd_data) {
   4947   const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
   4948       *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
   4949           cmd_data);
   4950   GLuint program = static_cast<GLuint>(c.program);
   4951   GLint location = static_cast<GLint>(c.location);
   4952   Bucket* bucket = GetBucket(c.name_bucket_id);
   4953   if (!bucket || bucket->size() == 0) {
   4954     return error::kInvalidArguments;
   4955   }
   4956   std::string name_str;
   4957   if (!bucket->GetAsString(&name_str)) {
   4958     return error::kInvalidArguments;
   4959   }
   4960   DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
   4961   return error::kNoError;
   4962 }
   4963 
   4964 error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
   4965                                                   const void* cmd_data) {
   4966   const gles2::cmds::DeleteShader& c =
   4967       *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
   4968   GLuint client_id = c.shader;
   4969   if (client_id) {
   4970     Shader* shader = GetShader(client_id);
   4971     if (shader) {
   4972       if (!shader->IsDeleted()) {
   4973         glDeleteShader(shader->service_id());
   4974         shader_manager()->MarkAsDeleted(shader);
   4975       }
   4976     } else {
   4977       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
   4978     }
   4979   }
   4980   return error::kNoError;
   4981 }
   4982 
   4983 error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
   4984                                                    const void* cmd_data) {
   4985   const gles2::cmds::DeleteProgram& c =
   4986       *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
   4987   GLuint client_id = c.program;
   4988   if (client_id) {
   4989     Program* program = GetProgram(client_id);
   4990     if (program) {
   4991       if (!program->IsDeleted()) {
   4992         program_manager()->MarkAsDeleted(shader_manager(), program);
   4993       }
   4994     } else {
   4995       LOCAL_SET_GL_ERROR(
   4996           GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
   4997     }
   4998   }
   4999   return error::kNoError;
   5000 }
   5001 
   5002 void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
   5003     GLuint namespace_id, GLsizei n, const GLuint* ids) {
   5004   IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
   5005   for (GLsizei ii = 0; ii < n; ++ii) {
   5006     id_allocator->FreeID(ids[ii]);
   5007   }
   5008 }
   5009 
   5010 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
   5011     uint32 immediate_data_size,
   5012     const void* cmd_data) {
   5013   const gles2::cmds::DeleteSharedIdsCHROMIUM& c =
   5014       *static_cast<const gles2::cmds::DeleteSharedIdsCHROMIUM*>(cmd_data);
   5015   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   5016   GLsizei n = static_cast<GLsizei>(c.n);
   5017   uint32 data_size;
   5018   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
   5019     return error::kOutOfBounds;
   5020   }
   5021   const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
   5022       c.ids_shm_id, c.ids_shm_offset, data_size);
   5023   if (n < 0) {
   5024     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
   5025     return error::kNoError;
   5026   }
   5027   if (ids == NULL) {
   5028     return error::kOutOfBounds;
   5029   }
   5030   DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
   5031   return error::kNoError;
   5032 }
   5033 
   5034 void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
   5035     GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
   5036   IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
   5037   if (id_offset == 0) {
   5038     for (GLsizei ii = 0; ii < n; ++ii) {
   5039       ids[ii] = id_allocator->AllocateID();
   5040     }
   5041   } else {
   5042     for (GLsizei ii = 0; ii < n; ++ii) {
   5043       ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
   5044       id_offset = ids[ii] + 1;
   5045     }
   5046   }
   5047 }
   5048 
   5049 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
   5050     uint32 immediate_data_size,
   5051     const void* cmd_data) {
   5052   const gles2::cmds::GenSharedIdsCHROMIUM& c =
   5053       *static_cast<const gles2::cmds::GenSharedIdsCHROMIUM*>(cmd_data);
   5054   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   5055   GLuint id_offset = static_cast<GLuint>(c.id_offset);
   5056   GLsizei n = static_cast<GLsizei>(c.n);
   5057   uint32 data_size;
   5058   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
   5059     return error::kOutOfBounds;
   5060   }
   5061   GLuint* ids = GetSharedMemoryAs<GLuint*>(
   5062       c.ids_shm_id, c.ids_shm_offset, data_size);
   5063   if (n < 0) {
   5064     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
   5065     return error::kNoError;
   5066   }
   5067   if (ids == NULL) {
   5068     return error::kOutOfBounds;
   5069   }
   5070   DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
   5071   return error::kNoError;
   5072 }
   5073 
   5074 void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
   5075     GLuint namespace_id, GLsizei n, const GLuint* ids) {
   5076   IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
   5077   for (GLsizei ii = 0; ii < n; ++ii) {
   5078     if (!id_allocator->MarkAsUsed(ids[ii])) {
   5079       for (GLsizei jj = 0; jj < ii; ++jj) {
   5080         id_allocator->FreeID(ids[jj]);
   5081       }
   5082       LOCAL_SET_GL_ERROR(
   5083           GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
   5084           "attempt to register id that already exists");
   5085       return;
   5086     }
   5087   }
   5088 }
   5089 
   5090 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
   5091     uint32 immediate_data_size,
   5092     const void* cmd_data) {
   5093   const gles2::cmds::RegisterSharedIdsCHROMIUM& c =
   5094       *static_cast<const gles2::cmds::RegisterSharedIdsCHROMIUM*>(cmd_data);
   5095   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   5096   GLsizei n = static_cast<GLsizei>(c.n);
   5097   uint32 data_size;
   5098   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
   5099     return error::kOutOfBounds;
   5100   }
   5101   GLuint* ids = GetSharedMemoryAs<GLuint*>(
   5102       c.ids_shm_id, c.ids_shm_offset, data_size);
   5103   if (n < 0) {
   5104     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
   5105     return error::kNoError;
   5106   }
   5107   if (ids == NULL) {
   5108     return error::kOutOfBounds;
   5109   }
   5110   DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
   5111   return error::kNoError;
   5112 }
   5113 
   5114 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
   5115   DCHECK(!ShouldDeferDraws());
   5116   if (CheckBoundFramebuffersValid("glClear")) {
   5117     ApplyDirtyState();
   5118     ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
   5119     glClear(mask);
   5120   }
   5121   return error::kNoError;
   5122 }
   5123 
   5124 void GLES2DecoderImpl::DoFramebufferRenderbuffer(
   5125     GLenum target, GLenum attachment, GLenum renderbuffertarget,
   5126     GLuint client_renderbuffer_id) {
   5127   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
   5128   if (!framebuffer) {
   5129     LOCAL_SET_GL_ERROR(
   5130         GL_INVALID_OPERATION,
   5131         "glFramebufferRenderbuffer", "no framebuffer bound");
   5132     return;
   5133   }
   5134   GLuint service_id = 0;
   5135   Renderbuffer* renderbuffer = NULL;
   5136   if (client_renderbuffer_id) {
   5137     renderbuffer = GetRenderbuffer(client_renderbuffer_id);
   5138     if (!renderbuffer) {
   5139       LOCAL_SET_GL_ERROR(
   5140           GL_INVALID_OPERATION,
   5141           "glFramebufferRenderbuffer", "unknown renderbuffer");
   5142       return;
   5143     }
   5144     service_id = renderbuffer->service_id();
   5145   }
   5146   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
   5147   glFramebufferRenderbufferEXT(
   5148       target, attachment, renderbuffertarget, service_id);
   5149   GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
   5150   if (error == GL_NO_ERROR) {
   5151     framebuffer->AttachRenderbuffer(attachment, renderbuffer);
   5152   }
   5153   if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
   5154     framebuffer_state_.clear_state_dirty = true;
   5155   }
   5156   OnFboChanged();
   5157 }
   5158 
   5159 void GLES2DecoderImpl::DoDisable(GLenum cap) {
   5160   if (SetCapabilityState(cap, false)) {
   5161     glDisable(cap);
   5162   }
   5163 }
   5164 
   5165 void GLES2DecoderImpl::DoEnable(GLenum cap) {
   5166   if (SetCapabilityState(cap, true)) {
   5167     glEnable(cap);
   5168   }
   5169 }
   5170 
   5171 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
   5172   state_.z_near = std::min(1.0f, std::max(0.0f, znear));
   5173   state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
   5174   glDepthRange(znear, zfar);
   5175 }
   5176 
   5177 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
   5178   state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
   5179   state_.sample_coverage_invert = (invert != 0);
   5180   glSampleCoverage(state_.sample_coverage_value, invert);
   5181 }
   5182 
   5183 // Assumes framebuffer is complete.
   5184 void GLES2DecoderImpl::ClearUnclearedAttachments(
   5185     GLenum target, Framebuffer* framebuffer) {
   5186   if (target == GL_READ_FRAMEBUFFER_EXT) {
   5187     // bind this to the DRAW point, clear then bind back to READ
   5188     // TODO(gman): I don't think there is any guarantee that an FBO that
   5189     //   is complete on the READ attachment will be complete as a DRAW
   5190     //   attachment.
   5191     glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
   5192     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
   5193   }
   5194   GLbitfield clear_bits = 0;
   5195   if (framebuffer->HasUnclearedColorAttachments()) {
   5196     glClearColor(
   5197         0.0f, 0.0f, 0.0f,
   5198         (GLES2Util::GetChannelsForFormat(
   5199              framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
   5200                                                                        1.0f);
   5201     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   5202     clear_bits |= GL_COLOR_BUFFER_BIT;
   5203     if (feature_info_->feature_flags().ext_draw_buffers)
   5204       framebuffer->PrepareDrawBuffersForClear();
   5205   }
   5206 
   5207   if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
   5208       framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
   5209     glClearStencil(0);
   5210     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
   5211     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
   5212     clear_bits |= GL_STENCIL_BUFFER_BIT;
   5213   }
   5214 
   5215   if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
   5216       framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
   5217     glClearDepth(1.0f);
   5218     state_.SetDeviceDepthMask(GL_TRUE);
   5219     clear_bits |= GL_DEPTH_BUFFER_BIT;
   5220   }
   5221 
   5222   state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   5223   glClear(clear_bits);
   5224 
   5225   if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
   5226       feature_info_->feature_flags().ext_draw_buffers)
   5227     framebuffer->RestoreDrawBuffersAfterClear();
   5228 
   5229   framebuffer_manager()->MarkAttachmentsAsCleared(
   5230       framebuffer, renderbuffer_manager(), texture_manager());
   5231 
   5232   RestoreClearState();
   5233 
   5234   if (target == GL_READ_FRAMEBUFFER_EXT) {
   5235     glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
   5236     Framebuffer* draw_framebuffer =
   5237         GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   5238     GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
   5239                                            GetBackbufferServiceId();
   5240     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
   5241   }
   5242 }
   5243 
   5244 void GLES2DecoderImpl::RestoreClearState() {
   5245   framebuffer_state_.clear_state_dirty = true;
   5246   glClearColor(
   5247       state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
   5248       state_.color_clear_alpha);
   5249   glClearStencil(state_.stencil_clear);
   5250   glClearDepth(state_.depth_clear);
   5251   if (state_.enable_flags.scissor_test) {
   5252     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
   5253   }
   5254 }
   5255 
   5256 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
   5257   Framebuffer* framebuffer =
   5258       GetFramebufferInfoForTarget(target);
   5259   if (!framebuffer) {
   5260     return GL_FRAMEBUFFER_COMPLETE;
   5261   }
   5262   GLenum completeness = framebuffer->IsPossiblyComplete();
   5263   if (completeness != GL_FRAMEBUFFER_COMPLETE) {
   5264     return completeness;
   5265   }
   5266   return framebuffer->GetStatus(texture_manager(), target);
   5267 }
   5268 
   5269 void GLES2DecoderImpl::DoFramebufferTexture2D(
   5270     GLenum target, GLenum attachment, GLenum textarget,
   5271     GLuint client_texture_id, GLint level) {
   5272   DoFramebufferTexture2DCommon(
   5273     "glFramebufferTexture2D", target, attachment,
   5274     textarget, client_texture_id, level, 0);
   5275 }
   5276 
   5277 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
   5278     GLenum target, GLenum attachment, GLenum textarget,
   5279     GLuint client_texture_id, GLint level, GLsizei samples) {
   5280   DoFramebufferTexture2DCommon(
   5281     "glFramebufferTexture2DMultisample", target, attachment,
   5282     textarget, client_texture_id, level, samples);
   5283 }
   5284 
   5285 void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
   5286     const char* name, GLenum target, GLenum attachment, GLenum textarget,
   5287     GLuint client_texture_id, GLint level, GLsizei samples) {
   5288   if (samples > renderbuffer_manager()->max_samples()) {
   5289     LOCAL_SET_GL_ERROR(
   5290         GL_INVALID_VALUE,
   5291         "glFramebufferTexture2DMultisample", "samples too large");
   5292     return;
   5293   }
   5294   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
   5295   if (!framebuffer) {
   5296     LOCAL_SET_GL_ERROR(
   5297         GL_INVALID_OPERATION,
   5298         name, "no framebuffer bound.");
   5299     return;
   5300   }
   5301   GLuint service_id = 0;
   5302   TextureRef* texture_ref = NULL;
   5303   if (client_texture_id) {
   5304     texture_ref = GetTexture(client_texture_id);
   5305     if (!texture_ref) {
   5306       LOCAL_SET_GL_ERROR(
   5307           GL_INVALID_OPERATION,
   5308           name, "unknown texture_ref");
   5309       return;
   5310     }
   5311     service_id = texture_ref->service_id();
   5312   }
   5313 
   5314   if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
   5315     LOCAL_SET_GL_ERROR(
   5316         GL_INVALID_VALUE,
   5317         name, "level out of range");
   5318     return;
   5319   }
   5320 
   5321   if (texture_ref)
   5322     DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
   5323 
   5324   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
   5325   if (0 == samples) {
   5326     glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
   5327   } else {
   5328     if (features().use_img_for_multisampled_render_to_texture) {
   5329       glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
   5330           service_id, level, samples);
   5331     } else {
   5332       glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
   5333           service_id, level, samples);
   5334     }
   5335   }
   5336   GLenum error = LOCAL_PEEK_GL_ERROR(name);
   5337   if (error == GL_NO_ERROR) {
   5338     framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
   5339          samples);
   5340   }
   5341   if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
   5342     framebuffer_state_.clear_state_dirty = true;
   5343   }
   5344 
   5345   if (texture_ref)
   5346     DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
   5347 
   5348   OnFboChanged();
   5349 }
   5350 
   5351 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
   5352     GLenum target, GLenum attachment, GLenum pname, GLint* params) {
   5353   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
   5354   if (!framebuffer) {
   5355     LOCAL_SET_GL_ERROR(
   5356         GL_INVALID_OPERATION,
   5357         "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
   5358     return;
   5359   }
   5360   if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
   5361     const Framebuffer::Attachment* attachment_object =
   5362         framebuffer->GetAttachment(attachment);
   5363     *params = attachment_object ? attachment_object->object_name() : 0;
   5364   } else {
   5365     if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
   5366         features().use_img_for_multisampled_render_to_texture) {
   5367       pname = GL_TEXTURE_SAMPLES_IMG;
   5368     }
   5369     glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
   5370   }
   5371 }
   5372 
   5373 void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
   5374     GLenum target, GLenum pname, GLint* params) {
   5375   Renderbuffer* renderbuffer =
   5376       GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
   5377   if (!renderbuffer) {
   5378     LOCAL_SET_GL_ERROR(
   5379         GL_INVALID_OPERATION,
   5380         "glGetRenderbufferParameteriv", "no renderbuffer bound");
   5381     return;
   5382   }
   5383 
   5384   EnsureRenderbufferBound();
   5385   switch (pname) {
   5386     case GL_RENDERBUFFER_INTERNAL_FORMAT:
   5387       *params = renderbuffer->internal_format();
   5388       break;
   5389     case GL_RENDERBUFFER_WIDTH:
   5390       *params = renderbuffer->width();
   5391       break;
   5392     case GL_RENDERBUFFER_HEIGHT:
   5393       *params = renderbuffer->height();
   5394       break;
   5395     case GL_RENDERBUFFER_SAMPLES_EXT:
   5396       if (features().use_img_for_multisampled_render_to_texture) {
   5397         glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
   5398             params);
   5399       } else {
   5400         glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
   5401             params);
   5402       }
   5403     default:
   5404       glGetRenderbufferParameterivEXT(target, pname, params);
   5405       break;
   5406   }
   5407 }
   5408 
   5409 void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
   5410     GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   5411     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   5412     GLbitfield mask, GLenum filter) {
   5413   DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
   5414 
   5415   if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
   5416     return;
   5417   }
   5418 
   5419   state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   5420   ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
   5421   BlitFramebufferHelper(
   5422       srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   5423   state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
   5424                                   state_.enable_flags.scissor_test);
   5425 }
   5426 
   5427 void GLES2DecoderImpl::EnsureRenderbufferBound() {
   5428   if (!state_.bound_renderbuffer_valid) {
   5429     state_.bound_renderbuffer_valid = true;
   5430     glBindRenderbufferEXT(GL_RENDERBUFFER,
   5431                           state_.bound_renderbuffer.get()
   5432                               ? state_.bound_renderbuffer->service_id()
   5433                               : 0);
   5434   }
   5435 }
   5436 
   5437 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
   5438     const FeatureInfo* feature_info,
   5439     GLenum target,
   5440     GLsizei samples,
   5441     GLenum internal_format,
   5442     GLsizei width,
   5443     GLsizei height) {
   5444   // TODO(sievers): This could be resolved at the GL binding level, but the
   5445   // binding process is currently a bit too 'brute force'.
   5446   if (feature_info->feature_flags().is_angle) {
   5447     glRenderbufferStorageMultisampleANGLE(
   5448         target, samples, internal_format, width, height);
   5449   } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
   5450     glRenderbufferStorageMultisample(
   5451         target, samples, internal_format, width, height);
   5452   } else {
   5453     glRenderbufferStorageMultisampleEXT(
   5454         target, samples, internal_format, width, height);
   5455   }
   5456 }
   5457 
   5458 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
   5459                                              GLint srcY0,
   5460                                              GLint srcX1,
   5461                                              GLint srcY1,
   5462                                              GLint dstX0,
   5463                                              GLint dstY0,
   5464                                              GLint dstX1,
   5465                                              GLint dstY1,
   5466                                              GLbitfield mask,
   5467                                              GLenum filter) {
   5468   // TODO(sievers): This could be resolved at the GL binding level, but the
   5469   // binding process is currently a bit too 'brute force'.
   5470   if (feature_info_->feature_flags().is_angle) {
   5471     glBlitFramebufferANGLE(
   5472         srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   5473   } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
   5474     glBlitFramebuffer(
   5475         srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   5476   } else {
   5477     glBlitFramebufferEXT(
   5478         srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   5479   }
   5480 }
   5481 
   5482 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
   5483     GLsizei samples,
   5484     GLenum internalformat,
   5485     GLsizei width,
   5486     GLsizei height) {
   5487   if (samples > renderbuffer_manager()->max_samples()) {
   5488     LOCAL_SET_GL_ERROR(
   5489         GL_INVALID_VALUE,
   5490         "glRenderbufferStorageMultisample", "samples too large");
   5491     return false;
   5492   }
   5493 
   5494   if (width > renderbuffer_manager()->max_renderbuffer_size() ||
   5495       height > renderbuffer_manager()->max_renderbuffer_size()) {
   5496     LOCAL_SET_GL_ERROR(
   5497         GL_INVALID_VALUE,
   5498         "glRenderbufferStorageMultisample", "dimensions too large");
   5499     return false;
   5500   }
   5501 
   5502   uint32 estimated_size = 0;
   5503   if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
   5504            width, height, samples, internalformat, &estimated_size)) {
   5505     LOCAL_SET_GL_ERROR(
   5506         GL_OUT_OF_MEMORY,
   5507         "glRenderbufferStorageMultisample", "dimensions too large");
   5508     return false;
   5509   }
   5510 
   5511   if (!EnsureGPUMemoryAvailable(estimated_size)) {
   5512     LOCAL_SET_GL_ERROR(
   5513         GL_OUT_OF_MEMORY,
   5514         "glRenderbufferStorageMultisample", "out of memory");
   5515     return false;
   5516   }
   5517 
   5518   return true;
   5519 }
   5520 
   5521 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
   5522     GLenum target, GLsizei samples, GLenum internalformat,
   5523     GLsizei width, GLsizei height) {
   5524   Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
   5525   if (!renderbuffer) {
   5526     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   5527                        "glRenderbufferStorageMultisampleCHROMIUM",
   5528                        "no renderbuffer bound");
   5529     return;
   5530   }
   5531 
   5532   if (!ValidateRenderbufferStorageMultisample(
   5533       samples, internalformat, width, height)) {
   5534     return;
   5535   }
   5536 
   5537   EnsureRenderbufferBound();
   5538   GLenum impl_format =
   5539       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
   5540           internalformat);
   5541   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
   5542       "glRenderbufferStorageMultisampleCHROMIUM");
   5543   RenderbufferStorageMultisampleHelper(
   5544       feature_info_.get(), target, samples, impl_format, width, height);
   5545   GLenum error =
   5546       LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
   5547   if (error == GL_NO_ERROR) {
   5548 
   5549     if (workarounds().validate_multisample_buffer_allocation) {
   5550       if (!VerifyMultisampleRenderbufferIntegrity(
   5551           renderbuffer->service_id(), impl_format)) {
   5552         LOCAL_SET_GL_ERROR(
   5553             GL_OUT_OF_MEMORY,
   5554             "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
   5555         return;
   5556       }
   5557     }
   5558 
   5559     // TODO(gman): If renderbuffers tracked which framebuffers they were
   5560     // attached to we could just mark those framebuffers as not complete.
   5561     framebuffer_manager()->IncFramebufferStateChangeCount();
   5562     renderbuffer_manager()->SetInfo(
   5563         renderbuffer, samples, internalformat, width, height);
   5564   }
   5565 }
   5566 
   5567 // This is the handler for multisampled_render_to_texture extensions.
   5568 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
   5569     GLenum target, GLsizei samples, GLenum internalformat,
   5570     GLsizei width, GLsizei height) {
   5571   Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
   5572   if (!renderbuffer) {
   5573     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   5574                        "glRenderbufferStorageMultisampleEXT",
   5575                        "no renderbuffer bound");
   5576     return;
   5577   }
   5578 
   5579   if (!ValidateRenderbufferStorageMultisample(
   5580       samples, internalformat, width, height)) {
   5581     return;
   5582   }
   5583 
   5584   EnsureRenderbufferBound();
   5585   GLenum impl_format =
   5586       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
   5587           internalformat);
   5588   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
   5589   if (features().use_img_for_multisampled_render_to_texture) {
   5590     glRenderbufferStorageMultisampleIMG(
   5591         target, samples, impl_format, width, height);
   5592   } else {
   5593     glRenderbufferStorageMultisampleEXT(
   5594         target, samples, impl_format, width, height);
   5595   }
   5596   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
   5597   if (error == GL_NO_ERROR) {
   5598     // TODO(gman): If renderbuffers tracked which framebuffers they were
   5599     // attached to we could just mark those framebuffers as not complete.
   5600     framebuffer_manager()->IncFramebufferStateChangeCount();
   5601     renderbuffer_manager()->SetInfo(
   5602         renderbuffer, samples, internalformat, width, height);
   5603   }
   5604 }
   5605 
   5606 // This function validates the allocation of a multisampled renderbuffer
   5607 // by clearing it to a key color, blitting the contents to a texture, and
   5608 // reading back the color to ensure it matches the key.
   5609 bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
   5610     GLuint renderbuffer, GLenum format) {
   5611 
   5612   // Only validate color buffers.
   5613   // These formats have been selected because they are very common or are known
   5614   // to be used by the WebGL backbuffer. If problems are observed with other
   5615   // color formats they can be added here.
   5616   switch(format) {
   5617     case GL_RGB:
   5618     case GL_RGB8:
   5619     case GL_RGBA:
   5620     case GL_RGBA8:
   5621       break;
   5622     default:
   5623       return true;
   5624   }
   5625 
   5626   GLint draw_framebuffer, read_framebuffer;
   5627 
   5628   // Cache framebuffer and texture bindings.
   5629   glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
   5630   glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
   5631 
   5632   if (!validation_texture_) {
   5633     GLint bound_texture;
   5634     glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
   5635 
   5636     // Create additional resources needed for the verification.
   5637     glGenTextures(1, &validation_texture_);
   5638     glGenFramebuffersEXT(1, &validation_fbo_multisample_);
   5639     glGenFramebuffersEXT(1, &validation_fbo_);
   5640 
   5641     // Texture only needs to be 1x1.
   5642     glBindTexture(GL_TEXTURE_2D, validation_texture_);
   5643     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
   5644         GL_UNSIGNED_BYTE, NULL);
   5645 
   5646     glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
   5647     glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   5648         GL_TEXTURE_2D, validation_texture_, 0);
   5649 
   5650     glBindTexture(GL_TEXTURE_2D, bound_texture);
   5651   }
   5652 
   5653   glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
   5654   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   5655       GL_RENDERBUFFER, renderbuffer);
   5656 
   5657   // Cache current state and reset it to the values we require.
   5658   GLboolean scissor_enabled = false;
   5659   glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
   5660   if (scissor_enabled)
   5661     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   5662 
   5663   GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
   5664   glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
   5665   state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   5666 
   5667   GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
   5668   glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
   5669   glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
   5670 
   5671   // Clear the buffer to the desired key color.
   5672   glClear(GL_COLOR_BUFFER_BIT);
   5673 
   5674   // Blit from the multisample buffer to a standard texture.
   5675   glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
   5676   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
   5677 
   5678   BlitFramebufferHelper(
   5679       0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
   5680 
   5681   // Read a pixel from the buffer.
   5682   glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
   5683 
   5684   unsigned char pixel[3] = {0, 0, 0};
   5685   glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
   5686 
   5687   // Detach the renderbuffer.
   5688   glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
   5689   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   5690       GL_RENDERBUFFER, 0);
   5691 
   5692   // Restore cached state.
   5693   if (scissor_enabled)
   5694     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
   5695 
   5696   state_.SetDeviceColorMask(
   5697       color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
   5698   glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
   5699   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
   5700   glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
   5701 
   5702   // Return true if the pixel matched the desired key color.
   5703   return (pixel[0] == 0xFF &&
   5704       pixel[1] == 0x00 &&
   5705       pixel[2] == 0xFF);
   5706 }
   5707 
   5708 void GLES2DecoderImpl::DoRenderbufferStorage(
   5709   GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
   5710   Renderbuffer* renderbuffer =
   5711       GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
   5712   if (!renderbuffer) {
   5713     LOCAL_SET_GL_ERROR(
   5714         GL_INVALID_OPERATION,
   5715         "glRenderbufferStorage", "no renderbuffer bound");
   5716     return;
   5717   }
   5718 
   5719   if (width > renderbuffer_manager()->max_renderbuffer_size() ||
   5720       height > renderbuffer_manager()->max_renderbuffer_size()) {
   5721     LOCAL_SET_GL_ERROR(
   5722         GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
   5723     return;
   5724   }
   5725 
   5726   uint32 estimated_size = 0;
   5727   if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
   5728            width, height, 1, internalformat, &estimated_size)) {
   5729     LOCAL_SET_GL_ERROR(
   5730         GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
   5731     return;
   5732   }
   5733 
   5734   if (!EnsureGPUMemoryAvailable(estimated_size)) {
   5735     LOCAL_SET_GL_ERROR(
   5736         GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
   5737     return;
   5738   }
   5739 
   5740   EnsureRenderbufferBound();
   5741   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
   5742   glRenderbufferStorageEXT(
   5743       target,
   5744       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
   5745           internalformat),
   5746       width,
   5747       height);
   5748   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
   5749   if (error == GL_NO_ERROR) {
   5750     // TODO(gman): If tetxures tracked which framebuffers they were attached to
   5751     // we could just mark those framebuffers as not complete.
   5752     framebuffer_manager()->IncFramebufferStateChangeCount();
   5753     renderbuffer_manager()->SetInfo(
   5754         renderbuffer, 1, internalformat, width, height);
   5755   }
   5756 }
   5757 
   5758 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
   5759   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
   5760   Program* program = GetProgramInfoNotShader(
   5761       program_id, "glLinkProgram");
   5762   if (!program) {
   5763     return;
   5764   }
   5765 
   5766   LogClientServiceForInfo(program, program_id, "glLinkProgram");
   5767   ShaderTranslator* vertex_translator = NULL;
   5768   ShaderTranslator* fragment_translator = NULL;
   5769   if (use_shader_translator_) {
   5770     vertex_translator = vertex_translator_.get();
   5771     fragment_translator = fragment_translator_.get();
   5772   }
   5773   if (program->Link(shader_manager(),
   5774                     vertex_translator,
   5775                     fragment_translator,
   5776                     workarounds().count_all_in_varyings_packing ?
   5777                         Program::kCountAll : Program::kCountOnlyStaticallyUsed,
   5778                     shader_cache_callback_)) {
   5779     if (program == state_.current_program.get()) {
   5780       if (workarounds().use_current_program_after_successful_link)
   5781         glUseProgram(program->service_id());
   5782       if (workarounds().clear_uniforms_before_first_program_use)
   5783         program_manager()->ClearUniforms(program);
   5784     }
   5785   }
   5786 
   5787   // LinkProgram can be very slow.  Exit command processing to allow for
   5788   // context preemption and GPU watchdog checks.
   5789   ExitCommandProcessingEarly();
   5790 };
   5791 
   5792 void GLES2DecoderImpl::DoTexParameterf(
   5793     GLenum target, GLenum pname, GLfloat param) {
   5794   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
   5795       &state_, target);
   5796   if (!texture) {
   5797     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
   5798     return;
   5799   }
   5800 
   5801   texture_manager()->SetParameterf(
   5802       "glTexParameterf", GetErrorState(), texture, pname, param);
   5803 }
   5804 
   5805 void GLES2DecoderImpl::DoTexParameteri(
   5806     GLenum target, GLenum pname, GLint param) {
   5807   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
   5808       &state_, target);
   5809   if (!texture) {
   5810     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
   5811     return;
   5812   }
   5813 
   5814   texture_manager()->SetParameteri(
   5815       "glTexParameteri", GetErrorState(), texture, pname, param);
   5816 }
   5817 
   5818 void GLES2DecoderImpl::DoTexParameterfv(
   5819     GLenum target, GLenum pname, const GLfloat* params) {
   5820   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
   5821       &state_, target);
   5822   if (!texture) {
   5823     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
   5824     return;
   5825   }
   5826 
   5827   texture_manager()->SetParameterf(
   5828       "glTexParameterfv", GetErrorState(), texture, pname, *params);
   5829 }
   5830 
   5831 void GLES2DecoderImpl::DoTexParameteriv(
   5832   GLenum target, GLenum pname, const GLint* params) {
   5833   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
   5834       &state_, target);
   5835   if (!texture) {
   5836     LOCAL_SET_GL_ERROR(
   5837         GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
   5838     return;
   5839   }
   5840 
   5841   texture_manager()->SetParameteri(
   5842       "glTexParameteriv", GetErrorState(), texture, pname, *params);
   5843 }
   5844 
   5845 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
   5846   if (!state_.current_program.get()) {
   5847     // The program does not exist.
   5848     LOCAL_SET_GL_ERROR(
   5849         GL_INVALID_OPERATION, function_name, "no program in use");
   5850     return false;
   5851   }
   5852   if (!state_.current_program->InUse()) {
   5853     LOCAL_SET_GL_ERROR(
   5854         GL_INVALID_OPERATION, function_name, "program not linked");
   5855     return false;
   5856   }
   5857   return true;
   5858 }
   5859 
   5860 bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
   5861     GLint location, const char* function_name) {
   5862   if (!CheckCurrentProgram(function_name)) {
   5863     return false;
   5864   }
   5865   return location != -1;
   5866 }
   5867 
   5868 bool GLES2DecoderImpl::PrepForSetUniformByLocation(
   5869     GLint fake_location,
   5870     const char* function_name,
   5871     Program::UniformApiType api_type,
   5872     GLint* real_location,
   5873     GLenum* type,
   5874     GLsizei* count) {
   5875   DCHECK(type);
   5876   DCHECK(count);
   5877   DCHECK(real_location);
   5878 
   5879   if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
   5880     return false;
   5881   }
   5882   GLint array_index = -1;
   5883   const Program::UniformInfo* info =
   5884       state_.current_program->GetUniformInfoByFakeLocation(
   5885           fake_location, real_location, &array_index);
   5886   if (!info) {
   5887     LOCAL_SET_GL_ERROR(
   5888         GL_INVALID_OPERATION, function_name, "unknown location");
   5889     return false;
   5890   }
   5891 
   5892   if ((api_type & info->accepts_api_type) == 0) {
   5893     LOCAL_SET_GL_ERROR(
   5894         GL_INVALID_OPERATION, function_name,
   5895         "wrong uniform function for type");
   5896     return false;
   5897   }
   5898   if (*count > 1 && !info->is_array) {
   5899     LOCAL_SET_GL_ERROR(
   5900         GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
   5901     return false;
   5902   }
   5903   *count = std::min(info->size - array_index, *count);
   5904   if (*count <= 0) {
   5905     return false;
   5906   }
   5907   *type = info->type;
   5908   return true;
   5909 }
   5910 
   5911 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
   5912   GLenum type = 0;
   5913   GLsizei count = 1;
   5914   GLint real_location = -1;
   5915   if (!PrepForSetUniformByLocation(fake_location,
   5916                                    "glUniform1i",
   5917                                    Program::kUniform1i,
   5918                                    &real_location,
   5919                                    &type,
   5920                                    &count)) {
   5921     return;
   5922   }
   5923   if (!state_.current_program->SetSamplers(
   5924       state_.texture_units.size(), fake_location, 1, &v0)) {
   5925     LOCAL_SET_GL_ERROR(
   5926         GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
   5927     return;
   5928   }
   5929   glUniform1i(real_location, v0);
   5930 }
   5931 
   5932 void GLES2DecoderImpl::DoUniform1iv(
   5933     GLint fake_location, GLsizei count, const GLint *value) {
   5934   GLenum type = 0;
   5935   GLint real_location = -1;
   5936   if (!PrepForSetUniformByLocation(fake_location,
   5937                                    "glUniform1iv",
   5938                                    Program::kUniform1i,
   5939                                    &real_location,
   5940                                    &type,
   5941                                    &count)) {
   5942     return;
   5943   }
   5944   if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
   5945       type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
   5946     if (!state_.current_program->SetSamplers(
   5947           state_.texture_units.size(), fake_location, count, value)) {
   5948       LOCAL_SET_GL_ERROR(
   5949           GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
   5950       return;
   5951     }
   5952   }
   5953   glUniform1iv(real_location, count, value);
   5954 }
   5955 
   5956 void GLES2DecoderImpl::DoUniform1fv(
   5957     GLint fake_location, GLsizei count, const GLfloat* value) {
   5958   GLenum type = 0;
   5959   GLint real_location = -1;
   5960   if (!PrepForSetUniformByLocation(fake_location,
   5961                                    "glUniform1fv",
   5962                                    Program::kUniform1f,
   5963                                    &real_location,
   5964                                    &type,
   5965                                    &count)) {
   5966     return;
   5967   }
   5968   if (type == GL_BOOL) {
   5969     scoped_ptr<GLint[]> temp(new GLint[count]);
   5970     for (GLsizei ii = 0; ii < count; ++ii) {
   5971       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
   5972     }
   5973     DoUniform1iv(real_location, count, temp.get());
   5974   } else {
   5975     glUniform1fv(real_location, count, value);
   5976   }
   5977 }
   5978 
   5979 void GLES2DecoderImpl::DoUniform2fv(
   5980     GLint fake_location, GLsizei count, const GLfloat* value) {
   5981   GLenum type = 0;
   5982   GLint real_location = -1;
   5983   if (!PrepForSetUniformByLocation(fake_location,
   5984                                    "glUniform2fv",
   5985                                    Program::kUniform2f,
   5986                                    &real_location,
   5987                                    &type,
   5988                                    &count)) {
   5989     return;
   5990   }
   5991   if (type == GL_BOOL_VEC2) {
   5992     GLsizei num_values = count * 2;
   5993     scoped_ptr<GLint[]> temp(new GLint[num_values]);
   5994     for (GLsizei ii = 0; ii < num_values; ++ii) {
   5995       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
   5996     }
   5997     glUniform2iv(real_location, count, temp.get());
   5998   } else {
   5999     glUniform2fv(real_location, count, value);
   6000   }
   6001 }
   6002 
   6003 void GLES2DecoderImpl::DoUniform3fv(
   6004     GLint fake_location, GLsizei count, const GLfloat* value) {
   6005   GLenum type = 0;
   6006   GLint real_location = -1;
   6007   if (!PrepForSetUniformByLocation(fake_location,
   6008                                    "glUniform3fv",
   6009                                    Program::kUniform3f,
   6010                                    &real_location,
   6011                                    &type,
   6012                                    &count)) {
   6013     return;
   6014   }
   6015   if (type == GL_BOOL_VEC3) {
   6016     GLsizei num_values = count * 3;
   6017     scoped_ptr<GLint[]> temp(new GLint[num_values]);
   6018     for (GLsizei ii = 0; ii < num_values; ++ii) {
   6019       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
   6020     }
   6021     glUniform3iv(real_location, count, temp.get());
   6022   } else {
   6023     glUniform3fv(real_location, count, value);
   6024   }
   6025 }
   6026 
   6027 void GLES2DecoderImpl::DoUniform4fv(
   6028     GLint fake_location, GLsizei count, const GLfloat* value) {
   6029   GLenum type = 0;
   6030   GLint real_location = -1;
   6031   if (!PrepForSetUniformByLocation(fake_location,
   6032                                    "glUniform4fv",
   6033                                    Program::kUniform4f,
   6034                                    &real_location,
   6035                                    &type,
   6036                                    &count)) {
   6037     return;
   6038   }
   6039   if (type == GL_BOOL_VEC4) {
   6040     GLsizei num_values = count * 4;
   6041     scoped_ptr<GLint[]> temp(new GLint[num_values]);
   6042     for (GLsizei ii = 0; ii < num_values; ++ii) {
   6043       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
   6044     }
   6045     glUniform4iv(real_location, count, temp.get());
   6046   } else {
   6047     glUniform4fv(real_location, count, value);
   6048   }
   6049 }
   6050 
   6051 void GLES2DecoderImpl::DoUniform2iv(
   6052     GLint fake_location, GLsizei count, const GLint* value) {
   6053   GLenum type = 0;
   6054   GLint real_location = -1;
   6055   if (!PrepForSetUniformByLocation(fake_location,
   6056                                    "glUniform2iv",
   6057                                    Program::kUniform2i,
   6058                                    &real_location,
   6059                                    &type,
   6060                                    &count)) {
   6061     return;
   6062   }
   6063   glUniform2iv(real_location, count, value);
   6064 }
   6065 
   6066 void GLES2DecoderImpl::DoUniform3iv(
   6067     GLint fake_location, GLsizei count, const GLint* value) {
   6068   GLenum type = 0;
   6069   GLint real_location = -1;
   6070   if (!PrepForSetUniformByLocation(fake_location,
   6071                                    "glUniform3iv",
   6072                                    Program::kUniform3i,
   6073                                    &real_location,
   6074                                    &type,
   6075                                    &count)) {
   6076     return;
   6077   }
   6078   glUniform3iv(real_location, count, value);
   6079 }
   6080 
   6081 void GLES2DecoderImpl::DoUniform4iv(
   6082     GLint fake_location, GLsizei count, const GLint* value) {
   6083   GLenum type = 0;
   6084   GLint real_location = -1;
   6085   if (!PrepForSetUniformByLocation(fake_location,
   6086                                    "glUniform4iv",
   6087                                    Program::kUniform4i,
   6088                                    &real_location,
   6089                                    &type,
   6090                                    &count)) {
   6091     return;
   6092   }
   6093   glUniform4iv(real_location, count, value);
   6094 }
   6095 
   6096 void GLES2DecoderImpl::DoUniformMatrix2fv(
   6097     GLint fake_location, GLsizei count, GLboolean transpose,
   6098     const GLfloat* value) {
   6099   GLenum type = 0;
   6100   GLint real_location = -1;
   6101   if (!PrepForSetUniformByLocation(fake_location,
   6102                                    "glUniformMatrix2fv",
   6103                                    Program::kUniformMatrix2f,
   6104                                    &real_location,
   6105                                    &type,
   6106                                    &count)) {
   6107     return;
   6108   }
   6109   glUniformMatrix2fv(real_location, count, transpose, value);
   6110 }
   6111 
   6112 void GLES2DecoderImpl::DoUniformMatrix3fv(
   6113     GLint fake_location, GLsizei count, GLboolean transpose,
   6114     const GLfloat* value) {
   6115   GLenum type = 0;
   6116   GLint real_location = -1;
   6117   if (!PrepForSetUniformByLocation(fake_location,
   6118                                    "glUniformMatrix3fv",
   6119                                    Program::kUniformMatrix3f,
   6120                                    &real_location,
   6121                                    &type,
   6122                                    &count)) {
   6123     return;
   6124   }
   6125   glUniformMatrix3fv(real_location, count, transpose, value);
   6126 }
   6127 
   6128 void GLES2DecoderImpl::DoUniformMatrix4fv(
   6129     GLint fake_location, GLsizei count, GLboolean transpose,
   6130     const GLfloat* value) {
   6131   GLenum type = 0;
   6132   GLint real_location = -1;
   6133   if (!PrepForSetUniformByLocation(fake_location,
   6134                                    "glUniformMatrix4fv",
   6135                                    Program::kUniformMatrix4f,
   6136                                    &real_location,
   6137                                    &type,
   6138                                    &count)) {
   6139     return;
   6140   }
   6141   glUniformMatrix4fv(real_location, count, transpose, value);
   6142 }
   6143 
   6144 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
   6145   GLuint service_id = 0;
   6146   Program* program = NULL;
   6147   if (program_id) {
   6148     program = GetProgramInfoNotShader(program_id, "glUseProgram");
   6149     if (!program) {
   6150       return;
   6151     }
   6152     if (!program->IsValid()) {
   6153       // Program was not linked successfully. (ie, glLinkProgram)
   6154       LOCAL_SET_GL_ERROR(
   6155           GL_INVALID_OPERATION, "glUseProgram", "program not linked");
   6156       return;
   6157     }
   6158     service_id = program->service_id();
   6159   }
   6160   if (state_.current_program.get()) {
   6161     program_manager()->UnuseProgram(shader_manager(),
   6162                                     state_.current_program.get());
   6163   }
   6164   state_.current_program = program;
   6165   LogClientServiceMapping("glUseProgram", program_id, service_id);
   6166   glUseProgram(service_id);
   6167   if (state_.current_program.get()) {
   6168     program_manager()->UseProgram(state_.current_program.get());
   6169     if (workarounds().clear_uniforms_before_first_program_use)
   6170       program_manager()->ClearUniforms(program);
   6171   }
   6172 }
   6173 
   6174 void GLES2DecoderImpl::RenderWarning(
   6175     const char* filename, int line, const std::string& msg) {
   6176   logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
   6177 }
   6178 
   6179 void GLES2DecoderImpl::PerformanceWarning(
   6180     const char* filename, int line, const std::string& msg) {
   6181   logger_.LogMessage(filename, line,
   6182                      std::string("PERFORMANCE WARNING: ") + msg);
   6183 }
   6184 
   6185 void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
   6186     Texture* texture, GLenum textarget) {
   6187   // Image is already in use if texture is attached to a framebuffer.
   6188   if (texture && !texture->IsAttachedToFramebuffer()) {
   6189     gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
   6190     if (image) {
   6191       ScopedGLErrorSuppressor suppressor(
   6192           "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
   6193           GetErrorState());
   6194       glBindTexture(textarget, texture->service_id());
   6195       image->WillUseTexImage();
   6196       RestoreCurrentTextureBindings(&state_, textarget);
   6197     }
   6198   }
   6199 }
   6200 
   6201 void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
   6202     Texture* texture, GLenum textarget) {
   6203   // Image is still in use if texture is attached to a framebuffer.
   6204   if (texture && !texture->IsAttachedToFramebuffer()) {
   6205     gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
   6206     if (image) {
   6207       ScopedGLErrorSuppressor suppressor(
   6208           "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
   6209           GetErrorState());
   6210       glBindTexture(textarget, texture->service_id());
   6211       image->DidUseTexImage();
   6212       RestoreCurrentTextureBindings(&state_, textarget);
   6213     }
   6214   }
   6215 }
   6216 
   6217 bool GLES2DecoderImpl::PrepareTexturesForRender() {
   6218   DCHECK(state_.current_program.get());
   6219   if (!texture_manager()->HaveUnrenderableTextures() &&
   6220       !texture_manager()->HaveImages()) {
   6221     return true;
   6222   }
   6223 
   6224   bool textures_set = false;
   6225   const Program::SamplerIndices& sampler_indices =
   6226      state_.current_program->sampler_indices();
   6227   for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
   6228     const Program::UniformInfo* uniform_info =
   6229         state_.current_program->GetUniformInfo(sampler_indices[ii]);
   6230     DCHECK(uniform_info);
   6231     for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
   6232       GLuint texture_unit_index = uniform_info->texture_units[jj];
   6233       if (texture_unit_index < state_.texture_units.size()) {
   6234         TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
   6235         TextureRef* texture_ref =
   6236             texture_unit.GetInfoForSamplerType(uniform_info->type).get();
   6237         GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
   6238         if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
   6239           textures_set = true;
   6240           glActiveTexture(GL_TEXTURE0 + texture_unit_index);
   6241           glBindTexture(
   6242               textarget,
   6243               texture_manager()->black_texture_id(uniform_info->type));
   6244           LOCAL_RENDER_WARNING(
   6245               std::string("texture bound to texture unit ") +
   6246               base::IntToString(texture_unit_index) +
   6247               " is not renderable. It maybe non-power-of-2 and have"
   6248               " incompatible texture filtering or is not"
   6249               " 'texture complete'");
   6250           continue;
   6251         }
   6252 
   6253         if (textarget != GL_TEXTURE_CUBE_MAP) {
   6254           Texture* texture = texture_ref->texture();
   6255           gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
   6256           if (image && !texture->IsAttachedToFramebuffer()) {
   6257             ScopedGLErrorSuppressor suppressor(
   6258                 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
   6259             textures_set = true;
   6260             glActiveTexture(GL_TEXTURE0 + texture_unit_index);
   6261             image->WillUseTexImage();
   6262             continue;
   6263           }
   6264         }
   6265       }
   6266       // else: should this be an error?
   6267     }
   6268   }
   6269   return !textures_set;
   6270 }
   6271 
   6272 void GLES2DecoderImpl::RestoreStateForTextures() {
   6273   DCHECK(state_.current_program.get());
   6274   const Program::SamplerIndices& sampler_indices =
   6275       state_.current_program->sampler_indices();
   6276   for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
   6277     const Program::UniformInfo* uniform_info =
   6278         state_.current_program->GetUniformInfo(sampler_indices[ii]);
   6279     DCHECK(uniform_info);
   6280     for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
   6281       GLuint texture_unit_index = uniform_info->texture_units[jj];
   6282       if (texture_unit_index < state_.texture_units.size()) {
   6283         TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
   6284         TextureRef* texture_ref =
   6285             texture_unit.GetInfoForSamplerType(uniform_info->type).get();
   6286         if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
   6287           glActiveTexture(GL_TEXTURE0 + texture_unit_index);
   6288           // Get the texture_ref info that was previously bound here.
   6289           texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
   6290                             ? texture_unit.bound_texture_2d.get()
   6291                             : texture_unit.bound_texture_cube_map.get();
   6292           glBindTexture(texture_unit.bind_target,
   6293                         texture_ref ? texture_ref->service_id() : 0);
   6294           continue;
   6295         }
   6296 
   6297         if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
   6298           Texture* texture = texture_ref->texture();
   6299           gfx::GLImage* image =
   6300               texture->GetLevelImage(texture_unit.bind_target, 0);
   6301           if (image && !texture->IsAttachedToFramebuffer()) {
   6302             ScopedGLErrorSuppressor suppressor(
   6303                 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
   6304             glActiveTexture(GL_TEXTURE0 + texture_unit_index);
   6305             image->DidUseTexImage();
   6306             continue;
   6307           }
   6308         }
   6309       }
   6310     }
   6311   }
   6312   // Set the active texture back to whatever the user had it as.
   6313   glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
   6314 }
   6315 
   6316 bool GLES2DecoderImpl::ClearUnclearedTextures() {
   6317   // Only check if there are some uncleared textures.
   6318   if (!texture_manager()->HaveUnsafeTextures()) {
   6319     return true;
   6320   }
   6321 
   6322   // 1: Check all textures we are about to render with.
   6323   if (state_.current_program.get()) {
   6324     const Program::SamplerIndices& sampler_indices =
   6325         state_.current_program->sampler_indices();
   6326     for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
   6327       const Program::UniformInfo* uniform_info =
   6328           state_.current_program->GetUniformInfo(sampler_indices[ii]);
   6329       DCHECK(uniform_info);
   6330       for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
   6331         GLuint texture_unit_index = uniform_info->texture_units[jj];
   6332         if (texture_unit_index < state_.texture_units.size()) {
   6333           TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
   6334           TextureRef* texture_ref =
   6335               texture_unit.GetInfoForSamplerType(uniform_info->type).get();
   6336           if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
   6337             if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
   6338               return false;
   6339             }
   6340           }
   6341         }
   6342       }
   6343     }
   6344   }
   6345   return true;
   6346 }
   6347 
   6348 bool GLES2DecoderImpl::IsDrawValid(
   6349     const char* function_name, GLuint max_vertex_accessed, bool instanced,
   6350     GLsizei primcount) {
   6351   DCHECK(instanced || primcount == 1);
   6352 
   6353   // NOTE: We specifically do not check current_program->IsValid() because
   6354   // it could never be invalid since glUseProgram would have failed. While
   6355   // glLinkProgram could later mark the program as invalid the previous
   6356   // valid program will still function if it is still the current program.
   6357   if (!state_.current_program.get()) {
   6358     // The program does not exist.
   6359     // But GL says no ERROR.
   6360     LOCAL_RENDER_WARNING("Drawing with no current shader program.");
   6361     return false;
   6362   }
   6363 
   6364   return state_.vertex_attrib_manager
   6365       ->ValidateBindings(function_name,
   6366                          this,
   6367                          feature_info_.get(),
   6368                          state_.current_program.get(),
   6369                          max_vertex_accessed,
   6370                          instanced,
   6371                          primcount);
   6372 }
   6373 
   6374 bool GLES2DecoderImpl::SimulateAttrib0(
   6375     const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
   6376   DCHECK(simulated);
   6377   *simulated = false;
   6378 
   6379   if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
   6380     return true;
   6381 
   6382   const VertexAttrib* attrib =
   6383       state_.vertex_attrib_manager->GetVertexAttrib(0);
   6384   // If it's enabled or it's not used then we don't need to do anything.
   6385   bool attrib_0_used =
   6386       state_.current_program->GetAttribInfoByLocation(0) != NULL;
   6387   if (attrib->enabled() && attrib_0_used) {
   6388     return true;
   6389   }
   6390 
   6391   // Make a buffer with a single repeated vec4 value enough to
   6392   // simulate the constant value that is supposed to be here.
   6393   // This is required to emulate GLES2 on GL.
   6394   GLuint num_vertices = max_vertex_accessed + 1;
   6395   uint32 size_needed = 0;
   6396 
   6397   if (num_vertices == 0 ||
   6398       !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
   6399       size_needed > 0x7FFFFFFFU) {
   6400     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
   6401     return false;
   6402   }
   6403 
   6404   LOCAL_PERFORMANCE_WARNING(
   6405       "Attribute 0 is disabled. This has signficant performance penalty");
   6406 
   6407   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
   6408   glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
   6409 
   6410   bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
   6411   if (new_buffer) {
   6412     glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
   6413     GLenum error = glGetError();
   6414     if (error != GL_NO_ERROR) {
   6415       LOCAL_SET_GL_ERROR(
   6416           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
   6417       return false;
   6418     }
   6419   }
   6420 
   6421   const Vec4& value = state_.attrib_values[0];
   6422   if (new_buffer ||
   6423       (attrib_0_used &&
   6424        (!attrib_0_buffer_matches_value_ ||
   6425         (value.v[0] != attrib_0_value_.v[0] ||
   6426          value.v[1] != attrib_0_value_.v[1] ||
   6427          value.v[2] != attrib_0_value_.v[2] ||
   6428          value.v[3] != attrib_0_value_.v[3])))) {
   6429     std::vector<Vec4> temp(num_vertices, value);
   6430     glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
   6431     attrib_0_buffer_matches_value_ = true;
   6432     attrib_0_value_ = value;
   6433     attrib_0_size_ = size_needed;
   6434   }
   6435 
   6436   glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6437 
   6438   if (attrib->divisor())
   6439     glVertexAttribDivisorANGLE(0, 0);
   6440 
   6441   *simulated = true;
   6442   return true;
   6443 }
   6444 
   6445 void GLES2DecoderImpl::RestoreStateForAttrib(
   6446     GLuint attrib_index, bool restore_array_binding) {
   6447   const VertexAttrib* attrib =
   6448       state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
   6449   if (restore_array_binding) {
   6450     const void* ptr = reinterpret_cast<const void*>(attrib->offset());
   6451     Buffer* buffer = attrib->buffer();
   6452     glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
   6453     glVertexAttribPointer(
   6454         attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
   6455         attrib->gl_stride(), ptr);
   6456   }
   6457   if (attrib->divisor())
   6458     glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
   6459   glBindBuffer(
   6460       GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
   6461           state_.bound_array_buffer->service_id() : 0);
   6462 
   6463   // Never touch vertex attribute 0's state (in particular, never
   6464   // disable it) when running on desktop GL because it will never be
   6465   // re-enabled.
   6466   if (attrib_index != 0 ||
   6467       gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
   6468     if (attrib->enabled()) {
   6469       glEnableVertexAttribArray(attrib_index);
   6470     } else {
   6471       glDisableVertexAttribArray(attrib_index);
   6472     }
   6473   }
   6474 }
   6475 
   6476 bool GLES2DecoderImpl::SimulateFixedAttribs(
   6477     const char* function_name,
   6478     GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
   6479   DCHECK(simulated);
   6480   *simulated = false;
   6481   if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
   6482     return true;
   6483 
   6484   if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
   6485     return true;
   6486   }
   6487 
   6488   LOCAL_PERFORMANCE_WARNING(
   6489       "GL_FIXED attributes have a signficant performance penalty");
   6490 
   6491   // NOTE: we could be smart and try to check if a buffer is used
   6492   // twice in 2 different attribs, find the overlapping parts and therefore
   6493   // duplicate the minimum amount of data but this whole code path is not meant
   6494   // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
   6495   // tests so we just add to the buffer attrib used.
   6496 
   6497   GLuint elements_needed = 0;
   6498   const VertexAttribManager::VertexAttribList& enabled_attribs =
   6499       state_.vertex_attrib_manager->GetEnabledVertexAttribs();
   6500   for (VertexAttribManager::VertexAttribList::const_iterator it =
   6501        enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
   6502     const VertexAttrib* attrib = *it;
   6503     const Program::VertexAttrib* attrib_info =
   6504         state_.current_program->GetAttribInfoByLocation(attrib->index());
   6505     GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
   6506                                                     max_vertex_accessed);
   6507     GLuint num_vertices = max_accessed + 1;
   6508     if (num_vertices == 0) {
   6509       LOCAL_SET_GL_ERROR(
   6510           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
   6511       return false;
   6512     }
   6513     if (attrib_info &&
   6514         attrib->CanAccess(max_accessed) &&
   6515         attrib->type() == GL_FIXED) {
   6516       uint32 elements_used = 0;
   6517       if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
   6518           !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
   6519         LOCAL_SET_GL_ERROR(
   6520             GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
   6521         return false;
   6522       }
   6523     }
   6524   }
   6525 
   6526   const uint32 kSizeOfFloat = sizeof(float);  // NOLINT
   6527   uint32 size_needed = 0;
   6528   if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
   6529       size_needed > 0x7FFFFFFFU) {
   6530     LOCAL_SET_GL_ERROR(
   6531         GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
   6532     return false;
   6533   }
   6534 
   6535   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
   6536 
   6537   glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
   6538   if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
   6539     glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
   6540     GLenum error = glGetError();
   6541     if (error != GL_NO_ERROR) {
   6542       LOCAL_SET_GL_ERROR(
   6543           GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
   6544       return false;
   6545     }
   6546   }
   6547 
   6548   // Copy the elements and convert to float
   6549   GLintptr offset = 0;
   6550   for (VertexAttribManager::VertexAttribList::const_iterator it =
   6551        enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
   6552     const VertexAttrib* attrib = *it;
   6553     const Program::VertexAttrib* attrib_info =
   6554         state_.current_program->GetAttribInfoByLocation(attrib->index());
   6555     GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
   6556                                                   max_vertex_accessed);
   6557     GLuint num_vertices = max_accessed + 1;
   6558     if (num_vertices == 0) {
   6559       LOCAL_SET_GL_ERROR(
   6560           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
   6561       return false;
   6562     }
   6563     if (attrib_info &&
   6564         attrib->CanAccess(max_accessed) &&
   6565         attrib->type() == GL_FIXED) {
   6566       int num_elements = attrib->size() * kSizeOfFloat;
   6567       int size = num_elements * num_vertices;
   6568       scoped_ptr<float[]> data(new float[size]);
   6569       const int32* src = reinterpret_cast<const int32 *>(
   6570           attrib->buffer()->GetRange(attrib->offset(), size));
   6571       const int32* end = src + num_elements;
   6572       float* dst = data.get();
   6573       while (src != end) {
   6574         *dst++ = static_cast<float>(*src++) / 65536.0f;
   6575       }
   6576       glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
   6577       glVertexAttribPointer(
   6578           attrib->index(), attrib->size(), GL_FLOAT, false, 0,
   6579           reinterpret_cast<GLvoid*>(offset));
   6580       offset += size;
   6581     }
   6582   }
   6583   *simulated = true;
   6584   return true;
   6585 }
   6586 
   6587 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
   6588   // There's no need to call glVertexAttribPointer because we shadow all the
   6589   // settings and passing GL_FIXED to it will not work.
   6590   glBindBuffer(
   6591       GL_ARRAY_BUFFER,
   6592       state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
   6593                                       : 0);
   6594 }
   6595 
   6596 error::Error GLES2DecoderImpl::DoDrawArrays(
   6597     const char* function_name,
   6598     bool instanced,
   6599     GLenum mode,
   6600     GLint first,
   6601     GLsizei count,
   6602     GLsizei primcount) {
   6603   error::Error error = WillAccessBoundFramebufferForDraw();
   6604   if (error != error::kNoError)
   6605     return error;
   6606   if (!validators_->draw_mode.IsValid(mode)) {
   6607     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
   6608     return error::kNoError;
   6609   }
   6610   if (count < 0) {
   6611     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
   6612     return error::kNoError;
   6613   }
   6614   if (primcount < 0) {
   6615     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
   6616     return error::kNoError;
   6617   }
   6618   if (!CheckBoundFramebuffersValid(function_name)) {
   6619     return error::kNoError;
   6620   }
   6621   // We have to check this here because the prototype for glDrawArrays
   6622   // is GLint not GLsizei.
   6623   if (first < 0) {
   6624     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
   6625     return error::kNoError;
   6626   }
   6627 
   6628   if (count == 0 || primcount == 0) {
   6629     LOCAL_RENDER_WARNING("Render count or primcount is 0.");
   6630     return error::kNoError;
   6631   }
   6632 
   6633   GLuint max_vertex_accessed = first + count - 1;
   6634   if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
   6635     if (!ClearUnclearedTextures()) {
   6636       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
   6637       return error::kNoError;
   6638     }
   6639     bool simulated_attrib_0 = false;
   6640     if (!SimulateAttrib0(
   6641         function_name, max_vertex_accessed, &simulated_attrib_0)) {
   6642       return error::kNoError;
   6643     }
   6644     bool simulated_fixed_attribs = false;
   6645     if (SimulateFixedAttribs(
   6646         function_name, max_vertex_accessed, &simulated_fixed_attribs,
   6647         primcount)) {
   6648       bool textures_set = !PrepareTexturesForRender();
   6649       ApplyDirtyState();
   6650       ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
   6651       if (!instanced) {
   6652         glDrawArrays(mode, first, count);
   6653       } else {
   6654         glDrawArraysInstancedANGLE(mode, first, count, primcount);
   6655       }
   6656       if (textures_set) {
   6657         RestoreStateForTextures();
   6658       }
   6659       if (simulated_fixed_attribs) {
   6660         RestoreStateForSimulatedFixedAttribs();
   6661       }
   6662     }
   6663     if (simulated_attrib_0) {
   6664       // We don't have to restore attrib 0 generic data at the end of this
   6665       // function even if it is simulated. This is because we will simulate
   6666       // it in each draw call, and attrib 0 generic data queries use cached
   6667       // values instead of passing down to the underlying driver.
   6668       RestoreStateForAttrib(0, false);
   6669     }
   6670   }
   6671   return error::kNoError;
   6672 }
   6673 
   6674 error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
   6675                                                 const void* cmd_data) {
   6676   const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
   6677   return DoDrawArrays("glDrawArrays",
   6678                       false,
   6679                       static_cast<GLenum>(c.mode),
   6680                       static_cast<GLint>(c.first),
   6681                       static_cast<GLsizei>(c.count),
   6682                       1);
   6683 }
   6684 
   6685 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
   6686     uint32 immediate_data_size,
   6687     const void* cmd_data) {
   6688   const gles2::cmds::DrawArraysInstancedANGLE& c =
   6689       *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
   6690   if (!features().angle_instanced_arrays) {
   6691     LOCAL_SET_GL_ERROR(
   6692         GL_INVALID_OPERATION,
   6693         "glDrawArraysInstancedANGLE", "function not available");
   6694     return error::kNoError;
   6695   }
   6696   return DoDrawArrays("glDrawArraysIntancedANGLE",
   6697                       true,
   6698                       static_cast<GLenum>(c.mode),
   6699                       static_cast<GLint>(c.first),
   6700                       static_cast<GLsizei>(c.count),
   6701                       static_cast<GLsizei>(c.primcount));
   6702 }
   6703 
   6704 error::Error GLES2DecoderImpl::DoDrawElements(
   6705     const char* function_name,
   6706     bool instanced,
   6707     GLenum mode,
   6708     GLsizei count,
   6709     GLenum type,
   6710     int32 offset,
   6711     GLsizei primcount) {
   6712   error::Error error = WillAccessBoundFramebufferForDraw();
   6713   if (error != error::kNoError)
   6714     return error;
   6715   if (!state_.vertex_attrib_manager->element_array_buffer()) {
   6716     LOCAL_SET_GL_ERROR(
   6717         GL_INVALID_OPERATION, function_name, "No element array buffer bound");
   6718     return error::kNoError;
   6719   }
   6720 
   6721   if (count < 0) {
   6722     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
   6723     return error::kNoError;
   6724   }
   6725   if (offset < 0) {
   6726     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
   6727     return error::kNoError;
   6728   }
   6729   if (!validators_->draw_mode.IsValid(mode)) {
   6730     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
   6731     return error::kNoError;
   6732   }
   6733   if (!validators_->index_type.IsValid(type)) {
   6734     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
   6735     return error::kNoError;
   6736   }
   6737   if (primcount < 0) {
   6738     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
   6739     return error::kNoError;
   6740   }
   6741 
   6742   if (!CheckBoundFramebuffersValid(function_name)) {
   6743     return error::kNoError;
   6744   }
   6745 
   6746   if (count == 0 || primcount == 0) {
   6747     return error::kNoError;
   6748   }
   6749 
   6750   GLuint max_vertex_accessed;
   6751   Buffer* element_array_buffer =
   6752       state_.vertex_attrib_manager->element_array_buffer();
   6753 
   6754   if (!element_array_buffer->GetMaxValueForRange(
   6755       offset, count, type, &max_vertex_accessed)) {
   6756     LOCAL_SET_GL_ERROR(
   6757         GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
   6758     return error::kNoError;
   6759   }
   6760 
   6761   if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
   6762     if (!ClearUnclearedTextures()) {
   6763       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
   6764       return error::kNoError;
   6765     }
   6766     bool simulated_attrib_0 = false;
   6767     if (!SimulateAttrib0(
   6768         function_name, max_vertex_accessed, &simulated_attrib_0)) {
   6769       return error::kNoError;
   6770     }
   6771     bool simulated_fixed_attribs = false;
   6772     if (SimulateFixedAttribs(
   6773         function_name, max_vertex_accessed, &simulated_fixed_attribs,
   6774         primcount)) {
   6775       bool textures_set = !PrepareTexturesForRender();
   6776       ApplyDirtyState();
   6777       // TODO(gman): Refactor to hide these details in BufferManager or
   6778       // VertexAttribManager.
   6779       const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
   6780       bool used_client_side_array = false;
   6781       if (element_array_buffer->IsClientSideArray()) {
   6782         used_client_side_array = true;
   6783         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
   6784         indices = element_array_buffer->GetRange(offset, 0);
   6785       }
   6786 
   6787       ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
   6788       if (!instanced) {
   6789         glDrawElements(mode, count, type, indices);
   6790       } else {
   6791         glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
   6792       }
   6793 
   6794       if (used_client_side_array) {
   6795         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
   6796                      element_array_buffer->service_id());
   6797       }
   6798 
   6799       if (textures_set) {
   6800         RestoreStateForTextures();
   6801       }
   6802       if (simulated_fixed_attribs) {
   6803         RestoreStateForSimulatedFixedAttribs();
   6804       }
   6805     }
   6806     if (simulated_attrib_0) {
   6807       // We don't have to restore attrib 0 generic data at the end of this
   6808       // function even if it is simulated. This is because we will simulate
   6809       // it in each draw call, and attrib 0 generic data queries use cached
   6810       // values instead of passing down to the underlying driver.
   6811       RestoreStateForAttrib(0, false);
   6812     }
   6813   }
   6814   return error::kNoError;
   6815 }
   6816 
   6817 error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
   6818                                                   const void* cmd_data) {
   6819   const gles2::cmds::DrawElements& c =
   6820       *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
   6821   return DoDrawElements("glDrawElements",
   6822                         false,
   6823                         static_cast<GLenum>(c.mode),
   6824                         static_cast<GLsizei>(c.count),
   6825                         static_cast<GLenum>(c.type),
   6826                         static_cast<int32>(c.index_offset),
   6827                         1);
   6828 }
   6829 
   6830 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
   6831     uint32 immediate_data_size,
   6832     const void* cmd_data) {
   6833   const gles2::cmds::DrawElementsInstancedANGLE& c =
   6834       *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
   6835   if (!features().angle_instanced_arrays) {
   6836     LOCAL_SET_GL_ERROR(
   6837         GL_INVALID_OPERATION,
   6838         "glDrawElementsInstancedANGLE", "function not available");
   6839     return error::kNoError;
   6840   }
   6841   return DoDrawElements("glDrawElementsInstancedANGLE",
   6842                         true,
   6843                         static_cast<GLenum>(c.mode),
   6844                         static_cast<GLsizei>(c.count),
   6845                         static_cast<GLenum>(c.type),
   6846                         static_cast<int32>(c.index_offset),
   6847                         static_cast<GLsizei>(c.primcount));
   6848 }
   6849 
   6850 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
   6851     GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
   6852   GLuint max_vertex_accessed = 0;
   6853   Buffer* buffer = GetBuffer(buffer_id);
   6854   if (!buffer) {
   6855     // TODO(gman): Should this be a GL error or a command buffer error?
   6856     LOCAL_SET_GL_ERROR(
   6857         GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
   6858   } else {
   6859     if (!buffer->GetMaxValueForRange(
   6860         offset, count, type, &max_vertex_accessed)) {
   6861       // TODO(gman): Should this be a GL error or a command buffer error?
   6862       LOCAL_SET_GL_ERROR(
   6863           GL_INVALID_OPERATION,
   6864           "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
   6865     }
   6866   }
   6867   return max_vertex_accessed;
   6868 }
   6869 
   6870 // Calls glShaderSource for the various versions of the ShaderSource command.
   6871 // Assumes that data / data_size points to a piece of memory that is in range
   6872 // of whatever context it came from (shared memory, immediate memory, bucket
   6873 // memory.)
   6874 error::Error GLES2DecoderImpl::ShaderSourceHelper(
   6875     GLuint client_id, const char* data, uint32 data_size) {
   6876   std::string str(data, data + data_size);
   6877   Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
   6878   if (!shader) {
   6879     return error::kNoError;
   6880   }
   6881   // Note: We don't actually call glShaderSource here. We wait until
   6882   // the call to glCompileShader.
   6883   shader->set_source(str);
   6884   return error::kNoError;
   6885 }
   6886 
   6887 error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
   6888     uint32 immediate_data_size,
   6889     const void* cmd_data) {
   6890   const gles2::cmds::ShaderSourceBucket& c =
   6891       *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
   6892   Bucket* bucket = GetBucket(c.data_bucket_id);
   6893   if (!bucket || bucket->size() == 0) {
   6894     return error::kInvalidArguments;
   6895   }
   6896   return ShaderSourceHelper(
   6897       c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
   6898       bucket->size() - 1);
   6899 }
   6900 
   6901 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
   6902   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
   6903   Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
   6904   if (!shader) {
   6905     return;
   6906   }
   6907   ShaderTranslator* translator = NULL;
   6908   if (use_shader_translator_) {
   6909     translator = shader->shader_type() == GL_VERTEX_SHADER ?
   6910         vertex_translator_.get() : fragment_translator_.get();
   6911   }
   6912 
   6913   shader->DoCompile(
   6914      translator,
   6915      feature_info_->feature_flags().angle_translated_shader_source ?
   6916          Shader::kANGLE : Shader::kGL);
   6917 
   6918   // CompileShader can be very slow.  Exit command processing to allow for
   6919   // context preemption and GPU watchdog checks.
   6920   ExitCommandProcessingEarly();
   6921 }
   6922 
   6923 void GLES2DecoderImpl::DoGetShaderiv(
   6924     GLuint shader_id, GLenum pname, GLint* params) {
   6925   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
   6926   if (!shader) {
   6927     return;
   6928   }
   6929   switch (pname) {
   6930     case GL_SHADER_SOURCE_LENGTH:
   6931       *params = shader->source().size();
   6932       if (*params)
   6933         ++(*params);
   6934       return;
   6935     case GL_COMPILE_STATUS:
   6936       *params = compile_shader_always_succeeds_ ? true : shader->valid();
   6937       return;
   6938     case GL_INFO_LOG_LENGTH:
   6939       *params = shader->log_info().size();
   6940       if (*params)
   6941         ++(*params);
   6942       return;
   6943     case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
   6944       *params = shader->translated_source().size();
   6945       if (*params)
   6946         ++(*params);
   6947       return;
   6948     default:
   6949       break;
   6950   }
   6951   glGetShaderiv(shader->service_id(), pname, params);
   6952 }
   6953 
   6954 error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
   6955                                                      const void* cmd_data) {
   6956   const gles2::cmds::GetShaderSource& c =
   6957       *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
   6958   GLuint shader_id = c.shader;
   6959   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   6960   Bucket* bucket = CreateBucket(bucket_id);
   6961   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
   6962   if (!shader || shader->source().empty()) {
   6963     bucket->SetSize(0);
   6964     return error::kNoError;
   6965   }
   6966   bucket->SetFromString(shader->source().c_str());
   6967   return error::kNoError;
   6968 }
   6969 
   6970 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
   6971     uint32 immediate_data_size,
   6972     const void* cmd_data) {
   6973   const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
   6974       *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
   6975           cmd_data);
   6976   GLuint shader_id = c.shader;
   6977   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   6978   Bucket* bucket = CreateBucket(bucket_id);
   6979   Shader* shader = GetShaderInfoNotProgram(
   6980       shader_id, "glGetTranslatedShaderSourceANGLE");
   6981   if (!shader) {
   6982     bucket->SetSize(0);
   6983     return error::kNoError;
   6984   }
   6985 
   6986   bucket->SetFromString(shader->translated_source().c_str());
   6987   return error::kNoError;
   6988 }
   6989 
   6990 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
   6991     uint32 immediate_data_size,
   6992     const void* cmd_data) {
   6993   const gles2::cmds::GetProgramInfoLog& c =
   6994       *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
   6995   GLuint program_id = c.program;
   6996   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   6997   Bucket* bucket = CreateBucket(bucket_id);
   6998   Program* program = GetProgramInfoNotShader(
   6999       program_id, "glGetProgramInfoLog");
   7000   if (!program || !program->log_info()) {
   7001     bucket->SetFromString("");
   7002     return error::kNoError;
   7003   }
   7004   bucket->SetFromString(program->log_info()->c_str());
   7005   return error::kNoError;
   7006 }
   7007 
   7008 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
   7009     uint32 immediate_data_size,
   7010     const void* cmd_data) {
   7011   const gles2::cmds::GetShaderInfoLog& c =
   7012       *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
   7013   GLuint shader_id = c.shader;
   7014   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   7015   Bucket* bucket = CreateBucket(bucket_id);
   7016   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
   7017   if (!shader) {
   7018     bucket->SetFromString("");
   7019     return error::kNoError;
   7020   }
   7021   bucket->SetFromString(shader->log_info().c_str());
   7022   return error::kNoError;
   7023 }
   7024 
   7025 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
   7026   return state_.GetEnabled(cap);
   7027 }
   7028 
   7029 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
   7030   const Buffer* buffer = GetBuffer(client_id);
   7031   return buffer && buffer->IsValid() && !buffer->IsDeleted();
   7032 }
   7033 
   7034 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
   7035   const Framebuffer* framebuffer =
   7036       GetFramebuffer(client_id);
   7037   return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
   7038 }
   7039 
   7040 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
   7041   // IsProgram is true for programs as soon as they are created, until they are
   7042   // deleted and no longer in use.
   7043   const Program* program = GetProgram(client_id);
   7044   return program != NULL && !program->IsDeleted();
   7045 }
   7046 
   7047 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
   7048   const Renderbuffer* renderbuffer =
   7049       GetRenderbuffer(client_id);
   7050   return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
   7051 }
   7052 
   7053 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
   7054   // IsShader is true for shaders as soon as they are created, until they
   7055   // are deleted and not attached to any programs.
   7056   const Shader* shader = GetShader(client_id);
   7057   return shader != NULL && !shader->IsDeleted();
   7058 }
   7059 
   7060 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
   7061   const TextureRef* texture_ref = GetTexture(client_id);
   7062   return texture_ref && texture_ref->texture()->IsValid();
   7063 }
   7064 
   7065 void GLES2DecoderImpl::DoAttachShader(
   7066     GLuint program_client_id, GLint shader_client_id) {
   7067   Program* program = GetProgramInfoNotShader(
   7068       program_client_id, "glAttachShader");
   7069   if (!program) {
   7070     return;
   7071   }
   7072   Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
   7073   if (!shader) {
   7074     return;
   7075   }
   7076   if (!program->AttachShader(shader_manager(), shader)) {
   7077     LOCAL_SET_GL_ERROR(
   7078         GL_INVALID_OPERATION,
   7079         "glAttachShader",
   7080         "can not attach more than one shader of the same type.");
   7081     return;
   7082   }
   7083   glAttachShader(program->service_id(), shader->service_id());
   7084 }
   7085 
   7086 void GLES2DecoderImpl::DoDetachShader(
   7087     GLuint program_client_id, GLint shader_client_id) {
   7088   Program* program = GetProgramInfoNotShader(
   7089       program_client_id, "glDetachShader");
   7090   if (!program) {
   7091     return;
   7092   }
   7093   Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
   7094   if (!shader) {
   7095     return;
   7096   }
   7097   if (!program->DetachShader(shader_manager(), shader)) {
   7098     LOCAL_SET_GL_ERROR(
   7099         GL_INVALID_OPERATION,
   7100         "glDetachShader", "shader not attached to program");
   7101     return;
   7102   }
   7103   glDetachShader(program->service_id(), shader->service_id());
   7104 }
   7105 
   7106 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
   7107   Program* program = GetProgramInfoNotShader(
   7108       program_client_id, "glValidateProgram");
   7109   if (!program) {
   7110     return;
   7111   }
   7112   program->Validate();
   7113 }
   7114 
   7115 void GLES2DecoderImpl::GetVertexAttribHelper(
   7116     const VertexAttrib* attrib, GLenum pname, GLint* params) {
   7117   switch (pname) {
   7118     case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
   7119         Buffer* buffer = attrib->buffer();
   7120         if (buffer && !buffer->IsDeleted()) {
   7121           GLuint client_id;
   7122           buffer_manager()->GetClientId(buffer->service_id(), &client_id);
   7123           *params = client_id;
   7124         }
   7125         break;
   7126       }
   7127     case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   7128       *params = attrib->enabled();
   7129       break;
   7130     case GL_VERTEX_ATTRIB_ARRAY_SIZE:
   7131       *params = attrib->size();
   7132       break;
   7133     case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   7134       *params = attrib->gl_stride();
   7135       break;
   7136     case GL_VERTEX_ATTRIB_ARRAY_TYPE:
   7137       *params = attrib->type();
   7138       break;
   7139     case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   7140       *params = attrib->normalized();
   7141       break;
   7142     case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
   7143       *params = attrib->divisor();
   7144       break;
   7145     default:
   7146       NOTREACHED();
   7147       break;
   7148   }
   7149 }
   7150 
   7151 void GLES2DecoderImpl::DoGetTexParameterfv(
   7152     GLenum target, GLenum pname, GLfloat* params) {
   7153   InitTextureMaxAnisotropyIfNeeded(target, pname);
   7154   glGetTexParameterfv(target, pname, params);
   7155 }
   7156 
   7157 void GLES2DecoderImpl::DoGetTexParameteriv(
   7158     GLenum target, GLenum pname, GLint* params) {
   7159   InitTextureMaxAnisotropyIfNeeded(target, pname);
   7160   glGetTexParameteriv(target, pname, params);
   7161 }
   7162 
   7163 void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
   7164     GLenum target, GLenum pname) {
   7165   if (!workarounds().init_texture_max_anisotropy)
   7166     return;
   7167   if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
   7168       !validators_->texture_parameter.IsValid(pname)) {
   7169     return;
   7170   }
   7171 
   7172   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   7173       &state_, target);
   7174   if (!texture_ref) {
   7175     LOCAL_SET_GL_ERROR(
   7176         GL_INVALID_OPERATION,
   7177         "glGetTexParamter{fi}v", "unknown texture for target");
   7178     return;
   7179   }
   7180   Texture* texture = texture_ref->texture();
   7181   texture->InitTextureMaxAnisotropyIfNeeded(target);
   7182 }
   7183 
   7184 void GLES2DecoderImpl::DoGetVertexAttribfv(
   7185     GLuint index, GLenum pname, GLfloat* params) {
   7186   VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
   7187   if (!attrib) {
   7188     LOCAL_SET_GL_ERROR(
   7189         GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
   7190     return;
   7191   }
   7192   switch (pname) {
   7193     case GL_CURRENT_VERTEX_ATTRIB: {
   7194       const Vec4& value = state_.attrib_values[index];
   7195       params[0] = value.v[0];
   7196       params[1] = value.v[1];
   7197       params[2] = value.v[2];
   7198       params[3] = value.v[3];
   7199       break;
   7200     }
   7201     default: {
   7202       GLint value = 0;
   7203       GetVertexAttribHelper(attrib, pname, &value);
   7204       *params = static_cast<GLfloat>(value);
   7205       break;
   7206     }
   7207   }
   7208 }
   7209 
   7210 void GLES2DecoderImpl::DoGetVertexAttribiv(
   7211     GLuint index, GLenum pname, GLint* params) {
   7212   VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
   7213   if (!attrib) {
   7214     LOCAL_SET_GL_ERROR(
   7215         GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
   7216     return;
   7217   }
   7218   switch (pname) {
   7219     case GL_CURRENT_VERTEX_ATTRIB: {
   7220       const Vec4& value = state_.attrib_values[index];
   7221       params[0] = static_cast<GLint>(value.v[0]);
   7222       params[1] = static_cast<GLint>(value.v[1]);
   7223       params[2] = static_cast<GLint>(value.v[2]);
   7224       params[3] = static_cast<GLint>(value.v[3]);
   7225       break;
   7226     }
   7227     default:
   7228       GetVertexAttribHelper(attrib, pname, params);
   7229       break;
   7230   }
   7231 }
   7232 
   7233 bool GLES2DecoderImpl::SetVertexAttribValue(
   7234     const char* function_name, GLuint index, const GLfloat* value) {
   7235   if (index >= state_.attrib_values.size()) {
   7236     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
   7237     return false;
   7238   }
   7239   Vec4& v = state_.attrib_values[index];
   7240   v.v[0] = value[0];
   7241   v.v[1] = value[1];
   7242   v.v[2] = value[2];
   7243   v.v[3] = value[3];
   7244   return true;
   7245 }
   7246 
   7247 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
   7248   GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
   7249   if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
   7250     glVertexAttrib1f(index, v0);
   7251   }
   7252 }
   7253 
   7254 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
   7255   GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
   7256   if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
   7257     glVertexAttrib2f(index, v0, v1);
   7258   }
   7259 }
   7260 
   7261 void GLES2DecoderImpl::DoVertexAttrib3f(
   7262     GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
   7263   GLfloat v[4] = { v0, v1, v2, 1.0f, };
   7264   if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
   7265     glVertexAttrib3f(index, v0, v1, v2);
   7266   }
   7267 }
   7268 
   7269 void GLES2DecoderImpl::DoVertexAttrib4f(
   7270     GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
   7271   GLfloat v[4] = { v0, v1, v2, v3, };
   7272   if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
   7273     glVertexAttrib4f(index, v0, v1, v2, v3);
   7274   }
   7275 }
   7276 
   7277 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
   7278   GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
   7279   if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
   7280     glVertexAttrib1fv(index, v);
   7281   }
   7282 }
   7283 
   7284 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
   7285   GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
   7286   if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
   7287     glVertexAttrib2fv(index, v);
   7288   }
   7289 }
   7290 
   7291 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
   7292   GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
   7293   if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
   7294     glVertexAttrib3fv(index, v);
   7295   }
   7296 }
   7297 
   7298 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
   7299   if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
   7300     glVertexAttrib4fv(index, v);
   7301   }
   7302 }
   7303 
   7304 error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
   7305     uint32 immediate_data_size,
   7306     const void* cmd_data) {
   7307   const gles2::cmds::VertexAttribPointer& c =
   7308       *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
   7309 
   7310   if (!state_.bound_array_buffer.get() ||
   7311       state_.bound_array_buffer->IsDeleted()) {
   7312     if (state_.vertex_attrib_manager.get() ==
   7313         state_.default_vertex_attrib_manager.get()) {
   7314       LOCAL_SET_GL_ERROR(
   7315           GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
   7316       return error::kNoError;
   7317     } else if (c.offset != 0) {
   7318       LOCAL_SET_GL_ERROR(
   7319           GL_INVALID_VALUE,
   7320           "glVertexAttribPointer", "client side arrays are not allowed");
   7321       return error::kNoError;
   7322     }
   7323   }
   7324 
   7325   GLuint indx = c.indx;
   7326   GLint size = c.size;
   7327   GLenum type = c.type;
   7328   GLboolean normalized = c.normalized;
   7329   GLsizei stride = c.stride;
   7330   GLsizei offset = c.offset;
   7331   const void* ptr = reinterpret_cast<const void*>(offset);
   7332   if (!validators_->vertex_attrib_type.IsValid(type)) {
   7333     LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
   7334     return error::kNoError;
   7335   }
   7336   if (!validators_->vertex_attrib_size.IsValid(size)) {
   7337     LOCAL_SET_GL_ERROR(
   7338         GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
   7339     return error::kNoError;
   7340   }
   7341   if (indx >= group_->max_vertex_attribs()) {
   7342     LOCAL_SET_GL_ERROR(
   7343         GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
   7344     return error::kNoError;
   7345   }
   7346   if (stride < 0) {
   7347     LOCAL_SET_GL_ERROR(
   7348         GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
   7349     return error::kNoError;
   7350   }
   7351   if (stride > 255) {
   7352     LOCAL_SET_GL_ERROR(
   7353         GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
   7354     return error::kNoError;
   7355   }
   7356   if (offset < 0) {
   7357     LOCAL_SET_GL_ERROR(
   7358         GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
   7359     return error::kNoError;
   7360   }
   7361   GLsizei component_size =
   7362       GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
   7363   // component_size must be a power of two to use & as optimized modulo.
   7364   DCHECK(GLES2Util::IsPOT(component_size));
   7365   if (offset & (component_size - 1)) {
   7366     LOCAL_SET_GL_ERROR(
   7367         GL_INVALID_OPERATION,
   7368         "glVertexAttribPointer", "offset not valid for type");
   7369     return error::kNoError;
   7370   }
   7371   if (stride & (component_size - 1)) {
   7372     LOCAL_SET_GL_ERROR(
   7373         GL_INVALID_OPERATION,
   7374         "glVertexAttribPointer", "stride not valid for type");
   7375     return error::kNoError;
   7376   }
   7377   state_.vertex_attrib_manager
   7378       ->SetAttribInfo(indx,
   7379                       state_.bound_array_buffer.get(),
   7380                       size,
   7381                       type,
   7382                       normalized,
   7383                       stride,
   7384                       stride != 0 ? stride : component_size * size,
   7385                       offset);
   7386   if (type != GL_FIXED) {
   7387     glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
   7388   }
   7389   return error::kNoError;
   7390 }
   7391 
   7392 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
   7393                                   GLsizei height) {
   7394   state_.viewport_x = x;
   7395   state_.viewport_y = y;
   7396   state_.viewport_width = std::min(width, viewport_max_width_);
   7397   state_.viewport_height = std::min(height, viewport_max_height_);
   7398   glViewport(x, y, width, height);
   7399 }
   7400 
   7401 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
   7402     uint32 immediate_data_size,
   7403     const void* cmd_data) {
   7404   const gles2::cmds::VertexAttribDivisorANGLE& c =
   7405       *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
   7406   if (!features().angle_instanced_arrays) {
   7407     LOCAL_SET_GL_ERROR(
   7408         GL_INVALID_OPERATION,
   7409         "glVertexAttribDivisorANGLE", "function not available");
   7410     return error::kNoError;
   7411   }
   7412   GLuint index = c.index;
   7413   GLuint divisor = c.divisor;
   7414   if (index >= group_->max_vertex_attribs()) {
   7415     LOCAL_SET_GL_ERROR(
   7416         GL_INVALID_VALUE,
   7417         "glVertexAttribDivisorANGLE", "index out of range");
   7418     return error::kNoError;
   7419   }
   7420 
   7421   state_.vertex_attrib_manager->SetDivisor(
   7422       index,
   7423       divisor);
   7424   glVertexAttribDivisorANGLE(index, divisor);
   7425   return error::kNoError;
   7426 }
   7427 
   7428 template <typename pixel_data_type>
   7429 static void WriteAlphaData(
   7430     void *pixels, uint32 row_count, uint32 channel_count,
   7431     uint32 alpha_channel_index, uint32 unpadded_row_size,
   7432     uint32 padded_row_size, pixel_data_type alpha_value) {
   7433   DCHECK_GT(channel_count, 0U);
   7434   DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
   7435   uint32 unpadded_row_size_in_elements =
   7436       unpadded_row_size / sizeof(pixel_data_type);
   7437   DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
   7438   uint32 padded_row_size_in_elements =
   7439       padded_row_size / sizeof(pixel_data_type);
   7440   pixel_data_type* dst =
   7441       static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
   7442   for (uint32 yy = 0; yy < row_count; ++yy) {
   7443     pixel_data_type* end = dst + unpadded_row_size_in_elements;
   7444     for (pixel_data_type* d = dst; d < end; d += channel_count) {
   7445       *d = alpha_value;
   7446     }
   7447     dst += padded_row_size_in_elements;
   7448   }
   7449 }
   7450 
   7451 void GLES2DecoderImpl::FinishReadPixels(
   7452     const cmds::ReadPixels& c,
   7453     GLuint buffer) {
   7454   TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
   7455   GLsizei width = c.width;
   7456   GLsizei height = c.height;
   7457   GLenum format = c.format;
   7458   GLenum type = c.type;
   7459   typedef cmds::ReadPixels::Result Result;
   7460   uint32 pixels_size;
   7461   Result* result = NULL;
   7462   if (c.result_shm_id != 0) {
   7463     result = GetSharedMemoryAs<Result*>(
   7464         c.result_shm_id, c.result_shm_offset, sizeof(*result));
   7465     if (!result) {
   7466       if (buffer != 0) {
   7467         glDeleteBuffersARB(1, &buffer);
   7468       }
   7469       return;
   7470     }
   7471   }
   7472   GLES2Util::ComputeImageDataSizes(
   7473       width, height, format, type, state_.pack_alignment, &pixels_size,
   7474       NULL, NULL);
   7475   void* pixels = GetSharedMemoryAs<void*>(
   7476       c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
   7477   if (!pixels) {
   7478     if (buffer != 0) {
   7479       glDeleteBuffersARB(1, &buffer);
   7480     }
   7481     return;
   7482   }
   7483 
   7484   if (buffer != 0) {
   7485     glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
   7486     void* data;
   7487     if (features().map_buffer_range) {
   7488       data = glMapBufferRange(
   7489           GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
   7490     } else {
   7491       data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
   7492     }
   7493     memcpy(pixels, data, pixels_size);
   7494     // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
   7495     // have to restore the state.
   7496     glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
   7497     glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
   7498     glDeleteBuffersARB(1, &buffer);
   7499   }
   7500 
   7501   if (result != NULL) {
   7502     *result = true;
   7503   }
   7504 
   7505   GLenum read_format = GetBoundReadFrameBufferInternalFormat();
   7506   uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
   7507   if ((channels_exist & 0x0008) == 0 &&
   7508       workarounds().clear_alpha_in_readpixels) {
   7509     // Set the alpha to 255 because some drivers are buggy in this regard.
   7510     uint32 temp_size;
   7511 
   7512     uint32 unpadded_row_size;
   7513     uint32 padded_row_size;
   7514     if (!GLES2Util::ComputeImageDataSizes(
   7515             width, 2, format, type, state_.pack_alignment, &temp_size,
   7516             &unpadded_row_size, &padded_row_size)) {
   7517       return;
   7518     }
   7519 
   7520     uint32 channel_count = 0;
   7521     uint32 alpha_channel = 0;
   7522     switch (format) {
   7523       case GL_RGBA:
   7524       case GL_BGRA_EXT:
   7525         channel_count = 4;
   7526         alpha_channel = 3;
   7527         break;
   7528       case GL_ALPHA:
   7529         channel_count = 1;
   7530         alpha_channel = 0;
   7531         break;
   7532     }
   7533 
   7534     if (channel_count > 0) {
   7535       switch (type) {
   7536         case GL_UNSIGNED_BYTE:
   7537           WriteAlphaData<uint8>(
   7538               pixels, height, channel_count, alpha_channel, unpadded_row_size,
   7539               padded_row_size, 0xFF);
   7540           break;
   7541         case GL_FLOAT:
   7542           WriteAlphaData<float>(
   7543               pixels, height, channel_count, alpha_channel, unpadded_row_size,
   7544               padded_row_size, 1.0f);
   7545           break;
   7546         case GL_HALF_FLOAT:
   7547           WriteAlphaData<uint16>(
   7548               pixels, height, channel_count, alpha_channel, unpadded_row_size,
   7549               padded_row_size, 0x3C00);
   7550           break;
   7551       }
   7552     }
   7553   }
   7554 }
   7555 
   7556 error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
   7557                                                 const void* cmd_data) {
   7558   const gles2::cmds::ReadPixels& c =
   7559       *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
   7560   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
   7561   error::Error fbo_error = WillAccessBoundFramebufferForRead();
   7562   if (fbo_error != error::kNoError)
   7563     return fbo_error;
   7564   GLint x = c.x;
   7565   GLint y = c.y;
   7566   GLsizei width = c.width;
   7567   GLsizei height = c.height;
   7568   GLenum format = c.format;
   7569   GLenum type = c.type;
   7570   GLboolean async = c.async;
   7571   if (width < 0 || height < 0) {
   7572     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
   7573     return error::kNoError;
   7574   }
   7575   typedef cmds::ReadPixels::Result Result;
   7576   uint32 pixels_size;
   7577   if (!GLES2Util::ComputeImageDataSizes(
   7578       width, height, format, type, state_.pack_alignment, &pixels_size,
   7579       NULL, NULL)) {
   7580     return error::kOutOfBounds;
   7581   }
   7582   void* pixels = GetSharedMemoryAs<void*>(
   7583       c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
   7584   if (!pixels) {
   7585     return error::kOutOfBounds;
   7586   }
   7587   Result* result = NULL;
   7588   if (c.result_shm_id != 0) {
   7589     result = GetSharedMemoryAs<Result*>(
   7590         c.result_shm_id, c.result_shm_offset, sizeof(*result));
   7591     if (!result) {
   7592       return error::kOutOfBounds;
   7593     }
   7594   }
   7595 
   7596   if (!validators_->read_pixel_format.IsValid(format)) {
   7597     LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
   7598     return error::kNoError;
   7599   }
   7600   if (!validators_->read_pixel_type.IsValid(type)) {
   7601     LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
   7602     return error::kNoError;
   7603   }
   7604   if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
   7605       format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
   7606     // format and type are acceptable enums but not guaranteed to be supported
   7607     // for this framebuffer.  Have to ask gl if they are valid.
   7608     GLint preferred_format = 0;
   7609     DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
   7610     GLint preferred_type = 0;
   7611     DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
   7612     if (format != static_cast<GLenum>(preferred_format) ||
   7613         type != static_cast<GLenum>(preferred_type)) {
   7614       LOCAL_SET_GL_ERROR(
   7615           GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
   7616           "with the current read framebuffer");
   7617       return error::kNoError;
   7618     }
   7619   }
   7620   if (width == 0 || height == 0) {
   7621     return error::kNoError;
   7622   }
   7623 
   7624   // Get the size of the current fbo or backbuffer.
   7625   gfx::Size max_size = GetBoundReadFrameBufferSize();
   7626 
   7627   int32 max_x;
   7628   int32 max_y;
   7629   if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
   7630     LOCAL_SET_GL_ERROR(
   7631         GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
   7632     return error::kNoError;
   7633   }
   7634 
   7635   if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
   7636     return error::kNoError;
   7637   }
   7638 
   7639   if (!CheckBoundFramebuffersValid("glReadPixels")) {
   7640     return error::kNoError;
   7641   }
   7642 
   7643   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
   7644 
   7645   ScopedResolvedFrameBufferBinder binder(this, false, true);
   7646 
   7647   if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
   7648     // The user requested an out of range area. Get the results 1 line
   7649     // at a time.
   7650     uint32 temp_size;
   7651     uint32 unpadded_row_size;
   7652     uint32 padded_row_size;
   7653     if (!GLES2Util::ComputeImageDataSizes(
   7654         width, 2, format, type, state_.pack_alignment, &temp_size,
   7655         &unpadded_row_size, &padded_row_size)) {
   7656       LOCAL_SET_GL_ERROR(
   7657           GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
   7658       return error::kNoError;
   7659     }
   7660 
   7661     GLint dest_x_offset = std::max(-x, 0);
   7662     uint32 dest_row_offset;
   7663     if (!GLES2Util::ComputeImageDataSizes(
   7664         dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
   7665         NULL, NULL)) {
   7666       LOCAL_SET_GL_ERROR(
   7667           GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
   7668       return error::kNoError;
   7669     }
   7670 
   7671     // Copy each row into the larger dest rect.
   7672     int8* dst = static_cast<int8*>(pixels);
   7673     GLint read_x = std::max(0, x);
   7674     GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
   7675     GLint read_width = read_end_x - read_x;
   7676     for (GLint yy = 0; yy < height; ++yy) {
   7677       GLint ry = y + yy;
   7678 
   7679       // Clear the row.
   7680       memset(dst, 0, unpadded_row_size);
   7681 
   7682       // If the row is in range, copy it.
   7683       if (ry >= 0 && ry < max_size.height() && read_width > 0) {
   7684         glReadPixels(
   7685             read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
   7686       }
   7687       dst += padded_row_size;
   7688     }
   7689   } else {
   7690     if (async && features().use_async_readpixels) {
   7691       GLuint buffer;
   7692       glGenBuffersARB(1, &buffer);
   7693       glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
   7694       glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
   7695       GLenum error = glGetError();
   7696       if (error == GL_NO_ERROR) {
   7697         glReadPixels(x, y, width, height, format, type, 0);
   7698         pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
   7699             new FenceCallback()));
   7700         WaitForReadPixels(base::Bind(
   7701             &GLES2DecoderImpl::FinishReadPixels,
   7702             base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
   7703             <GLES2DecoderImpl>(this),
   7704             c, buffer));
   7705         glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
   7706         return error::kNoError;
   7707       } else {
   7708         // On error, unbind pack buffer and fall through to sync readpixels
   7709         glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
   7710       }
   7711     }
   7712     glReadPixels(x, y, width, height, format, type, pixels);
   7713   }
   7714   GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
   7715   if (error == GL_NO_ERROR) {
   7716     if (result != NULL) {
   7717       *result = true;
   7718     }
   7719     FinishReadPixels(c, 0);
   7720   }
   7721 
   7722   return error::kNoError;
   7723 }
   7724 
   7725 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
   7726                                                  const void* cmd_data) {
   7727   const gles2::cmds::PixelStorei& c =
   7728       *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
   7729   GLenum pname = c.pname;
   7730   GLenum param = c.param;
   7731   if (!validators_->pixel_store.IsValid(pname)) {
   7732     LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
   7733     return error::kNoError;
   7734   }
   7735   switch (pname) {
   7736     case GL_PACK_ALIGNMENT:
   7737     case GL_UNPACK_ALIGNMENT:
   7738         if (!validators_->pixel_store_alignment.IsValid(param)) {
   7739             LOCAL_SET_GL_ERROR(
   7740                 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
   7741             return error::kNoError;
   7742         }
   7743         break;
   7744     case GL_UNPACK_FLIP_Y_CHROMIUM:
   7745         unpack_flip_y_ = (param != 0);
   7746         return error::kNoError;
   7747     case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
   7748         unpack_premultiply_alpha_ = (param != 0);
   7749         return error::kNoError;
   7750     case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
   7751         unpack_unpremultiply_alpha_ = (param != 0);
   7752         return error::kNoError;
   7753     default:
   7754         break;
   7755   }
   7756   glPixelStorei(pname, param);
   7757   switch (pname) {
   7758     case GL_PACK_ALIGNMENT:
   7759         state_.pack_alignment = param;
   7760         break;
   7761     case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   7762         state_.pack_reverse_row_order = (param != 0);
   7763         break;
   7764     case GL_UNPACK_ALIGNMENT:
   7765         state_.unpack_alignment = param;
   7766         break;
   7767     default:
   7768         // Validation should have prevented us from getting here.
   7769         NOTREACHED();
   7770         break;
   7771   }
   7772   return error::kNoError;
   7773 }
   7774 
   7775 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
   7776     uint32 immediate_data_size,
   7777     const void* cmd_data) {
   7778   const gles2::cmds::PostSubBufferCHROMIUM& c =
   7779       *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
   7780   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
   7781   {
   7782     TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
   7783   }
   7784   if (!supports_post_sub_buffer_) {
   7785     LOCAL_SET_GL_ERROR(
   7786         GL_INVALID_OPERATION,
   7787         "glPostSubBufferCHROMIUM", "command not supported by surface");
   7788     return error::kNoError;
   7789   }
   7790   bool is_tracing;
   7791   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
   7792                                      &is_tracing);
   7793   if (is_tracing) {
   7794     bool is_offscreen = !!offscreen_target_frame_buffer_.get();
   7795     ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
   7796     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
   7797         is_offscreen ? offscreen_size_ : surface_->GetSize());
   7798   }
   7799   if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
   7800     return error::kNoError;
   7801   } else {
   7802     LOG(ERROR) << "Context lost because PostSubBuffer failed.";
   7803     return error::kLostContext;
   7804   }
   7805 }
   7806 
   7807 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
   7808     uint32 immediate_data_size,
   7809     const void* cmd_data) {
   7810   const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
   7811       *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
   7812   TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
   7813   if (!ref) {
   7814     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
   7815                        "glScheduleOverlayPlaneCHROMIUM",
   7816                        "unknown texture");
   7817     return error::kNoError;
   7818   }
   7819   gfx::GLImage* image =
   7820       ref->texture()->GetLevelImage(ref->texture()->target(), 0);
   7821   if (!image) {
   7822     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
   7823                        "glScheduleOverlayPlaneCHROMIUM",
   7824                        "unsupported texture format");
   7825     return error::kNoError;
   7826   }
   7827   gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
   7828   if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
   7829     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
   7830                        "glScheduleOverlayPlaneCHROMIUM",
   7831                        "invalid transform enum");
   7832     return error::kNoError;
   7833   }
   7834   if (!surface_->ScheduleOverlayPlane(
   7835           c.plane_z_order,
   7836           transform,
   7837           image,
   7838           gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
   7839           gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
   7840     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   7841                        "glScheduleOverlayPlaneCHROMIUM",
   7842                        "failed to schedule overlay");
   7843   }
   7844   return error::kNoError;
   7845 }
   7846 
   7847 error::Error GLES2DecoderImpl::GetAttribLocationHelper(
   7848     GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
   7849     const std::string& name_str) {
   7850   if (!StringIsValidForGLES(name_str.c_str())) {
   7851     LOCAL_SET_GL_ERROR(
   7852         GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
   7853     return error::kNoError;
   7854   }
   7855   Program* program = GetProgramInfoNotShader(
   7856       client_id, "glGetAttribLocation");
   7857   if (!program) {
   7858     return error::kNoError;
   7859   }
   7860   if (!program->IsValid()) {
   7861     LOCAL_SET_GL_ERROR(
   7862         GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
   7863     return error::kNoError;
   7864   }
   7865   GLint* location = GetSharedMemoryAs<GLint*>(
   7866       location_shm_id, location_shm_offset, sizeof(GLint));
   7867   if (!location) {
   7868     return error::kOutOfBounds;
   7869   }
   7870   // Require the client to init this incase the context is lost and we are no
   7871   // longer executing commands.
   7872   if (*location != -1) {
   7873     return error::kGenericError;
   7874   }
   7875   *location = program->GetAttribLocation(name_str);
   7876   return error::kNoError;
   7877 }
   7878 
   7879 error::Error GLES2DecoderImpl::HandleGetAttribLocation(
   7880     uint32 immediate_data_size,
   7881     const void* cmd_data) {
   7882   const gles2::cmds::GetAttribLocation& c =
   7883       *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
   7884   Bucket* bucket = GetBucket(c.name_bucket_id);
   7885   if (!bucket) {
   7886     return error::kInvalidArguments;
   7887   }
   7888   std::string name_str;
   7889   if (!bucket->GetAsString(&name_str)) {
   7890     return error::kInvalidArguments;
   7891   }
   7892   return GetAttribLocationHelper(
   7893     c.program, c.location_shm_id, c.location_shm_offset, name_str);
   7894 }
   7895 
   7896 error::Error GLES2DecoderImpl::GetUniformLocationHelper(
   7897     GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
   7898     const std::string& name_str) {
   7899   if (!StringIsValidForGLES(name_str.c_str())) {
   7900     LOCAL_SET_GL_ERROR(
   7901         GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
   7902     return error::kNoError;
   7903   }
   7904   Program* program = GetProgramInfoNotShader(
   7905       client_id, "glGetUniformLocation");
   7906   if (!program) {
   7907     return error::kNoError;
   7908   }
   7909   if (!program->IsValid()) {
   7910     LOCAL_SET_GL_ERROR(
   7911         GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
   7912     return error::kNoError;
   7913   }
   7914   GLint* location = GetSharedMemoryAs<GLint*>(
   7915       location_shm_id, location_shm_offset, sizeof(GLint));
   7916   if (!location) {
   7917     return error::kOutOfBounds;
   7918   }
   7919   // Require the client to init this incase the context is lost an we are no
   7920   // longer executing commands.
   7921   if (*location != -1) {
   7922     return error::kGenericError;
   7923   }
   7924   *location = program->GetUniformFakeLocation(name_str);
   7925   return error::kNoError;
   7926 }
   7927 
   7928 error::Error GLES2DecoderImpl::HandleGetUniformLocation(
   7929     uint32 immediate_data_size,
   7930     const void* cmd_data) {
   7931   const gles2::cmds::GetUniformLocation& c =
   7932       *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
   7933   Bucket* bucket = GetBucket(c.name_bucket_id);
   7934   if (!bucket) {
   7935     return error::kInvalidArguments;
   7936   }
   7937   std::string name_str;
   7938   if (!bucket->GetAsString(&name_str)) {
   7939     return error::kInvalidArguments;
   7940   }
   7941   return GetUniformLocationHelper(
   7942     c.program, c.location_shm_id, c.location_shm_offset, name_str);
   7943 }
   7944 
   7945 error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
   7946                                                const void* cmd_data) {
   7947   const gles2::cmds::GetString& c =
   7948       *static_cast<const gles2::cmds::GetString*>(cmd_data);
   7949   GLenum name = static_cast<GLenum>(c.name);
   7950   if (!validators_->string_type.IsValid(name)) {
   7951     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
   7952     return error::kNoError;
   7953   }
   7954   const char* str = reinterpret_cast<const char*>(glGetString(name));
   7955   std::string extensions;
   7956   switch (name) {
   7957     case GL_VERSION:
   7958       str = "OpenGL ES 2.0 Chromium";
   7959       break;
   7960     case GL_SHADING_LANGUAGE_VERSION:
   7961       str = "OpenGL ES GLSL ES 1.0 Chromium";
   7962       break;
   7963     case GL_RENDERER:
   7964     case GL_VENDOR:
   7965       // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
   7966       // They are used by WEBGL_debug_renderer_info.
   7967       if (!force_webgl_glsl_validation_)
   7968         str = "Chromium";
   7969       break;
   7970     case GL_EXTENSIONS:
   7971       {
   7972         // For WebGL contexts, strip out the OES derivatives and
   7973         // EXT frag depth extensions if they have not been enabled.
   7974         if (force_webgl_glsl_validation_) {
   7975           extensions = feature_info_->extensions();
   7976           if (!derivatives_explicitly_enabled_) {
   7977             size_t offset = extensions.find(kOESDerivativeExtension);
   7978             if (std::string::npos != offset) {
   7979               extensions.replace(offset, arraysize(kOESDerivativeExtension),
   7980                                  std::string());
   7981             }
   7982           }
   7983           if (!frag_depth_explicitly_enabled_) {
   7984             size_t offset = extensions.find(kEXTFragDepthExtension);
   7985             if (std::string::npos != offset) {
   7986               extensions.replace(offset, arraysize(kEXTFragDepthExtension),
   7987                                  std::string());
   7988             }
   7989           }
   7990           if (!draw_buffers_explicitly_enabled_) {
   7991             size_t offset = extensions.find(kEXTDrawBuffersExtension);
   7992             if (std::string::npos != offset) {
   7993               extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
   7994                                  std::string());
   7995             }
   7996           }
   7997           if (!shader_texture_lod_explicitly_enabled_) {
   7998             size_t offset = extensions.find(kEXTShaderTextureLodExtension);
   7999             if (std::string::npos != offset) {
   8000               extensions.replace(offset,
   8001                                  arraysize(kEXTShaderTextureLodExtension),
   8002                                  std::string());
   8003             }
   8004           }
   8005         } else {
   8006           extensions = feature_info_->extensions().c_str();
   8007         }
   8008         if (supports_post_sub_buffer_)
   8009           extensions += " GL_CHROMIUM_post_sub_buffer";
   8010         str = extensions.c_str();
   8011       }
   8012       break;
   8013     default:
   8014       break;
   8015   }
   8016   Bucket* bucket = CreateBucket(c.bucket_id);
   8017   bucket->SetFromString(str);
   8018   return error::kNoError;
   8019 }
   8020 
   8021 error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
   8022                                                 const void* cmd_data) {
   8023   const gles2::cmds::BufferData& c =
   8024       *static_cast<const gles2::cmds::BufferData*>(cmd_data);
   8025   GLenum target = static_cast<GLenum>(c.target);
   8026   GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
   8027   uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
   8028   uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
   8029   GLenum usage = static_cast<GLenum>(c.usage);
   8030   const void* data = NULL;
   8031   if (data_shm_id != 0 || data_shm_offset != 0) {
   8032     data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
   8033     if (!data) {
   8034       return error::kOutOfBounds;
   8035     }
   8036   }
   8037   buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
   8038   return error::kNoError;
   8039 }
   8040 
   8041 void GLES2DecoderImpl::DoBufferSubData(
   8042   GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
   8043   // Just delegate it. Some validation is actually done before this.
   8044   buffer_manager()->ValidateAndDoBufferSubData(
   8045       &state_, target, offset, size, data);
   8046 }
   8047 
   8048 bool GLES2DecoderImpl::ClearLevel(
   8049     unsigned service_id,
   8050     unsigned bind_target,
   8051     unsigned target,
   8052     int level,
   8053     unsigned internal_format,
   8054     unsigned format,
   8055     unsigned type,
   8056     int width,
   8057     int height,
   8058     bool is_texture_immutable) {
   8059   uint32 channels = GLES2Util::GetChannelsForFormat(format);
   8060   if (feature_info_->feature_flags().angle_depth_texture &&
   8061       (channels & GLES2Util::kDepth) != 0) {
   8062     // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
   8063     // on depth formats.
   8064     GLuint fb = 0;
   8065     glGenFramebuffersEXT(1, &fb);
   8066     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
   8067 
   8068     bool have_stencil = (channels & GLES2Util::kStencil) != 0;
   8069     GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
   8070                                        GL_DEPTH_ATTACHMENT;
   8071 
   8072     glFramebufferTexture2DEXT(
   8073         GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
   8074     // ANGLE promises a depth only attachment ok.
   8075     if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
   8076         GL_FRAMEBUFFER_COMPLETE) {
   8077       return false;
   8078     }
   8079     glClearStencil(0);
   8080     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
   8081     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
   8082     glClearDepth(1.0f);
   8083     state_.SetDeviceDepthMask(GL_TRUE);
   8084     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   8085     glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
   8086 
   8087     RestoreClearState();
   8088 
   8089     glDeleteFramebuffersEXT(1, &fb);
   8090     Framebuffer* framebuffer =
   8091         GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
   8092     GLuint fb_service_id =
   8093         framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
   8094     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
   8095     return true;
   8096   }
   8097 
   8098   static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
   8099 
   8100   uint32 size;
   8101   uint32 padded_row_size;
   8102   if (!GLES2Util::ComputeImageDataSizes(
   8103           width, height, format, type, state_.unpack_alignment, &size,
   8104           NULL, &padded_row_size)) {
   8105     return false;
   8106   }
   8107 
   8108   TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
   8109 
   8110   int tile_height;
   8111 
   8112   if (size > kMaxZeroSize) {
   8113     if (kMaxZeroSize < padded_row_size) {
   8114         // That'd be an awfully large texture.
   8115         return false;
   8116     }
   8117     // We should never have a large total size with a zero row size.
   8118     DCHECK_GT(padded_row_size, 0U);
   8119     tile_height = kMaxZeroSize / padded_row_size;
   8120     if (!GLES2Util::ComputeImageDataSizes(
   8121             width, tile_height, format, type, state_.unpack_alignment, &size,
   8122             NULL, NULL)) {
   8123       return false;
   8124     }
   8125   } else {
   8126     tile_height = height;
   8127   }
   8128 
   8129   // Assumes the size has already been checked.
   8130   scoped_ptr<char[]> zero(new char[size]);
   8131   memset(zero.get(), 0, size);
   8132   glBindTexture(bind_target, service_id);
   8133 
   8134   GLint y = 0;
   8135   while (y < height) {
   8136     GLint h = y + tile_height > height ? height - y : tile_height;
   8137     if (is_texture_immutable || h != height) {
   8138       glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
   8139     } else {
   8140       glTexImage2D(
   8141           target, level, internal_format, width, h, 0, format, type,
   8142           zero.get());
   8143     }
   8144     y += tile_height;
   8145   }
   8146   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
   8147       &state_, bind_target);
   8148   glBindTexture(bind_target, texture ? texture->service_id() : 0);
   8149   return true;
   8150 }
   8151 
   8152 namespace {
   8153 
   8154 const int kS3TCBlockWidth = 4;
   8155 const int kS3TCBlockHeight = 4;
   8156 const int kS3TCDXT1BlockSize = 8;
   8157 const int kS3TCDXT3AndDXT5BlockSize = 16;
   8158 
   8159 bool IsValidDXTSize(GLint level, GLsizei size) {
   8160   return (size == 1) ||
   8161          (size == 2) || !(size % kS3TCBlockWidth);
   8162 }
   8163 
   8164 bool IsValidPVRTCSize(GLint level, GLsizei size) {
   8165   return GLES2Util::IsPOT(size);
   8166 }
   8167 
   8168 }  // anonymous namespace.
   8169 
   8170 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
   8171     const char* function_name,
   8172     GLsizei width, GLsizei height, GLenum format, size_t size) {
   8173   unsigned int bytes_required = 0;
   8174 
   8175   switch (format) {
   8176     case GL_ATC_RGB_AMD:
   8177     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   8178     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   8179     case GL_ETC1_RGB8_OES: {
   8180         int num_blocks_across =
   8181             (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
   8182         int num_blocks_down =
   8183             (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
   8184         int num_blocks = num_blocks_across * num_blocks_down;
   8185         bytes_required = num_blocks * kS3TCDXT1BlockSize;
   8186         break;
   8187       }
   8188     case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
   8189     case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
   8190     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   8191     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
   8192         int num_blocks_across =
   8193             (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
   8194         int num_blocks_down =
   8195             (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
   8196         int num_blocks = num_blocks_across * num_blocks_down;
   8197         bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
   8198         break;
   8199       }
   8200     case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
   8201     case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
   8202         bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
   8203         break;
   8204       }
   8205     case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
   8206     case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
   8207         bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
   8208         break;
   8209       }
   8210     default:
   8211       LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
   8212       return false;
   8213   }
   8214 
   8215   if (size != bytes_required) {
   8216     LOCAL_SET_GL_ERROR(
   8217         GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
   8218     return false;
   8219   }
   8220 
   8221   return true;
   8222 }
   8223 
   8224 bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
   8225     const char* function_name,
   8226     GLint level, GLsizei width, GLsizei height, GLenum format) {
   8227   switch (format) {
   8228     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   8229     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   8230     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   8231     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
   8232       if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
   8233         LOCAL_SET_GL_ERROR(
   8234             GL_INVALID_OPERATION, function_name,
   8235             "width or height invalid for level");
   8236         return false;
   8237       }
   8238       return true;
   8239     }
   8240     case GL_ATC_RGB_AMD:
   8241     case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
   8242     case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
   8243     case GL_ETC1_RGB8_OES: {
   8244       if (width <= 0 || height <= 0) {
   8245         LOCAL_SET_GL_ERROR(
   8246             GL_INVALID_OPERATION, function_name,
   8247             "width or height invalid for level");
   8248         return false;
   8249       }
   8250       return true;
   8251     }
   8252     case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
   8253     case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
   8254     case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
   8255     case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
   8256       if (!IsValidPVRTCSize(level, width) ||
   8257           !IsValidPVRTCSize(level, height)) {
   8258         LOCAL_SET_GL_ERROR(
   8259             GL_INVALID_OPERATION, function_name,
   8260             "width or height invalid for level");
   8261         return false;
   8262       }
   8263       return true;
   8264     }
   8265     default:
   8266       return false;
   8267   }
   8268 }
   8269 
   8270 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
   8271     const char* function_name,
   8272     GLenum target, GLint level, GLint xoffset, GLint yoffset,
   8273     GLsizei width, GLsizei height, GLenum format,
   8274     Texture* texture) {
   8275   if (xoffset < 0 || yoffset < 0) {
   8276     LOCAL_SET_GL_ERROR(
   8277         GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
   8278     return false;
   8279   }
   8280 
   8281   switch (format) {
   8282     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   8283     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   8284     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   8285     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
   8286       const int kBlockWidth = 4;
   8287       const int kBlockHeight = 4;
   8288       if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
   8289         LOCAL_SET_GL_ERROR(
   8290             GL_INVALID_OPERATION, function_name,
   8291             "xoffset or yoffset not multiple of 4");
   8292         return false;
   8293       }
   8294       GLsizei tex_width = 0;
   8295       GLsizei tex_height = 0;
   8296       if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
   8297           width - xoffset > tex_width ||
   8298           height - yoffset > tex_height) {
   8299         LOCAL_SET_GL_ERROR(
   8300             GL_INVALID_OPERATION, function_name, "dimensions out of range");
   8301         return false;
   8302       }
   8303       return ValidateCompressedTexDimensions(
   8304           function_name, level, width, height, format);
   8305     }
   8306     case GL_ATC_RGB_AMD:
   8307     case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
   8308     case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
   8309       LOCAL_SET_GL_ERROR(
   8310           GL_INVALID_OPERATION, function_name,
   8311           "not supported for ATC textures");
   8312       return false;
   8313     }
   8314     case GL_ETC1_RGB8_OES: {
   8315       LOCAL_SET_GL_ERROR(
   8316           GL_INVALID_OPERATION, function_name,
   8317           "not supported for ECT1_RGB8_OES textures");
   8318       return false;
   8319     }
   8320     case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
   8321     case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
   8322     case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
   8323     case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
   8324       if ((xoffset != 0) || (yoffset != 0)) {
   8325         LOCAL_SET_GL_ERROR(
   8326             GL_INVALID_OPERATION, function_name,
   8327             "xoffset and yoffset must be zero");
   8328         return false;
   8329       }
   8330       GLsizei tex_width = 0;
   8331       GLsizei tex_height = 0;
   8332       if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
   8333           width != tex_width ||
   8334           height != tex_height) {
   8335         LOCAL_SET_GL_ERROR(
   8336             GL_INVALID_OPERATION, function_name,
   8337             "dimensions must match existing texture level dimensions");
   8338         return false;
   8339       }
   8340       return ValidateCompressedTexDimensions(
   8341           function_name, level, width, height, format);
   8342     }
   8343     default:
   8344       return false;
   8345   }
   8346 }
   8347 
   8348 error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
   8349   GLenum target,
   8350   GLint level,
   8351   GLenum internal_format,
   8352   GLsizei width,
   8353   GLsizei height,
   8354   GLint border,
   8355   GLsizei image_size,
   8356   const void* data) {
   8357   // TODO(gman): Validate image_size is correct for width, height and format.
   8358   if (!validators_->texture_target.IsValid(target)) {
   8359     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   8360         "glCompressedTexImage2D", target, "target");
   8361     return error::kNoError;
   8362   }
   8363   if (!validators_->compressed_texture_format.IsValid(
   8364       internal_format)) {
   8365     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   8366         "glCompressedTexImage2D", internal_format, "internal_format");
   8367     return error::kNoError;
   8368   }
   8369   if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
   8370       border != 0) {
   8371     LOCAL_SET_GL_ERROR(
   8372         GL_INVALID_VALUE,
   8373         "glCompressedTexImage2D", "dimensions out of range");
   8374     return error::kNoError;
   8375   }
   8376   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8377       &state_, target);
   8378   if (!texture_ref) {
   8379     LOCAL_SET_GL_ERROR(
   8380         GL_INVALID_VALUE,
   8381         "glCompressedTexImage2D", "unknown texture target");
   8382     return error::kNoError;
   8383   }
   8384   Texture* texture = texture_ref->texture();
   8385   if (texture->IsImmutable()) {
   8386     LOCAL_SET_GL_ERROR(
   8387         GL_INVALID_OPERATION,
   8388         "glCompressedTexImage2D", "texture is immutable");
   8389     return error::kNoError;
   8390   }
   8391 
   8392   if (!ValidateCompressedTexDimensions(
   8393       "glCompressedTexImage2D", level, width, height, internal_format) ||
   8394       !ValidateCompressedTexFuncData(
   8395       "glCompressedTexImage2D", width, height, internal_format, image_size)) {
   8396     return error::kNoError;
   8397   }
   8398 
   8399   if (!EnsureGPUMemoryAvailable(image_size)) {
   8400     LOCAL_SET_GL_ERROR(
   8401         GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
   8402     return error::kNoError;
   8403   }
   8404 
   8405   if (texture->IsAttachedToFramebuffer()) {
   8406     framebuffer_state_.clear_state_dirty = true;
   8407   }
   8408 
   8409   scoped_ptr<int8[]> zero;
   8410   if (!data) {
   8411     zero.reset(new int8[image_size]);
   8412     memset(zero.get(), 0, image_size);
   8413     data = zero.get();
   8414   }
   8415   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
   8416   glCompressedTexImage2D(
   8417       target, level, internal_format, width, height, border, image_size, data);
   8418   GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
   8419   if (error == GL_NO_ERROR) {
   8420     texture_manager()->SetLevelInfo(
   8421         texture_ref, target, level, internal_format,
   8422         width, height, 1, border, 0, 0, true);
   8423   }
   8424 
   8425   // This may be a slow command.  Exit command processing to allow for
   8426   // context preemption and GPU watchdog checks.
   8427   ExitCommandProcessingEarly();
   8428   return error::kNoError;
   8429 }
   8430 
   8431 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
   8432     uint32 immediate_data_size,
   8433     const void* cmd_data) {
   8434   const gles2::cmds::CompressedTexImage2D& c =
   8435       *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
   8436   GLenum target = static_cast<GLenum>(c.target);
   8437   GLint level = static_cast<GLint>(c.level);
   8438   GLenum internal_format = static_cast<GLenum>(c.internalformat);
   8439   GLsizei width = static_cast<GLsizei>(c.width);
   8440   GLsizei height = static_cast<GLsizei>(c.height);
   8441   GLint border = static_cast<GLint>(c.border);
   8442   GLsizei image_size = static_cast<GLsizei>(c.imageSize);
   8443   uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
   8444   uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
   8445   const void* data = NULL;
   8446   if (data_shm_id != 0 || data_shm_offset != 0) {
   8447     data = GetSharedMemoryAs<const void*>(
   8448         data_shm_id, data_shm_offset, image_size);
   8449     if (!data) {
   8450       return error::kOutOfBounds;
   8451     }
   8452   }
   8453   return DoCompressedTexImage2D(
   8454       target, level, internal_format, width, height, border, image_size, data);
   8455 }
   8456 
   8457 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
   8458     uint32 immediate_data_size,
   8459     const void* cmd_data) {
   8460   const gles2::cmds::CompressedTexImage2DBucket& c =
   8461       *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
   8462   GLenum target = static_cast<GLenum>(c.target);
   8463   GLint level = static_cast<GLint>(c.level);
   8464   GLenum internal_format = static_cast<GLenum>(c.internalformat);
   8465   GLsizei width = static_cast<GLsizei>(c.width);
   8466   GLsizei height = static_cast<GLsizei>(c.height);
   8467   GLint border = static_cast<GLint>(c.border);
   8468   Bucket* bucket = GetBucket(c.bucket_id);
   8469   if (!bucket) {
   8470     return error::kInvalidArguments;
   8471   }
   8472   uint32 data_size = bucket->size();
   8473   GLsizei imageSize = data_size;
   8474   const void* data = bucket->GetData(0, data_size);
   8475   if (!data) {
   8476     return error::kInvalidArguments;
   8477   }
   8478   return DoCompressedTexImage2D(
   8479       target, level, internal_format, width, height, border,
   8480       imageSize, data);
   8481 }
   8482 
   8483 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
   8484     uint32 immediate_data_size,
   8485     const void* cmd_data) {
   8486   const gles2::cmds::CompressedTexSubImage2DBucket& c =
   8487       *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
   8488   GLenum target = static_cast<GLenum>(c.target);
   8489   GLint level = static_cast<GLint>(c.level);
   8490   GLint xoffset = static_cast<GLint>(c.xoffset);
   8491   GLint yoffset = static_cast<GLint>(c.yoffset);
   8492   GLsizei width = static_cast<GLsizei>(c.width);
   8493   GLsizei height = static_cast<GLsizei>(c.height);
   8494   GLenum format = static_cast<GLenum>(c.format);
   8495   Bucket* bucket = GetBucket(c.bucket_id);
   8496   if (!bucket) {
   8497     return error::kInvalidArguments;
   8498   }
   8499   uint32 data_size = bucket->size();
   8500   GLsizei imageSize = data_size;
   8501   const void* data = bucket->GetData(0, data_size);
   8502   if (!data) {
   8503     return error::kInvalidArguments;
   8504   }
   8505   if (!validators_->texture_target.IsValid(target)) {
   8506     LOCAL_SET_GL_ERROR(
   8507         GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
   8508     return error::kNoError;
   8509   }
   8510   if (!validators_->compressed_texture_format.IsValid(format)) {
   8511     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   8512         "glCompressedTexSubImage2D", format, "format");
   8513     return error::kNoError;
   8514   }
   8515   if (width < 0) {
   8516     LOCAL_SET_GL_ERROR(
   8517         GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
   8518     return error::kNoError;
   8519   }
   8520   if (height < 0) {
   8521     LOCAL_SET_GL_ERROR(
   8522         GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
   8523     return error::kNoError;
   8524   }
   8525   if (imageSize < 0) {
   8526     LOCAL_SET_GL_ERROR(
   8527         GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
   8528     return error::kNoError;
   8529   }
   8530   DoCompressedTexSubImage2D(
   8531       target, level, xoffset, yoffset, width, height, format, imageSize, data);
   8532   return error::kNoError;
   8533 }
   8534 
   8535 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
   8536                                                 const void* cmd_data) {
   8537   const gles2::cmds::TexImage2D& c =
   8538       *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
   8539   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
   8540       "width", c.width, "height", c.height);
   8541   // Set as failed for now, but if it successed, this will be set to not failed.
   8542   texture_state_.tex_image_2d_failed = true;
   8543   GLenum target = static_cast<GLenum>(c.target);
   8544   GLint level = static_cast<GLint>(c.level);
   8545   // TODO(kloveless): Change TexImage2D command to use unsigned integer
   8546   // for internalformat.
   8547   GLenum internal_format = static_cast<GLenum>(c.internalformat);
   8548   GLsizei width = static_cast<GLsizei>(c.width);
   8549   GLsizei height = static_cast<GLsizei>(c.height);
   8550   GLint border = static_cast<GLint>(c.border);
   8551   GLenum format = static_cast<GLenum>(c.format);
   8552   GLenum type = static_cast<GLenum>(c.type);
   8553   uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
   8554   uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
   8555   uint32 pixels_size;
   8556   if (!GLES2Util::ComputeImageDataSizes(
   8557       width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
   8558       NULL)) {
   8559     return error::kOutOfBounds;
   8560   }
   8561   const void* pixels = NULL;
   8562   if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
   8563     pixels = GetSharedMemoryAs<const void*>(
   8564         pixels_shm_id, pixels_shm_offset, pixels_size);
   8565     if (!pixels) {
   8566       return error::kOutOfBounds;
   8567     }
   8568   }
   8569 
   8570   TextureManager::DoTextImage2DArguments args = {
   8571     target, level, internal_format, width, height, border, format, type,
   8572     pixels, pixels_size};
   8573   texture_manager()->ValidateAndDoTexImage2D(
   8574       &texture_state_, &state_, &framebuffer_state_, args);
   8575 
   8576   // This may be a slow command.  Exit command processing to allow for
   8577   // context preemption and GPU watchdog checks.
   8578   ExitCommandProcessingEarly();
   8579   return error::kNoError;
   8580 }
   8581 
   8582 void GLES2DecoderImpl::DoCompressedTexSubImage2D(
   8583   GLenum target,
   8584   GLint level,
   8585   GLint xoffset,
   8586   GLint yoffset,
   8587   GLsizei width,
   8588   GLsizei height,
   8589   GLenum format,
   8590   GLsizei image_size,
   8591   const void * data) {
   8592   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8593       &state_, target);
   8594   if (!texture_ref) {
   8595     LOCAL_SET_GL_ERROR(
   8596         GL_INVALID_OPERATION,
   8597         "glCompressedTexSubImage2D", "unknown texture for target");
   8598     return;
   8599   }
   8600   Texture* texture = texture_ref->texture();
   8601   GLenum type = 0;
   8602   GLenum internal_format = 0;
   8603   if (!texture->GetLevelType(target, level, &type, &internal_format)) {
   8604     LOCAL_SET_GL_ERROR(
   8605         GL_INVALID_OPERATION,
   8606         "glCompressedTexSubImage2D", "level does not exist.");
   8607     return;
   8608   }
   8609   if (internal_format != format) {
   8610     LOCAL_SET_GL_ERROR(
   8611         GL_INVALID_OPERATION,
   8612         "glCompressedTexSubImage2D", "format does not match internal format.");
   8613     return;
   8614   }
   8615   if (!texture->ValidForTexture(
   8616       target, level, xoffset, yoffset, width, height, type)) {
   8617     LOCAL_SET_GL_ERROR(
   8618         GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
   8619     return;
   8620   }
   8621 
   8622   if (!ValidateCompressedTexFuncData(
   8623       "glCompressedTexSubImage2D", width, height, format, image_size) ||
   8624       !ValidateCompressedTexSubDimensions(
   8625       "glCompressedTexSubImage2D",
   8626       target, level, xoffset, yoffset, width, height, format, texture)) {
   8627     return;
   8628   }
   8629 
   8630 
   8631   // Note: There is no need to deal with texture cleared tracking here
   8632   // because the validation above means you can only get here if the level
   8633   // is already a matching compressed format and in that case
   8634   // CompressedTexImage2D already cleared the texture.
   8635   glCompressedTexSubImage2D(
   8636       target, level, xoffset, yoffset, width, height, format, image_size, data);
   8637 
   8638   // This may be a slow command.  Exit command processing to allow for
   8639   // context preemption and GPU watchdog checks.
   8640   ExitCommandProcessingEarly();
   8641 }
   8642 
   8643 static void Clip(
   8644     GLint start, GLint range, GLint sourceRange,
   8645     GLint* out_start, GLint* out_range) {
   8646   DCHECK(out_start);
   8647   DCHECK(out_range);
   8648   if (start < 0) {
   8649     range += start;
   8650     start = 0;
   8651   }
   8652   GLint end = start + range;
   8653   if (end > sourceRange) {
   8654     range -= end - sourceRange;
   8655   }
   8656   *out_start = start;
   8657   *out_range = range;
   8658 }
   8659 
   8660 void GLES2DecoderImpl::DoCopyTexImage2D(
   8661     GLenum target,
   8662     GLint level,
   8663     GLenum internal_format,
   8664     GLint x,
   8665     GLint y,
   8666     GLsizei width,
   8667     GLsizei height,
   8668     GLint border) {
   8669   DCHECK(!ShouldDeferReads());
   8670   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8671       &state_, target);
   8672   if (!texture_ref) {
   8673     LOCAL_SET_GL_ERROR(
   8674         GL_INVALID_OPERATION,
   8675         "glCopyTexImage2D", "unknown texture for target");
   8676     return;
   8677   }
   8678   Texture* texture = texture_ref->texture();
   8679   if (texture->IsImmutable()) {
   8680     LOCAL_SET_GL_ERROR(
   8681         GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
   8682     return;
   8683   }
   8684   if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
   8685       border != 0) {
   8686     LOCAL_SET_GL_ERROR(
   8687         GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
   8688     return;
   8689   }
   8690   if (!texture_manager()->ValidateFormatAndTypeCombination(
   8691       state_.GetErrorState(), "glCopyTexImage2D", internal_format,
   8692       GL_UNSIGNED_BYTE)) {
   8693     return;
   8694   }
   8695 
   8696   // Check we have compatible formats.
   8697   GLenum read_format = GetBoundReadFrameBufferInternalFormat();
   8698   uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
   8699   uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
   8700 
   8701   if ((channels_needed & channels_exist) != channels_needed) {
   8702     LOCAL_SET_GL_ERROR(
   8703         GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
   8704     return;
   8705   }
   8706 
   8707   if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
   8708     LOCAL_SET_GL_ERROR(
   8709         GL_INVALID_OPERATION,
   8710         "glCopyTexImage2D", "can not be used with depth or stencil textures");
   8711     return;
   8712   }
   8713 
   8714   uint32 estimated_size = 0;
   8715   if (!GLES2Util::ComputeImageDataSizes(
   8716       width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
   8717       &estimated_size, NULL, NULL)) {
   8718     LOCAL_SET_GL_ERROR(
   8719         GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
   8720     return;
   8721   }
   8722 
   8723   if (!EnsureGPUMemoryAvailable(estimated_size)) {
   8724     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
   8725     return;
   8726   }
   8727 
   8728   if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
   8729     return;
   8730   }
   8731 
   8732   if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
   8733     return;
   8734   }
   8735 
   8736   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
   8737   ScopedResolvedFrameBufferBinder binder(this, false, true);
   8738   gfx::Size size = GetBoundReadFrameBufferSize();
   8739 
   8740   if (texture->IsAttachedToFramebuffer()) {
   8741     framebuffer_state_.clear_state_dirty = true;
   8742   }
   8743 
   8744   // Clip to size to source dimensions
   8745   GLint copyX = 0;
   8746   GLint copyY = 0;
   8747   GLint copyWidth = 0;
   8748   GLint copyHeight = 0;
   8749   Clip(x, width, size.width(), &copyX, &copyWidth);
   8750   Clip(y, height, size.height(), &copyY, &copyHeight);
   8751 
   8752   if (copyX != x ||
   8753       copyY != y ||
   8754       copyWidth != width ||
   8755       copyHeight != height) {
   8756     // some part was clipped so clear the texture.
   8757     if (!ClearLevel(
   8758         texture->service_id(), texture->target(),
   8759         target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
   8760         width, height, texture->IsImmutable())) {
   8761       LOCAL_SET_GL_ERROR(
   8762           GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
   8763       return;
   8764     }
   8765     if (copyHeight > 0 && copyWidth > 0) {
   8766       GLint dx = copyX - x;
   8767       GLint dy = copyY - y;
   8768       GLint destX = dx;
   8769       GLint destY = dy;
   8770       ScopedModifyPixels modify(texture_ref);
   8771       glCopyTexSubImage2D(target, level,
   8772                           destX, destY, copyX, copyY,
   8773                           copyWidth, copyHeight);
   8774     }
   8775   } else {
   8776     ScopedModifyPixels modify(texture_ref);
   8777     glCopyTexImage2D(target, level, internal_format,
   8778                      copyX, copyY, copyWidth, copyHeight, border);
   8779   }
   8780   GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
   8781   if (error == GL_NO_ERROR) {
   8782     texture_manager()->SetLevelInfo(
   8783         texture_ref, target, level, internal_format, width, height, 1,
   8784         border, internal_format, GL_UNSIGNED_BYTE, true);
   8785   }
   8786 
   8787   // This may be a slow command.  Exit command processing to allow for
   8788   // context preemption and GPU watchdog checks.
   8789   ExitCommandProcessingEarly();
   8790 }
   8791 
   8792 void GLES2DecoderImpl::DoCopyTexSubImage2D(
   8793     GLenum target,
   8794     GLint level,
   8795     GLint xoffset,
   8796     GLint yoffset,
   8797     GLint x,
   8798     GLint y,
   8799     GLsizei width,
   8800     GLsizei height) {
   8801   DCHECK(!ShouldDeferReads());
   8802   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8803       &state_, target);
   8804   if (!texture_ref) {
   8805     LOCAL_SET_GL_ERROR(
   8806         GL_INVALID_OPERATION,
   8807         "glCopyTexSubImage2D", "unknown texture for target");
   8808     return;
   8809   }
   8810   Texture* texture = texture_ref->texture();
   8811   GLenum type = 0;
   8812   GLenum format = 0;
   8813   if (!texture->GetLevelType(target, level, &type, &format) ||
   8814       !texture->ValidForTexture(
   8815           target, level, xoffset, yoffset, width, height, type)) {
   8816     LOCAL_SET_GL_ERROR(
   8817         GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
   8818     return;
   8819   }
   8820   if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
   8821     LOCAL_SET_GL_ERROR(
   8822         GL_INVALID_OPERATION,
   8823         "glCopyTexSubImage2D", "async upload pending for texture");
   8824     return;
   8825   }
   8826 
   8827   // Check we have compatible formats.
   8828   GLenum read_format = GetBoundReadFrameBufferInternalFormat();
   8829   uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
   8830   uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
   8831 
   8832   if (!channels_needed ||
   8833       (channels_needed & channels_exist) != channels_needed) {
   8834     LOCAL_SET_GL_ERROR(
   8835         GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
   8836     return;
   8837   }
   8838 
   8839   if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
   8840     LOCAL_SET_GL_ERROR(
   8841         GL_INVALID_OPERATION,
   8842         "glCopySubImage2D", "can not be used with depth or stencil textures");
   8843     return;
   8844   }
   8845 
   8846   if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
   8847     return;
   8848   }
   8849 
   8850   if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
   8851     return;
   8852   }
   8853 
   8854   ScopedResolvedFrameBufferBinder binder(this, false, true);
   8855   gfx::Size size = GetBoundReadFrameBufferSize();
   8856   GLint copyX = 0;
   8857   GLint copyY = 0;
   8858   GLint copyWidth = 0;
   8859   GLint copyHeight = 0;
   8860   Clip(x, width, size.width(), &copyX, &copyWidth);
   8861   Clip(y, height, size.height(), &copyY, &copyHeight);
   8862 
   8863   if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
   8864     LOCAL_SET_GL_ERROR(
   8865         GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
   8866     return;
   8867   }
   8868 
   8869   if (copyX != x ||
   8870       copyY != y ||
   8871       copyWidth != width ||
   8872       copyHeight != height) {
   8873     // some part was clipped so clear the sub rect.
   8874     uint32 pixels_size = 0;
   8875     if (!GLES2Util::ComputeImageDataSizes(
   8876         width, height, format, type, state_.unpack_alignment, &pixels_size,
   8877         NULL, NULL)) {
   8878       LOCAL_SET_GL_ERROR(
   8879           GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
   8880       return;
   8881     }
   8882     scoped_ptr<char[]> zero(new char[pixels_size]);
   8883     memset(zero.get(), 0, pixels_size);
   8884     ScopedModifyPixels modify(texture_ref);
   8885     glTexSubImage2D(
   8886         target, level, xoffset, yoffset, width, height,
   8887         format, type, zero.get());
   8888   }
   8889 
   8890   if (copyHeight > 0 && copyWidth > 0) {
   8891     GLint dx = copyX - x;
   8892     GLint dy = copyY - y;
   8893     GLint destX = xoffset + dx;
   8894     GLint destY = yoffset + dy;
   8895     ScopedModifyPixels modify(texture_ref);
   8896     glCopyTexSubImage2D(target, level,
   8897                         destX, destY, copyX, copyY,
   8898                         copyWidth, copyHeight);
   8899   }
   8900 
   8901   // This may be a slow command.  Exit command processing to allow for
   8902   // context preemption and GPU watchdog checks.
   8903   ExitCommandProcessingEarly();
   8904 }
   8905 
   8906 bool GLES2DecoderImpl::ValidateTexSubImage2D(
   8907     error::Error* error,
   8908     const char* function_name,
   8909     GLenum target,
   8910     GLint level,
   8911     GLint xoffset,
   8912     GLint yoffset,
   8913     GLsizei width,
   8914     GLsizei height,
   8915     GLenum format,
   8916     GLenum type,
   8917     const void * data) {
   8918   (*error) = error::kNoError;
   8919   if (!validators_->texture_target.IsValid(target)) {
   8920     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
   8921     return false;
   8922   }
   8923   if (width < 0) {
   8924     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
   8925     return false;
   8926   }
   8927   if (height < 0) {
   8928     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
   8929     return false;
   8930   }
   8931   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8932       &state_, target);
   8933   if (!texture_ref) {
   8934     LOCAL_SET_GL_ERROR(
   8935         GL_INVALID_OPERATION,
   8936         function_name, "unknown texture for target");
   8937     return false;
   8938   }
   8939   Texture* texture = texture_ref->texture();
   8940   GLenum current_type = 0;
   8941   GLenum internal_format = 0;
   8942   if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
   8943     LOCAL_SET_GL_ERROR(
   8944         GL_INVALID_OPERATION, function_name, "level does not exist.");
   8945     return false;
   8946   }
   8947   if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
   8948       function_name, format, type, internal_format, level)) {
   8949     return false;
   8950   }
   8951   if (type != current_type) {
   8952     LOCAL_SET_GL_ERROR(
   8953         GL_INVALID_OPERATION,
   8954         function_name, "type does not match type of texture.");
   8955     return false;
   8956   }
   8957   if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
   8958     LOCAL_SET_GL_ERROR(
   8959         GL_INVALID_OPERATION,
   8960         function_name, "async upload pending for texture");
   8961     return false;
   8962   }
   8963   if (!texture->ValidForTexture(
   8964           target, level, xoffset, yoffset, width, height, type)) {
   8965     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
   8966     return false;
   8967   }
   8968   if ((GLES2Util::GetChannelsForFormat(format) &
   8969        (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
   8970     LOCAL_SET_GL_ERROR(
   8971         GL_INVALID_OPERATION,
   8972         function_name, "can not supply data for depth or stencil textures");
   8973     return false;
   8974   }
   8975   if (data == NULL) {
   8976     (*error) = error::kOutOfBounds;
   8977     return false;
   8978   }
   8979   return true;
   8980 }
   8981 
   8982 error::Error GLES2DecoderImpl::DoTexSubImage2D(
   8983     GLenum target,
   8984     GLint level,
   8985     GLint xoffset,
   8986     GLint yoffset,
   8987     GLsizei width,
   8988     GLsizei height,
   8989     GLenum format,
   8990     GLenum type,
   8991     const void * data) {
   8992   error::Error error = error::kNoError;
   8993   if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
   8994       xoffset, yoffset, width, height, format, type, data)) {
   8995     return error;
   8996   }
   8997   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   8998       &state_, target);
   8999   Texture* texture = texture_ref->texture();
   9000   GLsizei tex_width = 0;
   9001   GLsizei tex_height = 0;
   9002   bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
   9003   DCHECK(ok);
   9004   if (xoffset != 0 || yoffset != 0 ||
   9005       width != tex_width || height != tex_height) {
   9006     if (!texture_manager()->ClearTextureLevel(this, texture_ref,
   9007                                               target, level)) {
   9008       LOCAL_SET_GL_ERROR(
   9009           GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
   9010       return error::kNoError;
   9011     }
   9012     ScopedTextureUploadTimer timer(&texture_state_);
   9013     glTexSubImage2D(
   9014         target, level, xoffset, yoffset, width, height, format, type, data);
   9015     return error::kNoError;
   9016   }
   9017 
   9018   if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
   9019       !texture->IsImmutable()) {
   9020     ScopedTextureUploadTimer timer(&texture_state_);
   9021     GLenum internal_format;
   9022     GLenum tex_type;
   9023     texture->GetLevelType(target, level, &tex_type, &internal_format);
   9024     // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
   9025     // to look it up.
   9026     glTexImage2D(
   9027         target, level, internal_format, width, height, 0, format, type, data);
   9028   } else {
   9029     ScopedTextureUploadTimer timer(&texture_state_);
   9030     glTexSubImage2D(
   9031         target, level, xoffset, yoffset, width, height, format, type, data);
   9032   }
   9033   texture_manager()->SetLevelCleared(texture_ref, target, level, true);
   9034 
   9035   // This may be a slow command.  Exit command processing to allow for
   9036   // context preemption and GPU watchdog checks.
   9037   ExitCommandProcessingEarly();
   9038   return error::kNoError;
   9039 }
   9040 
   9041 error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
   9042                                                    const void* cmd_data) {
   9043   const gles2::cmds::TexSubImage2D& c =
   9044       *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
   9045   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
   9046       "width", c.width, "height", c.height);
   9047   GLboolean internal = static_cast<GLboolean>(c.internal);
   9048   if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
   9049     return error::kNoError;
   9050 
   9051   GLenum target = static_cast<GLenum>(c.target);
   9052   GLint level = static_cast<GLint>(c.level);
   9053   GLint xoffset = static_cast<GLint>(c.xoffset);
   9054   GLint yoffset = static_cast<GLint>(c.yoffset);
   9055   GLsizei width = static_cast<GLsizei>(c.width);
   9056   GLsizei height = static_cast<GLsizei>(c.height);
   9057   GLenum format = static_cast<GLenum>(c.format);
   9058   GLenum type = static_cast<GLenum>(c.type);
   9059   uint32 data_size;
   9060   if (!GLES2Util::ComputeImageDataSizes(
   9061       width, height, format, type, state_.unpack_alignment, &data_size,
   9062       NULL, NULL)) {
   9063     return error::kOutOfBounds;
   9064   }
   9065   const void* pixels = GetSharedMemoryAs<const void*>(
   9066       c.pixels_shm_id, c.pixels_shm_offset, data_size);
   9067   return DoTexSubImage2D(
   9068       target, level, xoffset, yoffset, width, height, format, type, pixels);
   9069 }
   9070 
   9071 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
   9072     uint32 immediate_data_size,
   9073     const void* cmd_data) {
   9074   const gles2::cmds::GetVertexAttribPointerv& c =
   9075       *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
   9076   GLuint index = static_cast<GLuint>(c.index);
   9077   GLenum pname = static_cast<GLenum>(c.pname);
   9078   typedef cmds::GetVertexAttribPointerv::Result Result;
   9079   Result* result = GetSharedMemoryAs<Result*>(
   9080         c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
   9081   if (!result) {
   9082     return error::kOutOfBounds;
   9083   }
   9084   // Check that the client initialized the result.
   9085   if (result->size != 0) {
   9086     return error::kInvalidArguments;
   9087   }
   9088   if (!validators_->vertex_pointer.IsValid(pname)) {
   9089     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   9090         "glGetVertexAttribPointerv", pname, "pname");
   9091     return error::kNoError;
   9092   }
   9093   if (index >= group_->max_vertex_attribs()) {
   9094     LOCAL_SET_GL_ERROR(
   9095         GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
   9096     return error::kNoError;
   9097   }
   9098   result->SetNumResults(1);
   9099   *result->GetData() =
   9100       state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
   9101   return error::kNoError;
   9102 }
   9103 
   9104 bool GLES2DecoderImpl::GetUniformSetup(
   9105     GLuint program_id, GLint fake_location,
   9106     uint32 shm_id, uint32 shm_offset,
   9107     error::Error* error, GLint* real_location,
   9108     GLuint* service_id, void** result_pointer, GLenum* result_type) {
   9109   DCHECK(error);
   9110   DCHECK(service_id);
   9111   DCHECK(result_pointer);
   9112   DCHECK(result_type);
   9113   DCHECK(real_location);
   9114   *error = error::kNoError;
   9115   // Make sure we have enough room for the result on failure.
   9116   SizedResult<GLint>* result;
   9117   result = GetSharedMemoryAs<SizedResult<GLint>*>(
   9118       shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
   9119   if (!result) {
   9120     *error = error::kOutOfBounds;
   9121     return false;
   9122   }
   9123   *result_pointer = result;
   9124   // Set the result size to 0 so the client does not have to check for success.
   9125   result->SetNumResults(0);
   9126   Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
   9127   if (!program) {
   9128     return false;
   9129   }
   9130   if (!program->IsValid()) {
   9131     // Program was not linked successfully. (ie, glLinkProgram)
   9132     LOCAL_SET_GL_ERROR(
   9133         GL_INVALID_OPERATION, "glGetUniform", "program not linked");
   9134     return false;
   9135   }
   9136   *service_id = program->service_id();
   9137   GLint array_index = -1;
   9138   const Program::UniformInfo* uniform_info =
   9139       program->GetUniformInfoByFakeLocation(
   9140           fake_location, real_location, &array_index);
   9141   if (!uniform_info) {
   9142     // No such location.
   9143     LOCAL_SET_GL_ERROR(
   9144         GL_INVALID_OPERATION, "glGetUniform", "unknown location");
   9145     return false;
   9146   }
   9147   GLenum type = uniform_info->type;
   9148   GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
   9149   if (size == 0) {
   9150     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
   9151     return false;
   9152   }
   9153   result = GetSharedMemoryAs<SizedResult<GLint>*>(
   9154       shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
   9155   if (!result) {
   9156     *error = error::kOutOfBounds;
   9157     return false;
   9158   }
   9159   result->size = size;
   9160   *result_type = type;
   9161   return true;
   9162 }
   9163 
   9164 error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
   9165                                                   const void* cmd_data) {
   9166   const gles2::cmds::GetUniformiv& c =
   9167       *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
   9168   GLuint program = c.program;
   9169   GLint fake_location = c.location;
   9170   GLuint service_id;
   9171   GLenum result_type;
   9172   GLint real_location = -1;
   9173   Error error;
   9174   void* result;
   9175   if (GetUniformSetup(
   9176       program, fake_location, c.params_shm_id, c.params_shm_offset,
   9177       &error, &real_location, &service_id, &result, &result_type)) {
   9178     glGetUniformiv(
   9179         service_id, real_location,
   9180         static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
   9181   }
   9182   return error;
   9183 }
   9184 
   9185 error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
   9186                                                   const void* cmd_data) {
   9187   const gles2::cmds::GetUniformfv& c =
   9188       *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
   9189   GLuint program = c.program;
   9190   GLint fake_location = c.location;
   9191   GLuint service_id;
   9192   GLint real_location = -1;
   9193   Error error;
   9194   typedef cmds::GetUniformfv::Result Result;
   9195   Result* result;
   9196   GLenum result_type;
   9197   if (GetUniformSetup(
   9198       program, fake_location, c.params_shm_id, c.params_shm_offset,
   9199       &error, &real_location, &service_id,
   9200       reinterpret_cast<void**>(&result), &result_type)) {
   9201     if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
   9202         result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
   9203       GLsizei num_values = result->GetNumResults();
   9204       scoped_ptr<GLint[]> temp(new GLint[num_values]);
   9205       glGetUniformiv(service_id, real_location, temp.get());
   9206       GLfloat* dst = result->GetData();
   9207       for (GLsizei ii = 0; ii < num_values; ++ii) {
   9208         dst[ii] = (temp[ii] != 0);
   9209       }
   9210     } else {
   9211       glGetUniformfv(service_id, real_location, result->GetData());
   9212     }
   9213   }
   9214   return error;
   9215 }
   9216 
   9217 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
   9218     uint32 immediate_data_size,
   9219     const void* cmd_data) {
   9220   const gles2::cmds::GetShaderPrecisionFormat& c =
   9221       *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
   9222   GLenum shader_type = static_cast<GLenum>(c.shadertype);
   9223   GLenum precision_type = static_cast<GLenum>(c.precisiontype);
   9224   typedef cmds::GetShaderPrecisionFormat::Result Result;
   9225   Result* result = GetSharedMemoryAs<Result*>(
   9226       c.result_shm_id, c.result_shm_offset, sizeof(*result));
   9227   if (!result) {
   9228     return error::kOutOfBounds;
   9229   }
   9230   // Check that the client initialized the result.
   9231   if (result->success != 0) {
   9232     return error::kInvalidArguments;
   9233   }
   9234   if (!validators_->shader_type.IsValid(shader_type)) {
   9235     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   9236         "glGetShaderPrecisionFormat", shader_type, "shader_type");
   9237     return error::kNoError;
   9238   }
   9239   if (!validators_->shader_precision.IsValid(precision_type)) {
   9240     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   9241         "glGetShaderPrecisionFormat", precision_type, "precision_type");
   9242     return error::kNoError;
   9243   }
   9244 
   9245   result->success = 1;  // true
   9246 
   9247   GLint range[2] = { 0, 0 };
   9248   GLint precision = 0;
   9249   GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
   9250 
   9251   result->min_range = range[0];
   9252   result->max_range = range[1];
   9253   result->precision = precision;
   9254 
   9255   return error::kNoError;
   9256 }
   9257 
   9258 error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
   9259     uint32 immediate_data_size,
   9260     const void* cmd_data) {
   9261   const gles2::cmds::GetAttachedShaders& c =
   9262       *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
   9263   uint32 result_size = c.result_size;
   9264   GLuint program_id = static_cast<GLuint>(c.program);
   9265   Program* program = GetProgramInfoNotShader(
   9266       program_id, "glGetAttachedShaders");
   9267   if (!program) {
   9268     return error::kNoError;
   9269   }
   9270   typedef cmds::GetAttachedShaders::Result Result;
   9271   uint32 max_count = Result::ComputeMaxResults(result_size);
   9272   Result* result = GetSharedMemoryAs<Result*>(
   9273       c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
   9274   if (!result) {
   9275     return error::kOutOfBounds;
   9276   }
   9277   // Check that the client initialized the result.
   9278   if (result->size != 0) {
   9279     return error::kInvalidArguments;
   9280   }
   9281   GLsizei count = 0;
   9282   glGetAttachedShaders(
   9283       program->service_id(), max_count, &count, result->GetData());
   9284   for (GLsizei ii = 0; ii < count; ++ii) {
   9285     if (!shader_manager()->GetClientId(result->GetData()[ii],
   9286                                        &result->GetData()[ii])) {
   9287       NOTREACHED();
   9288       return error::kGenericError;
   9289     }
   9290   }
   9291   result->SetNumResults(count);
   9292   return error::kNoError;
   9293 }
   9294 
   9295 error::Error GLES2DecoderImpl::HandleGetActiveUniform(
   9296     uint32 immediate_data_size,
   9297     const void* cmd_data) {
   9298   const gles2::cmds::GetActiveUniform& c =
   9299       *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
   9300   GLuint program_id = c.program;
   9301   GLuint index = c.index;
   9302   uint32 name_bucket_id = c.name_bucket_id;
   9303   typedef cmds::GetActiveUniform::Result Result;
   9304   Result* result = GetSharedMemoryAs<Result*>(
   9305       c.result_shm_id, c.result_shm_offset, sizeof(*result));
   9306   if (!result) {
   9307     return error::kOutOfBounds;
   9308   }
   9309   // Check that the client initialized the result.
   9310   if (result->success != 0) {
   9311     return error::kInvalidArguments;
   9312   }
   9313   Program* program = GetProgramInfoNotShader(
   9314       program_id, "glGetActiveUniform");
   9315   if (!program) {
   9316     return error::kNoError;
   9317   }
   9318   const Program::UniformInfo* uniform_info =
   9319       program->GetUniformInfo(index);
   9320   if (!uniform_info) {
   9321     LOCAL_SET_GL_ERROR(
   9322         GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
   9323     return error::kNoError;
   9324   }
   9325   result->success = 1;  // true.
   9326   result->size = uniform_info->size;
   9327   result->type = uniform_info->type;
   9328   Bucket* bucket = CreateBucket(name_bucket_id);
   9329   bucket->SetFromString(uniform_info->name.c_str());
   9330   return error::kNoError;
   9331 }
   9332 
   9333 error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
   9334                                                      const void* cmd_data) {
   9335   const gles2::cmds::GetActiveAttrib& c =
   9336       *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
   9337   GLuint program_id = c.program;
   9338   GLuint index = c.index;
   9339   uint32 name_bucket_id = c.name_bucket_id;
   9340   typedef cmds::GetActiveAttrib::Result Result;
   9341   Result* result = GetSharedMemoryAs<Result*>(
   9342       c.result_shm_id, c.result_shm_offset, sizeof(*result));
   9343   if (!result) {
   9344     return error::kOutOfBounds;
   9345   }
   9346   // Check that the client initialized the result.
   9347   if (result->success != 0) {
   9348     return error::kInvalidArguments;
   9349   }
   9350   Program* program = GetProgramInfoNotShader(
   9351       program_id, "glGetActiveAttrib");
   9352   if (!program) {
   9353     return error::kNoError;
   9354   }
   9355   const Program::VertexAttrib* attrib_info =
   9356       program->GetAttribInfo(index);
   9357   if (!attrib_info) {
   9358     LOCAL_SET_GL_ERROR(
   9359         GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
   9360     return error::kNoError;
   9361   }
   9362   result->success = 1;  // true.
   9363   result->size = attrib_info->size;
   9364   result->type = attrib_info->type;
   9365   Bucket* bucket = CreateBucket(name_bucket_id);
   9366   bucket->SetFromString(attrib_info->name.c_str());
   9367   return error::kNoError;
   9368 }
   9369 
   9370 error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
   9371                                                   const void* cmd_data) {
   9372 #if 1  // No binary shader support.
   9373   LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
   9374   return error::kNoError;
   9375 #else
   9376   GLsizei n = static_cast<GLsizei>(c.n);
   9377   if (n < 0) {
   9378     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
   9379     return error::kNoError;
   9380   }
   9381   GLsizei length = static_cast<GLsizei>(c.length);
   9382   if (length < 0) {
   9383     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
   9384     return error::kNoError;
   9385   }
   9386   uint32 data_size;
   9387   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
   9388     return error::kOutOfBounds;
   9389   }
   9390   const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
   9391       c.shaders_shm_id, c.shaders_shm_offset, data_size);
   9392   GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
   9393   const void* binary = GetSharedMemoryAs<const void*>(
   9394       c.binary_shm_id, c.binary_shm_offset, length);
   9395   if (shaders == NULL || binary == NULL) {
   9396     return error::kOutOfBounds;
   9397   }
   9398   scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   9399   for (GLsizei ii = 0; ii < n; ++ii) {
   9400     Shader* shader = GetShader(shaders[ii]);
   9401     if (!shader) {
   9402       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
   9403       return error::kNoError;
   9404     }
   9405     service_ids[ii] = shader->service_id();
   9406   }
   9407   // TODO(gman): call glShaderBinary
   9408   return error::kNoError;
   9409 #endif
   9410 }
   9411 
   9412 void GLES2DecoderImpl::DoSwapBuffers() {
   9413   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
   9414 
   9415   int this_frame_number = frame_number_++;
   9416   // TRACE_EVENT for gpu tests:
   9417   TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
   9418                        TRACE_EVENT_SCOPE_THREAD,
   9419                        "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
   9420                        "width", (is_offscreen ? offscreen_size_.width() :
   9421                                  surface_->GetSize().width()));
   9422   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
   9423                "offscreen", is_offscreen,
   9424                "frame", this_frame_number);
   9425   {
   9426     TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
   9427   }
   9428 
   9429   bool is_tracing;
   9430   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
   9431                                      &is_tracing);
   9432   if (is_tracing) {
   9433     ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
   9434     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
   9435         is_offscreen ? offscreen_size_ : surface_->GetSize());
   9436   }
   9437 
   9438   // If offscreen then don't actually SwapBuffers to the display. Just copy
   9439   // the rendered frame to another frame buffer.
   9440   if (is_offscreen) {
   9441     TRACE_EVENT2("gpu", "Offscreen",
   9442         "width", offscreen_size_.width(), "height", offscreen_size_.height());
   9443     if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
   9444       // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
   9445       // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
   9446       // fix this.
   9447       if (workarounds().needs_offscreen_buffer_workaround) {
   9448         offscreen_saved_frame_buffer_->Create();
   9449         glFinish();
   9450       }
   9451 
   9452       // Allocate the offscreen saved color texture.
   9453       DCHECK(offscreen_saved_color_format_);
   9454       offscreen_saved_color_texture_->AllocateStorage(
   9455           offscreen_size_, offscreen_saved_color_format_, false);
   9456 
   9457       offscreen_saved_frame_buffer_->AttachRenderTexture(
   9458           offscreen_saved_color_texture_.get());
   9459       if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
   9460         if (offscreen_saved_frame_buffer_->CheckStatus() !=
   9461             GL_FRAMEBUFFER_COMPLETE) {
   9462           LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
   9463                      << "because offscreen saved FBO was incomplete.";
   9464           LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
   9465           return;
   9466         }
   9467 
   9468         // Clear the offscreen color texture.
   9469         // TODO(piman): Is this still necessary?
   9470         {
   9471           ScopedFrameBufferBinder binder(this,
   9472                                          offscreen_saved_frame_buffer_->id());
   9473           glClearColor(0, 0, 0, 0);
   9474           state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   9475           state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   9476           glClear(GL_COLOR_BUFFER_BIT);
   9477           RestoreClearState();
   9478         }
   9479       }
   9480 
   9481       UpdateParentTextureInfo();
   9482     }
   9483 
   9484     if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
   9485       return;
   9486     ScopedGLErrorSuppressor suppressor(
   9487         "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
   9488 
   9489     if (IsOffscreenBufferMultisampled()) {
   9490       // For multisampled buffers, resolve the frame buffer.
   9491       ScopedResolvedFrameBufferBinder binder(this, true, false);
   9492     } else {
   9493       ScopedFrameBufferBinder binder(this,
   9494                                      offscreen_target_frame_buffer_->id());
   9495 
   9496       if (offscreen_target_buffer_preserved_) {
   9497         // Copy the target frame buffer to the saved offscreen texture.
   9498         offscreen_saved_color_texture_->Copy(
   9499             offscreen_saved_color_texture_->size(),
   9500             offscreen_saved_color_format_);
   9501       } else {
   9502         // Flip the textures in the parent context via the texture manager.
   9503         if (!!offscreen_saved_color_texture_info_.get())
   9504           offscreen_saved_color_texture_info_->texture()->
   9505               SetServiceId(offscreen_target_color_texture_->id());
   9506 
   9507         offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
   9508         offscreen_target_frame_buffer_->AttachRenderTexture(
   9509             offscreen_target_color_texture_.get());
   9510       }
   9511 
   9512       // Ensure the side effects of the copy are visible to the parent
   9513       // context. There is no need to do this for ANGLE because it uses a
   9514       // single D3D device for all contexts.
   9515       if (!feature_info_->feature_flags().is_angle)
   9516         glFlush();
   9517     }
   9518   } else {
   9519     if (!surface_->SwapBuffers()) {
   9520       LOG(ERROR) << "Context lost because SwapBuffers failed.";
   9521       LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
   9522     }
   9523   }
   9524 
   9525   // This may be a slow command.  Exit command processing to allow for
   9526   // context preemption and GPU watchdog checks.
   9527   ExitCommandProcessingEarly();
   9528 }
   9529 
   9530 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
   9531     uint32 immediate_data_size,
   9532     const void* cmd_data) {
   9533   const gles2::cmds::EnableFeatureCHROMIUM& c =
   9534       *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
   9535   Bucket* bucket = GetBucket(c.bucket_id);
   9536   if (!bucket || bucket->size() == 0) {
   9537     return error::kInvalidArguments;
   9538   }
   9539   typedef cmds::EnableFeatureCHROMIUM::Result Result;
   9540   Result* result = GetSharedMemoryAs<Result*>(
   9541       c.result_shm_id, c.result_shm_offset, sizeof(*result));
   9542   if (!result) {
   9543     return error::kOutOfBounds;
   9544   }
   9545   // Check that the client initialized the result.
   9546   if (*result != 0) {
   9547     return error::kInvalidArguments;
   9548   }
   9549   std::string feature_str;
   9550   if (!bucket->GetAsString(&feature_str)) {
   9551     return error::kInvalidArguments;
   9552   }
   9553 
   9554   // TODO(gman): make this some kind of table to function pointer thingy.
   9555   if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
   9556     buffer_manager()->set_allow_buffers_on_multiple_targets(true);
   9557   } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
   9558     buffer_manager()->set_allow_buffers_on_multiple_targets(true);
   9559     // TODO(gman): decide how to remove the need for this const_cast.
   9560     // I could make validators_ non const but that seems bad as this is the only
   9561     // place it is needed. I could make some special friend class of validators
   9562     // just to allow this to set them. That seems silly. I could refactor this
   9563     // code to use the extension mechanism or the initialization attributes to
   9564     // turn this feature on. Given that the only real point of this is to make
   9565     // the conformance tests pass and given that there is lots of real work that
   9566     // needs to be done it seems like refactoring for one to one of those
   9567     // methods is a very low priority.
   9568     const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
   9569   } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
   9570     force_webgl_glsl_validation_ = true;
   9571     InitializeShaderTranslator();
   9572   } else {
   9573     return error::kNoError;
   9574   }
   9575 
   9576   *result = 1;  // true.
   9577   return error::kNoError;
   9578 }
   9579 
   9580 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
   9581     uint32 immediate_data_size,
   9582     const void* cmd_data) {
   9583   const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
   9584       *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
   9585           cmd_data);
   9586   Bucket* bucket = CreateBucket(c.bucket_id);
   9587   scoped_refptr<FeatureInfo> info(new FeatureInfo());
   9588   info->Initialize(disallowed_features_);
   9589   bucket->SetFromString(info->extensions().c_str());
   9590   return error::kNoError;
   9591 }
   9592 
   9593 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
   9594     uint32 immediate_data_size,
   9595     const void* cmd_data) {
   9596   const gles2::cmds::RequestExtensionCHROMIUM& c =
   9597       *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
   9598   Bucket* bucket = GetBucket(c.bucket_id);
   9599   if (!bucket || bucket->size() == 0) {
   9600     return error::kInvalidArguments;
   9601   }
   9602   std::string feature_str;
   9603   if (!bucket->GetAsString(&feature_str)) {
   9604     return error::kInvalidArguments;
   9605   }
   9606 
   9607   bool desire_webgl_glsl_validation =
   9608       feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
   9609   bool desire_standard_derivatives = false;
   9610   bool desire_frag_depth = false;
   9611   bool desire_draw_buffers = false;
   9612   bool desire_shader_texture_lod = false;
   9613   if (force_webgl_glsl_validation_) {
   9614     desire_standard_derivatives =
   9615         feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
   9616     desire_frag_depth =
   9617         feature_str.find("GL_EXT_frag_depth") != std::string::npos;
   9618     desire_draw_buffers =
   9619         feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
   9620     desire_shader_texture_lod =
   9621         feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
   9622   }
   9623 
   9624   if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
   9625       desire_standard_derivatives != derivatives_explicitly_enabled_ ||
   9626       desire_frag_depth != frag_depth_explicitly_enabled_ ||
   9627       desire_draw_buffers != draw_buffers_explicitly_enabled_) {
   9628     force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
   9629     derivatives_explicitly_enabled_ |= desire_standard_derivatives;
   9630     frag_depth_explicitly_enabled_ |= desire_frag_depth;
   9631     draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
   9632     shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
   9633     InitializeShaderTranslator();
   9634   }
   9635 
   9636   UpdateCapabilities();
   9637 
   9638   return error::kNoError;
   9639 }
   9640 
   9641 error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
   9642     uint32 immediate_data_size,
   9643     const void* cmd_data) {
   9644   const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
   9645       *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
   9646   GLuint count = c.count;
   9647   uint32 pnames_size;
   9648   if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
   9649     return error::kOutOfBounds;
   9650   }
   9651   const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
   9652       c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
   9653   if (pnames == NULL) {
   9654     return error::kOutOfBounds;
   9655   }
   9656 
   9657   // We have to copy them since we use them twice so the client
   9658   // can't change them between the time we validate them and the time we use
   9659   // them.
   9660   scoped_ptr<GLenum[]> enums(new GLenum[count]);
   9661   memcpy(enums.get(), pnames, pnames_size);
   9662 
   9663   // Count up the space needed for the result.
   9664   uint32 num_results = 0;
   9665   for (GLuint ii = 0; ii < count; ++ii) {
   9666     uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
   9667     if (num == 0) {
   9668       LOCAL_SET_GL_ERROR_INVALID_ENUM(
   9669           "glGetMultipleCHROMIUM", enums[ii], "pname");
   9670       return error::kNoError;
   9671     }
   9672     // Num will never be more than 4.
   9673     DCHECK_LE(num, 4u);
   9674     if (!SafeAddUint32(num_results, num, &num_results)) {
   9675       return error::kOutOfBounds;
   9676     }
   9677   }
   9678 
   9679   uint32 result_size = 0;
   9680   if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
   9681     return error::kOutOfBounds;
   9682   }
   9683 
   9684   if (result_size != static_cast<uint32>(c.size)) {
   9685     LOCAL_SET_GL_ERROR(
   9686         GL_INVALID_VALUE,
   9687         "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
   9688     return error::kNoError;
   9689   }
   9690 
   9691   GLint* results = GetSharedMemoryAs<GLint*>(
   9692       c.results_shm_id, c.results_shm_offset, result_size);
   9693   if (results == NULL) {
   9694     return error::kOutOfBounds;
   9695   }
   9696 
   9697   // Check the results have been cleared in case the context was lost.
   9698   for (uint32 ii = 0; ii < num_results; ++ii) {
   9699     if (results[ii]) {
   9700       return error::kInvalidArguments;
   9701     }
   9702   }
   9703 
   9704   // Get each result.
   9705   GLint* start = results;
   9706   for (GLuint ii = 0; ii < count; ++ii) {
   9707     GLsizei num_written = 0;
   9708     if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
   9709         !GetHelper(enums[ii], results, &num_written)) {
   9710       DoGetIntegerv(enums[ii], results);
   9711     }
   9712     results += num_written;
   9713   }
   9714 
   9715   // Just to verify. Should this be a DCHECK?
   9716   if (static_cast<uint32>(results - start) != num_results) {
   9717     return error::kOutOfBounds;
   9718   }
   9719 
   9720   return error::kNoError;
   9721 }
   9722 
   9723 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
   9724     uint32 immediate_data_size,
   9725     const void* cmd_data) {
   9726   const gles2::cmds::GetProgramInfoCHROMIUM& c =
   9727       *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
   9728   GLuint program_id = static_cast<GLuint>(c.program);
   9729   uint32 bucket_id = c.bucket_id;
   9730   Bucket* bucket = CreateBucket(bucket_id);
   9731   bucket->SetSize(sizeof(ProgramInfoHeader));  // in case we fail.
   9732   Program* program = NULL;
   9733   program = GetProgram(program_id);
   9734   if (!program || !program->IsValid()) {
   9735     return error::kNoError;
   9736   }
   9737   program->GetProgramInfo(program_manager(), bucket);
   9738   return error::kNoError;
   9739 }
   9740 
   9741 error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
   9742   switch (reset_status_) {
   9743     case GL_NO_ERROR:
   9744       // TODO(kbr): improve the precision of the error code in this case.
   9745       // Consider delegating to context for error code if MakeCurrent fails.
   9746       return error::kUnknown;
   9747     case GL_GUILTY_CONTEXT_RESET_ARB:
   9748       return error::kGuilty;
   9749     case GL_INNOCENT_CONTEXT_RESET_ARB:
   9750       return error::kInnocent;
   9751     case GL_UNKNOWN_CONTEXT_RESET_ARB:
   9752       return error::kUnknown;
   9753   }
   9754 
   9755   NOTREACHED();
   9756   return error::kUnknown;
   9757 }
   9758 
   9759 bool GLES2DecoderImpl::WasContextLost() {
   9760   if (reset_status_ != GL_NO_ERROR) {
   9761     return true;
   9762   }
   9763   if (context_->WasAllocatedUsingRobustnessExtension()) {
   9764     GLenum status = GL_NO_ERROR;
   9765     if (has_robustness_extension_)
   9766       status = glGetGraphicsResetStatusARB();
   9767     if (status != GL_NO_ERROR) {
   9768       // The graphics card was reset. Signal a lost context to the application.
   9769       reset_status_ = status;
   9770       reset_by_robustness_extension_ = true;
   9771       LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
   9772                  << " context lost via ARB/EXT_robustness. Reset status = "
   9773                  << GLES2Util::GetStringEnum(status);
   9774       return true;
   9775     }
   9776   }
   9777   return false;
   9778 }
   9779 
   9780 bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
   9781   return WasContextLost() && reset_by_robustness_extension_;
   9782 }
   9783 
   9784 void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
   9785   // Only loses the context once.
   9786   if (reset_status_ != GL_NO_ERROR) {
   9787     return;
   9788   }
   9789 
   9790   // Marks this context as lost.
   9791   reset_status_ = reset_status;
   9792   current_decoder_error_ = error::kLostContext;
   9793 }
   9794 
   9795 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
   9796     uint32 immediate_data_size,
   9797     const void* cmd_data) {
   9798   return error::kUnknownCommand;
   9799 }
   9800 
   9801 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
   9802     uint32 immediate_data_size,
   9803     const void* cmd_data) {
   9804   const gles2::cmds::WaitSyncPointCHROMIUM& c =
   9805       *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
   9806   uint32 sync_point = c.sync_point;
   9807   if (wait_sync_point_callback_.is_null())
   9808     return error::kNoError;
   9809 
   9810   return wait_sync_point_callback_.Run(sync_point) ?
   9811       error::kNoError : error::kDeferCommandUntilLater;
   9812 }
   9813 
   9814 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
   9815     uint32 immediate_data_size,
   9816     const void* cmd_data) {
   9817   if (surface_->DeferDraws())
   9818     return error::kDeferCommandUntilLater;
   9819   if (!surface_->SetBackbufferAllocation(false))
   9820     return error::kLostContext;
   9821   backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
   9822   backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
   9823   backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
   9824   return error::kNoError;
   9825 }
   9826 
   9827 bool GLES2DecoderImpl::GenQueriesEXTHelper(
   9828     GLsizei n, const GLuint* client_ids) {
   9829   for (GLsizei ii = 0; ii < n; ++ii) {
   9830     if (query_manager_->GetQuery(client_ids[ii])) {
   9831       return false;
   9832     }
   9833   }
   9834   query_manager_->GenQueries(n, client_ids);
   9835   return true;
   9836 }
   9837 
   9838 void GLES2DecoderImpl::DeleteQueriesEXTHelper(
   9839     GLsizei n, const GLuint* client_ids) {
   9840   for (GLsizei ii = 0; ii < n; ++ii) {
   9841     QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
   9842     if (query && !query->IsDeleted()) {
   9843       ContextState::QueryMap::iterator it =
   9844           state_.current_queries.find(query->target());
   9845       if (it != state_.current_queries.end())
   9846         state_.current_queries.erase(it);
   9847 
   9848       query->Destroy(true);
   9849     }
   9850     query_manager_->RemoveQuery(client_ids[ii]);
   9851   }
   9852 }
   9853 
   9854 bool GLES2DecoderImpl::ProcessPendingQueries() {
   9855   if (query_manager_.get() == NULL) {
   9856     return false;
   9857   }
   9858   if (!query_manager_->ProcessPendingQueries()) {
   9859     current_decoder_error_ = error::kOutOfBounds;
   9860   }
   9861   return query_manager_->HavePendingQueries();
   9862 }
   9863 
   9864 // Note that if there are no pending readpixels right now,
   9865 // this function will call the callback immediately.
   9866 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
   9867   if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
   9868     pending_readpixel_fences_.back()->callbacks.push_back(callback);
   9869   } else {
   9870     callback.Run();
   9871   }
   9872 }
   9873 
   9874 void GLES2DecoderImpl::ProcessPendingReadPixels() {
   9875   while (!pending_readpixel_fences_.empty() &&
   9876          pending_readpixel_fences_.front()->fence->HasCompleted()) {
   9877     std::vector<base::Closure> callbacks =
   9878         pending_readpixel_fences_.front()->callbacks;
   9879     pending_readpixel_fences_.pop();
   9880     for (size_t i = 0; i < callbacks.size(); i++) {
   9881       callbacks[i].Run();
   9882     }
   9883   }
   9884 }
   9885 
   9886 bool GLES2DecoderImpl::HasMoreIdleWork() {
   9887   return !pending_readpixel_fences_.empty() ||
   9888       async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
   9889 }
   9890 
   9891 void GLES2DecoderImpl::PerformIdleWork() {
   9892   ProcessPendingReadPixels();
   9893   if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
   9894     return;
   9895   async_pixel_transfer_manager_->ProcessMorePendingTransfers();
   9896   ProcessFinishedAsyncTransfers();
   9897 }
   9898 
   9899 error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
   9900                                                    const void* cmd_data) {
   9901   const gles2::cmds::BeginQueryEXT& c =
   9902       *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
   9903   GLenum target = static_cast<GLenum>(c.target);
   9904   GLuint client_id = static_cast<GLuint>(c.id);
   9905   int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
   9906   uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
   9907 
   9908   switch (target) {
   9909     case GL_COMMANDS_ISSUED_CHROMIUM:
   9910     case GL_LATENCY_QUERY_CHROMIUM:
   9911     case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
   9912     case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
   9913     case GL_GET_ERROR_QUERY_CHROMIUM:
   9914       break;
   9915     case GL_COMMANDS_COMPLETED_CHROMIUM:
   9916       if (!features().chromium_sync_query) {
   9917         LOCAL_SET_GL_ERROR(
   9918             GL_INVALID_OPERATION, "glBeginQueryEXT",
   9919             "not enabled for commands completed queries");
   9920         return error::kNoError;
   9921       }
   9922       break;
   9923     default:
   9924       if (!features().occlusion_query_boolean) {
   9925         LOCAL_SET_GL_ERROR(
   9926             GL_INVALID_OPERATION, "glBeginQueryEXT",
   9927             "not enabled for occlusion queries");
   9928         return error::kNoError;
   9929       }
   9930       break;
   9931   }
   9932 
   9933   if (state_.current_queries.find(target) != state_.current_queries.end()) {
   9934     LOCAL_SET_GL_ERROR(
   9935         GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
   9936     return error::kNoError;
   9937   }
   9938 
   9939   if (client_id == 0) {
   9940     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
   9941     return error::kNoError;
   9942   }
   9943 
   9944   QueryManager::Query* query = query_manager_->GetQuery(client_id);
   9945   if (!query) {
   9946     if (!query_manager_->IsValidQuery(client_id)) {
   9947       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   9948                          "glBeginQueryEXT",
   9949                          "id not made by glGenQueriesEXT");
   9950       return error::kNoError;
   9951     }
   9952     query = query_manager_->CreateQuery(
   9953         target, client_id, sync_shm_id, sync_shm_offset);
   9954   }
   9955 
   9956   if (query->target() != target) {
   9957     LOCAL_SET_GL_ERROR(
   9958         GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
   9959     return error::kNoError;
   9960   } else if (query->shm_id() != sync_shm_id ||
   9961              query->shm_offset() != sync_shm_offset) {
   9962     DLOG(ERROR) << "Shared memory used by query not the same as before";
   9963     return error::kInvalidArguments;
   9964   }
   9965 
   9966   if (!query_manager_->BeginQuery(query)) {
   9967     return error::kOutOfBounds;
   9968   }
   9969 
   9970   state_.current_queries[target] = query;
   9971   return error::kNoError;
   9972 }
   9973 
   9974 error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
   9975                                                  const void* cmd_data) {
   9976   const gles2::cmds::EndQueryEXT& c =
   9977       *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
   9978   GLenum target = static_cast<GLenum>(c.target);
   9979   uint32 submit_count = static_cast<GLuint>(c.submit_count);
   9980   ContextState::QueryMap::iterator it = state_.current_queries.find(target);
   9981 
   9982   if (it == state_.current_queries.end()) {
   9983     LOCAL_SET_GL_ERROR(
   9984         GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
   9985     return error::kNoError;
   9986   }
   9987 
   9988   QueryManager::Query* query = it->second.get();
   9989   if (!query_manager_->EndQuery(query, submit_count)) {
   9990     return error::kOutOfBounds;
   9991   }
   9992 
   9993   query_manager_->ProcessPendingTransferQueries();
   9994 
   9995   state_.current_queries.erase(it);
   9996   return error::kNoError;
   9997 }
   9998 
   9999 bool GLES2DecoderImpl::GenVertexArraysOESHelper(
   10000     GLsizei n, const GLuint* client_ids) {
   10001   for (GLsizei ii = 0; ii < n; ++ii) {
   10002     if (GetVertexAttribManager(client_ids[ii])) {
   10003       return false;
   10004     }
   10005   }
   10006 
   10007   if (!features().native_vertex_array_object) {
   10008     // Emulated VAO
   10009     for (GLsizei ii = 0; ii < n; ++ii) {
   10010       CreateVertexAttribManager(client_ids[ii], 0, true);
   10011     }
   10012   } else {
   10013     scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
   10014 
   10015     glGenVertexArraysOES(n, service_ids.get());
   10016     for (GLsizei ii = 0; ii < n; ++ii) {
   10017       CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
   10018     }
   10019   }
   10020 
   10021   return true;
   10022 }
   10023 
   10024 void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
   10025     GLsizei n, const GLuint* client_ids) {
   10026   for (GLsizei ii = 0; ii < n; ++ii) {
   10027     VertexAttribManager* vao =
   10028         GetVertexAttribManager(client_ids[ii]);
   10029     if (vao && !vao->IsDeleted()) {
   10030       if (state_.vertex_attrib_manager.get() == vao) {
   10031         DoBindVertexArrayOES(0);
   10032       }
   10033       RemoveVertexAttribManager(client_ids[ii]);
   10034     }
   10035   }
   10036 }
   10037 
   10038 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
   10039   VertexAttribManager* vao = NULL;
   10040   if (client_id != 0) {
   10041     vao = GetVertexAttribManager(client_id);
   10042     if (!vao) {
   10043       // Unlike most Bind* methods, the spec explicitly states that VertexArray
   10044       // only allows names that have been previously generated. As such, we do
   10045       // not generate new names here.
   10046       LOCAL_SET_GL_ERROR(
   10047           GL_INVALID_OPERATION,
   10048           "glBindVertexArrayOES", "bad vertex array id.");
   10049       current_decoder_error_ = error::kNoError;
   10050       return;
   10051     }
   10052   } else {
   10053     vao = state_.default_vertex_attrib_manager.get();
   10054   }
   10055 
   10056   // Only set the VAO state if it's changed
   10057   if (state_.vertex_attrib_manager.get() != vao) {
   10058     state_.vertex_attrib_manager = vao;
   10059     if (!features().native_vertex_array_object) {
   10060       EmulateVertexArrayState();
   10061     } else {
   10062       GLuint service_id = vao->service_id();
   10063       glBindVertexArrayOES(service_id);
   10064     }
   10065   }
   10066 }
   10067 
   10068 // Used when OES_vertex_array_object isn't natively supported
   10069 void GLES2DecoderImpl::EmulateVertexArrayState() {
   10070   // Setup the Vertex attribute state
   10071   for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
   10072     RestoreStateForAttrib(vv, true);
   10073   }
   10074 
   10075   // Setup the element buffer
   10076   Buffer* element_array_buffer =
   10077       state_.vertex_attrib_manager->element_array_buffer();
   10078   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
   10079       element_array_buffer ? element_array_buffer->service_id() : 0);
   10080 }
   10081 
   10082 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
   10083   const VertexAttribManager* vao =
   10084       GetVertexAttribManager(client_id);
   10085   return vao && vao->IsValid() && !vao->IsDeleted();
   10086 }
   10087 
   10088 #if defined(OS_MACOSX)
   10089 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
   10090   TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
   10091       texture_id);
   10092   if (it != texture_to_io_surface_map_.end()) {
   10093     // Found a previous IOSurface bound to this texture; release it.
   10094     IOSurfaceRef surface = it->second;
   10095     CFRelease(surface);
   10096     texture_to_io_surface_map_.erase(it);
   10097   }
   10098 }
   10099 #endif
   10100 
   10101 void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
   10102     GLenum target, GLsizei width, GLsizei height,
   10103     GLuint io_surface_id, GLuint plane) {
   10104 #if defined(OS_MACOSX)
   10105   if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
   10106     LOCAL_SET_GL_ERROR(
   10107         GL_INVALID_OPERATION,
   10108         "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
   10109     return;
   10110   }
   10111 
   10112   if (target != GL_TEXTURE_RECTANGLE_ARB) {
   10113     // This might be supported in the future, and if we could require
   10114     // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
   10115     // could delete a lot of code. For now, perform strict validation so we
   10116     // know what's going on.
   10117     LOCAL_SET_GL_ERROR(
   10118         GL_INVALID_OPERATION,
   10119         "glTexImageIOSurface2DCHROMIUM",
   10120         "requires TEXTURE_RECTANGLE_ARB target");
   10121     return;
   10122   }
   10123 
   10124   // Default target might be conceptually valid, but disallow it to avoid
   10125   // accidents.
   10126   TextureRef* texture_ref =
   10127       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
   10128   if (!texture_ref) {
   10129     LOCAL_SET_GL_ERROR(
   10130         GL_INVALID_OPERATION,
   10131         "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
   10132     return;
   10133   }
   10134 
   10135   // Look up the new IOSurface. Note that because of asynchrony
   10136   // between processes this might fail; during live resizing the
   10137   // plugin process might allocate and release an IOSurface before
   10138   // this process gets a chance to look it up. Hold on to any old
   10139   // IOSurface in this case.
   10140   IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
   10141   if (!surface) {
   10142     LOCAL_SET_GL_ERROR(
   10143         GL_INVALID_OPERATION,
   10144         "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
   10145     return;
   10146   }
   10147 
   10148   // Release any IOSurface previously bound to this texture.
   10149   ReleaseIOSurfaceForTexture(texture_ref->service_id());
   10150 
   10151   // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
   10152   texture_to_io_surface_map_.insert(
   10153       std::make_pair(texture_ref->service_id(), surface));
   10154 
   10155   CGLContextObj context =
   10156       static_cast<CGLContextObj>(context_->GetHandle());
   10157 
   10158   CGLError err = CGLTexImageIOSurface2D(
   10159       context,
   10160       target,
   10161       GL_RGBA,
   10162       width,
   10163       height,
   10164       GL_BGRA,
   10165       GL_UNSIGNED_INT_8_8_8_8_REV,
   10166       surface,
   10167       plane);
   10168 
   10169   if (err != kCGLNoError) {
   10170     LOCAL_SET_GL_ERROR(
   10171         GL_INVALID_OPERATION,
   10172         "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
   10173     return;
   10174   }
   10175 
   10176   texture_manager()->SetLevelInfo(
   10177       texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
   10178       GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
   10179 
   10180 #else
   10181   LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   10182              "glTexImageIOSurface2DCHROMIUM", "not supported.");
   10183 #endif
   10184 }
   10185 
   10186 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
   10187   switch (internalformat) {
   10188     case GL_RGB565:
   10189       return GL_RGB;
   10190     case GL_RGBA4:
   10191       return GL_RGBA;
   10192     case GL_RGB5_A1:
   10193       return GL_RGBA;
   10194     case GL_RGB8_OES:
   10195       return GL_RGB;
   10196     case GL_RGBA8_OES:
   10197       return GL_RGBA;
   10198     case GL_LUMINANCE8_ALPHA8_EXT:
   10199       return GL_LUMINANCE_ALPHA;
   10200     case GL_LUMINANCE8_EXT:
   10201       return GL_LUMINANCE;
   10202     case GL_ALPHA8_EXT:
   10203       return GL_ALPHA;
   10204     case GL_RGBA32F_EXT:
   10205       return GL_RGBA;
   10206     case GL_RGB32F_EXT:
   10207       return GL_RGB;
   10208     case GL_ALPHA32F_EXT:
   10209       return GL_ALPHA;
   10210     case GL_LUMINANCE32F_EXT:
   10211       return GL_LUMINANCE;
   10212     case GL_LUMINANCE_ALPHA32F_EXT:
   10213       return GL_LUMINANCE_ALPHA;
   10214     case GL_RGBA16F_EXT:
   10215       return GL_RGBA;
   10216     case GL_RGB16F_EXT:
   10217       return GL_RGB;
   10218     case GL_ALPHA16F_EXT:
   10219       return GL_ALPHA;
   10220     case GL_LUMINANCE16F_EXT:
   10221       return GL_LUMINANCE;
   10222     case GL_LUMINANCE_ALPHA16F_EXT:
   10223       return GL_LUMINANCE_ALPHA;
   10224     case GL_BGRA8_EXT:
   10225       return GL_BGRA_EXT;
   10226     default:
   10227       return GL_NONE;
   10228   }
   10229 }
   10230 
   10231 void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
   10232     GLenum target, GLuint source_id, GLuint dest_id, GLint level,
   10233     GLenum internal_format, GLenum dest_type) {
   10234   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
   10235 
   10236   TextureRef* dest_texture_ref = GetTexture(dest_id);
   10237   TextureRef* source_texture_ref = GetTexture(source_id);
   10238 
   10239   if (!source_texture_ref || !dest_texture_ref) {
   10240     LOCAL_SET_GL_ERROR(
   10241         GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
   10242     return;
   10243   }
   10244 
   10245   if (GL_TEXTURE_2D != target) {
   10246     LOCAL_SET_GL_ERROR(
   10247         GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
   10248     return;
   10249   }
   10250 
   10251   Texture* source_texture = source_texture_ref->texture();
   10252   Texture* dest_texture = dest_texture_ref->texture();
   10253   if (dest_texture->target() != GL_TEXTURE_2D ||
   10254       (source_texture->target() != GL_TEXTURE_2D &&
   10255        source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
   10256        source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
   10257     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
   10258                        "glCopyTextureCHROMIUM",
   10259                        "invalid texture target binding");
   10260     return;
   10261   }
   10262 
   10263   int source_width, source_height, dest_width, dest_height;
   10264 
   10265   gfx::GLImage* image =
   10266       source_texture->GetLevelImage(source_texture->target(), 0);
   10267   if (image) {
   10268     gfx::Size size = image->GetSize();
   10269     source_width = size.width();
   10270     source_height = size.height();
   10271     if (source_width <= 0 || source_height <= 0) {
   10272       LOCAL_SET_GL_ERROR(
   10273           GL_INVALID_VALUE,
   10274           "glCopyTextureChromium", "invalid image size");
   10275       return;
   10276     }
   10277   } else {
   10278     if (!source_texture->GetLevelSize(
   10279              source_texture->target(), 0, &source_width, &source_height)) {
   10280       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
   10281                          "glCopyTextureChromium",
   10282                          "source texture has no level 0");
   10283       return;
   10284     }
   10285 
   10286     // Check that this type of texture is allowed.
   10287     if (!texture_manager()->ValidForTarget(
   10288              source_texture->target(), level, source_width, source_height, 1)) {
   10289       LOCAL_SET_GL_ERROR(
   10290           GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
   10291       return;
   10292     }
   10293   }
   10294 
   10295   // Clear the source texture if necessary.
   10296   if (!texture_manager()->ClearTextureLevel(
   10297           this, source_texture_ref, source_texture->target(), 0)) {
   10298     LOCAL_SET_GL_ERROR(
   10299         GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
   10300     return;
   10301   }
   10302 
   10303   GLenum source_type = 0;
   10304   GLenum source_internal_format = 0;
   10305   source_texture->GetLevelType(
   10306       source_texture->target(), 0, &source_type, &source_internal_format);
   10307 
   10308   // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
   10309   // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
   10310   // renderable on some platforms.
   10311   bool valid_dest_format = internal_format == GL_RGB ||
   10312                            internal_format == GL_RGBA ||
   10313                            internal_format == GL_BGRA_EXT;
   10314   bool valid_source_format = source_internal_format == GL_ALPHA ||
   10315                              source_internal_format == GL_RGB ||
   10316                              source_internal_format == GL_RGBA ||
   10317                              source_internal_format == GL_LUMINANCE ||
   10318                              source_internal_format == GL_LUMINANCE_ALPHA ||
   10319                              source_internal_format == GL_BGRA_EXT;
   10320   if (!valid_source_format || !valid_dest_format) {
   10321     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   10322                        "glCopyTextureCHROMIUM",
   10323                        "invalid internal format");
   10324     return;
   10325   }
   10326 
   10327   // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
   10328   // needed because it takes 10s of milliseconds to initialize.
   10329   if (!copy_texture_CHROMIUM_.get()) {
   10330     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
   10331     copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
   10332     copy_texture_CHROMIUM_->Initialize(this);
   10333     RestoreCurrentFramebufferBindings();
   10334     if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
   10335       return;
   10336   }
   10337 
   10338   GLenum dest_type_previous = dest_type;
   10339   GLenum dest_internal_format = internal_format;
   10340   bool dest_level_defined = dest_texture->GetLevelSize(
   10341       GL_TEXTURE_2D, level, &dest_width, &dest_height);
   10342 
   10343   if (dest_level_defined) {
   10344     dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
   10345                                &dest_internal_format);
   10346   }
   10347 
   10348   // Resize the destination texture to the dimensions of the source texture.
   10349   if (!dest_level_defined || dest_width != source_width ||
   10350       dest_height != source_height ||
   10351       dest_internal_format != internal_format ||
   10352       dest_type_previous != dest_type) {
   10353     // Ensure that the glTexImage2D succeeds.
   10354     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
   10355     glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
   10356     glTexImage2D(
   10357         GL_TEXTURE_2D, level, internal_format, source_width, source_height,
   10358         0, internal_format, dest_type, NULL);
   10359     GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
   10360     if (error != GL_NO_ERROR) {
   10361       RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
   10362       return;
   10363     }
   10364 
   10365     texture_manager()->SetLevelInfo(
   10366         dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
   10367         source_height, 1, 0, internal_format, dest_type, true);
   10368   } else {
   10369     texture_manager()->SetLevelCleared(
   10370         dest_texture_ref, GL_TEXTURE_2D, level, true);
   10371   }
   10372 
   10373   ScopedModifyPixels modify(dest_texture_ref);
   10374 
   10375   // Try using GLImage::CopyTexImage when possible.
   10376   bool unpack_premultiply_alpha_change =
   10377       unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
   10378   if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
   10379     glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
   10380     if (image->CopyTexImage(GL_TEXTURE_2D))
   10381       return;
   10382   }
   10383 
   10384   DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
   10385 
   10386   // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
   10387   // before presenting.
   10388   if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
   10389     // TODO(hkuang): get the StreamTexture transform matrix in GPU process
   10390     // instead of using default matrix crbug.com/226218.
   10391     const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
   10392                                                0.0f, 1.0f, 0.0f, 0.0f,
   10393                                                0.0f, 0.0f, 1.0f, 0.0f,
   10394                                                0.0f, 0.0f, 0.0f, 1.0f};
   10395     copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
   10396         this,
   10397         source_texture->target(),
   10398         source_texture->service_id(),
   10399         dest_texture->service_id(),
   10400         level,
   10401         source_width,
   10402         source_height,
   10403         unpack_flip_y_,
   10404         unpack_premultiply_alpha_,
   10405         unpack_unpremultiply_alpha_,
   10406         default_matrix);
   10407   } else {
   10408     copy_texture_CHROMIUM_->DoCopyTexture(this,
   10409                                           source_texture->target(),
   10410                                           source_texture->service_id(),
   10411                                           source_internal_format,
   10412                                           dest_texture->service_id(),
   10413                                           level,
   10414                                           internal_format,
   10415                                           source_width,
   10416                                           source_height,
   10417                                           unpack_flip_y_,
   10418                                           unpack_premultiply_alpha_,
   10419                                           unpack_unpremultiply_alpha_);
   10420   }
   10421 
   10422   DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
   10423 }
   10424 
   10425 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
   10426   switch (internalformat) {
   10427     case GL_RGB565:
   10428       return GL_UNSIGNED_SHORT_5_6_5;
   10429     case GL_RGBA4:
   10430       return GL_UNSIGNED_SHORT_4_4_4_4;
   10431     case GL_RGB5_A1:
   10432       return GL_UNSIGNED_SHORT_5_5_5_1;
   10433     case GL_RGB8_OES:
   10434       return GL_UNSIGNED_BYTE;
   10435     case GL_RGBA8_OES:
   10436       return GL_UNSIGNED_BYTE;
   10437     case GL_LUMINANCE8_ALPHA8_EXT:
   10438       return GL_UNSIGNED_BYTE;
   10439     case GL_LUMINANCE8_EXT:
   10440       return GL_UNSIGNED_BYTE;
   10441     case GL_ALPHA8_EXT:
   10442       return GL_UNSIGNED_BYTE;
   10443     case GL_RGBA32F_EXT:
   10444       return GL_FLOAT;
   10445     case GL_RGB32F_EXT:
   10446       return GL_FLOAT;
   10447     case GL_ALPHA32F_EXT:
   10448       return GL_FLOAT;
   10449     case GL_LUMINANCE32F_EXT:
   10450       return GL_FLOAT;
   10451     case GL_LUMINANCE_ALPHA32F_EXT:
   10452       return GL_FLOAT;
   10453     case GL_RGBA16F_EXT:
   10454       return GL_HALF_FLOAT_OES;
   10455     case GL_RGB16F_EXT:
   10456       return GL_HALF_FLOAT_OES;
   10457     case GL_ALPHA16F_EXT:
   10458       return GL_HALF_FLOAT_OES;
   10459     case GL_LUMINANCE16F_EXT:
   10460       return GL_HALF_FLOAT_OES;
   10461     case GL_LUMINANCE_ALPHA16F_EXT:
   10462       return GL_HALF_FLOAT_OES;
   10463     case GL_BGRA8_EXT:
   10464       return GL_UNSIGNED_BYTE;
   10465     default:
   10466       return GL_NONE;
   10467   }
   10468 }
   10469 
   10470 void GLES2DecoderImpl::DoTexStorage2DEXT(
   10471     GLenum target,
   10472     GLint levels,
   10473     GLenum internal_format,
   10474     GLsizei width,
   10475     GLsizei height) {
   10476   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
   10477       "width", width, "height", height);
   10478   if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
   10479       TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
   10480     LOCAL_SET_GL_ERROR(
   10481         GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
   10482     return;
   10483   }
   10484   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   10485       &state_, target);
   10486   if (!texture_ref) {
   10487     LOCAL_SET_GL_ERROR(
   10488         GL_INVALID_OPERATION,
   10489         "glTexStorage2DEXT", "unknown texture for target");
   10490     return;
   10491   }
   10492   Texture* texture = texture_ref->texture();
   10493   if (texture->IsAttachedToFramebuffer()) {
   10494     framebuffer_state_.clear_state_dirty = true;
   10495   }
   10496   if (texture->IsImmutable()) {
   10497     LOCAL_SET_GL_ERROR(
   10498         GL_INVALID_OPERATION,
   10499         "glTexStorage2DEXT", "texture is immutable");
   10500     return;
   10501   }
   10502 
   10503   GLenum format = ExtractFormatFromStorageFormat(internal_format);
   10504   GLenum type = ExtractTypeFromStorageFormat(internal_format);
   10505 
   10506   {
   10507     GLsizei level_width = width;
   10508     GLsizei level_height = height;
   10509     uint32 estimated_size = 0;
   10510     for (int ii = 0; ii < levels; ++ii) {
   10511       uint32 level_size = 0;
   10512       if (!GLES2Util::ComputeImageDataSizes(
   10513           level_width, level_height, format, type, state_.unpack_alignment,
   10514           &estimated_size, NULL, NULL) ||
   10515           !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
   10516         LOCAL_SET_GL_ERROR(
   10517             GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
   10518         return;
   10519       }
   10520       level_width = std::max(1, level_width >> 1);
   10521       level_height = std::max(1, level_height >> 1);
   10522     }
   10523     if (!EnsureGPUMemoryAvailable(estimated_size)) {
   10524       LOCAL_SET_GL_ERROR(
   10525           GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
   10526       return;
   10527     }
   10528   }
   10529 
   10530   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
   10531   glTexStorage2DEXT(target, levels, internal_format, width, height);
   10532   GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
   10533   if (error == GL_NO_ERROR) {
   10534     GLsizei level_width = width;
   10535     GLsizei level_height = height;
   10536     for (int ii = 0; ii < levels; ++ii) {
   10537       texture_manager()->SetLevelInfo(
   10538           texture_ref, target, ii, format,
   10539           level_width, level_height, 1, 0, format, type, false);
   10540       level_width = std::max(1, level_width >> 1);
   10541       level_height = std::max(1, level_height >> 1);
   10542     }
   10543     texture->SetImmutable(true);
   10544   }
   10545 }
   10546 
   10547 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
   10548     uint32 immediate_data_size,
   10549     const void* cmd_data) {
   10550   return error::kUnknownCommand;
   10551 }
   10552 
   10553 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
   10554                                                 const GLbyte* data) {
   10555   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
   10556       "context", logger_.GetLogPrefix(),
   10557       "mailbox[0]", static_cast<unsigned char>(data[0]));
   10558 
   10559   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   10560       &state_, target);
   10561   ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
   10562 }
   10563 
   10564 void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
   10565     GLenum target, const GLbyte* data) {
   10566   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
   10567       "context", logger_.GetLogPrefix(),
   10568       "mailbox[0]", static_cast<unsigned char>(data[0]));
   10569 
   10570   ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
   10571       target, data);
   10572 }
   10573 
   10574 void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
   10575     TextureRef* texture_ref, GLenum target, const GLbyte* data) {
   10576   const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
   10577   DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
   10578                                        "mailbox that was not generated by "
   10579                                        "GenMailboxCHROMIUM.";
   10580 
   10581   if (!texture_ref) {
   10582     LOCAL_SET_GL_ERROR(
   10583         GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
   10584     return;
   10585   }
   10586 
   10587   Texture* produced = texture_manager()->Produce(texture_ref);
   10588   if (!produced) {
   10589     LOCAL_SET_GL_ERROR(
   10590         GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
   10591     return;
   10592   }
   10593 
   10594   if (produced->target() != target) {
   10595     LOCAL_SET_GL_ERROR(
   10596         GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
   10597     return;
   10598   }
   10599 
   10600   group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
   10601 }
   10602 
   10603 void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
   10604                                                 const GLbyte* data) {
   10605   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
   10606       "context", logger_.GetLogPrefix(),
   10607       "mailbox[0]", static_cast<unsigned char>(data[0]));
   10608   const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
   10609   DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
   10610                                        "mailbox that was not generated by "
   10611                                        "GenMailboxCHROMIUM.";
   10612 
   10613   scoped_refptr<TextureRef> texture_ref =
   10614       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
   10615   if (!texture_ref.get()) {
   10616     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   10617                        "glConsumeTextureCHROMIUM",
   10618                        "unknown texture for target");
   10619     return;
   10620   }
   10621   GLuint client_id = texture_ref->client_id();
   10622   if (!client_id) {
   10623     LOCAL_SET_GL_ERROR(
   10624         GL_INVALID_OPERATION,
   10625         "glConsumeTextureCHROMIUM", "unknown texture for target");
   10626     return;
   10627   }
   10628   Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
   10629   if (!texture) {
   10630     LOCAL_SET_GL_ERROR(
   10631         GL_INVALID_OPERATION,
   10632         "glConsumeTextureCHROMIUM", "invalid mailbox name");
   10633     return;
   10634   }
   10635   if (texture->target() != target) {
   10636     LOCAL_SET_GL_ERROR(
   10637         GL_INVALID_OPERATION,
   10638         "glConsumeTextureCHROMIUM", "invalid target");
   10639     return;
   10640   }
   10641 
   10642   DeleteTexturesHelper(1, &client_id);
   10643   texture_ref = texture_manager()->Consume(client_id, texture);
   10644   glBindTexture(target, texture_ref->service_id());
   10645 
   10646   TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
   10647   unit.bind_target = target;
   10648   switch (target) {
   10649     case GL_TEXTURE_2D:
   10650       unit.bound_texture_2d = texture_ref;
   10651       break;
   10652     case GL_TEXTURE_CUBE_MAP:
   10653       unit.bound_texture_cube_map = texture_ref;
   10654       break;
   10655     case GL_TEXTURE_EXTERNAL_OES:
   10656       unit.bound_texture_external_oes = texture_ref;
   10657       break;
   10658     case GL_TEXTURE_RECTANGLE_ARB:
   10659       unit.bound_texture_rectangle_arb = texture_ref;
   10660       break;
   10661     default:
   10662       NOTREACHED();  // Validation should prevent us getting here.
   10663       break;
   10664   }
   10665 }
   10666 
   10667 error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
   10668     uint32_t immediate_data_size,
   10669     const void* cmd_data) {
   10670   const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
   10671       *static_cast<
   10672           const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
   10673           cmd_data);
   10674   GLenum target = static_cast<GLenum>(c.target);
   10675   uint32_t data_size;
   10676   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
   10677     return error::kOutOfBounds;
   10678   }
   10679   if (data_size > immediate_data_size) {
   10680     return error::kOutOfBounds;
   10681   }
   10682   const GLbyte* mailbox =
   10683       GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
   10684   if (!validators_->texture_bind_target.IsValid(target)) {
   10685     LOCAL_SET_GL_ERROR_INVALID_ENUM(
   10686         "glCreateAndConsumeTextureCHROMIUM", target, "target");
   10687     return error::kNoError;
   10688   }
   10689   if (mailbox == NULL) {
   10690     return error::kOutOfBounds;
   10691   }
   10692   uint32_t client_id = c.client_id;
   10693   DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
   10694   return error::kNoError;
   10695 }
   10696 
   10697 void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
   10698     const GLbyte* data, GLuint client_id) {
   10699   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
   10700       "context", logger_.GetLogPrefix(),
   10701       "mailbox[0]", static_cast<unsigned char>(data[0]));
   10702   const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
   10703   DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
   10704                                        "passed a mailbox that was not "
   10705                                        "generated by GenMailboxCHROMIUM.";
   10706 
   10707   TextureRef* texture_ref = GetTexture(client_id);
   10708   if (texture_ref) {
   10709     LOCAL_SET_GL_ERROR(
   10710         GL_INVALID_OPERATION,
   10711         "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
   10712     return;
   10713   }
   10714   Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
   10715   if (!texture) {
   10716     LOCAL_SET_GL_ERROR(
   10717         GL_INVALID_OPERATION,
   10718         "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
   10719     return;
   10720   }
   10721   if (texture->target() != target) {
   10722     LOCAL_SET_GL_ERROR(
   10723         GL_INVALID_OPERATION,
   10724         "glCreateAndConsumeTextureCHROMIUM", "invalid target");
   10725     return;
   10726   }
   10727 
   10728   IdAllocatorInterface* id_allocator =
   10729       group_->GetIdAllocator(id_namespaces::kTextures);
   10730   id_allocator->MarkAsUsed(client_id);
   10731 
   10732   texture_ref = texture_manager()->Consume(client_id, texture);
   10733 }
   10734 
   10735 void GLES2DecoderImpl::DoInsertEventMarkerEXT(
   10736     GLsizei length, const GLchar* marker) {
   10737   if (!marker) {
   10738     marker = "";
   10739   }
   10740   debug_marker_manager_.SetMarker(
   10741       length ? std::string(marker, length) : std::string(marker));
   10742 }
   10743 
   10744 void GLES2DecoderImpl::DoPushGroupMarkerEXT(
   10745     GLsizei length, const GLchar* marker) {
   10746   if (!marker) {
   10747     marker = "";
   10748   }
   10749   std::string name = length ? std::string(marker, length) : std::string(marker);
   10750   debug_marker_manager_.PushGroup(name);
   10751   gpu_tracer_->Begin(name, kTraceGroupMarker);
   10752 }
   10753 
   10754 void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
   10755   debug_marker_manager_.PopGroup();
   10756   gpu_tracer_->End(kTraceGroupMarker);
   10757 }
   10758 
   10759 void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
   10760     GLenum target, GLint image_id) {
   10761   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
   10762 
   10763   if (target == GL_TEXTURE_CUBE_MAP) {
   10764     LOCAL_SET_GL_ERROR(
   10765         GL_INVALID_ENUM,
   10766         "glBindTexImage2DCHROMIUM", "invalid target");
   10767     return;
   10768   }
   10769 
   10770   // Default target might be conceptually valid, but disallow it to avoid
   10771   // accidents.
   10772   TextureRef* texture_ref =
   10773       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
   10774   if (!texture_ref) {
   10775     LOCAL_SET_GL_ERROR(
   10776         GL_INVALID_OPERATION,
   10777         "glBindTexImage2DCHROMIUM", "no texture bound");
   10778     return;
   10779   }
   10780 
   10781   gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
   10782   if (!gl_image) {
   10783     LOCAL_SET_GL_ERROR(
   10784         GL_INVALID_OPERATION,
   10785         "glBindTexImage2DCHROMIUM", "no image found with the given ID");
   10786     return;
   10787   }
   10788 
   10789   {
   10790     ScopedGLErrorSuppressor suppressor(
   10791         "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
   10792     if (!gl_image->BindTexImage(target)) {
   10793       LOCAL_SET_GL_ERROR(
   10794           GL_INVALID_OPERATION,
   10795           "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
   10796       return;
   10797     }
   10798   }
   10799 
   10800   gfx::Size size = gl_image->GetSize();
   10801   texture_manager()->SetLevelInfo(
   10802       texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
   10803       GL_RGBA, GL_UNSIGNED_BYTE, true);
   10804   texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
   10805 }
   10806 
   10807 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
   10808     GLenum target, GLint image_id) {
   10809   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
   10810 
   10811   // Default target might be conceptually valid, but disallow it to avoid
   10812   // accidents.
   10813   TextureRef* texture_ref =
   10814       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
   10815   if (!texture_ref) {
   10816     LOCAL_SET_GL_ERROR(
   10817         GL_INVALID_OPERATION,
   10818         "glReleaseTexImage2DCHROMIUM", "no texture bound");
   10819     return;
   10820   }
   10821 
   10822   gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
   10823   if (!gl_image) {
   10824     LOCAL_SET_GL_ERROR(
   10825         GL_INVALID_OPERATION,
   10826         "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
   10827     return;
   10828   }
   10829 
   10830   // Do nothing when image is not currently bound.
   10831   if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
   10832     return;
   10833 
   10834   {
   10835     ScopedGLErrorSuppressor suppressor(
   10836         "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
   10837     gl_image->ReleaseTexImage(target);
   10838   }
   10839 
   10840   texture_manager()->SetLevelInfo(
   10841       texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
   10842       GL_RGBA, GL_UNSIGNED_BYTE, false);
   10843 }
   10844 
   10845 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
   10846     uint32 immediate_data_size,
   10847     const void* cmd_data) {
   10848   const gles2::cmds::TraceBeginCHROMIUM& c =
   10849       *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
   10850   Bucket* bucket = GetBucket(c.bucket_id);
   10851   if (!bucket || bucket->size() == 0) {
   10852     return error::kInvalidArguments;
   10853   }
   10854   std::string command_name;
   10855   if (!bucket->GetAsString(&command_name)) {
   10856     return error::kInvalidArguments;
   10857   }
   10858   TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
   10859   if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
   10860     LOCAL_SET_GL_ERROR(
   10861         GL_INVALID_OPERATION,
   10862         "glTraceBeginCHROMIUM", "unable to create begin trace");
   10863     return error::kNoError;
   10864   }
   10865   return error::kNoError;
   10866 }
   10867 
   10868 void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
   10869   if (gpu_tracer_->CurrentName().empty()) {
   10870     LOCAL_SET_GL_ERROR(
   10871         GL_INVALID_OPERATION,
   10872         "glTraceEndCHROMIUM", "no trace begin found");
   10873     return;
   10874   }
   10875   TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
   10876   gpu_tracer_->End(kTraceCHROMIUM);
   10877 }
   10878 
   10879 void GLES2DecoderImpl::DoDrawBuffersEXT(
   10880     GLsizei count, const GLenum* bufs) {
   10881   if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
   10882     LOCAL_SET_GL_ERROR(
   10883         GL_INVALID_VALUE,
   10884         "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
   10885     return;
   10886   }
   10887 
   10888   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
   10889   if (framebuffer) {
   10890     for (GLsizei i = 0; i < count; ++i) {
   10891       if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
   10892           bufs[i] != GL_NONE) {
   10893         LOCAL_SET_GL_ERROR(
   10894             GL_INVALID_OPERATION,
   10895             "glDrawBuffersEXT",
   10896             "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
   10897         return;
   10898       }
   10899     }
   10900     glDrawBuffersARB(count, bufs);
   10901     framebuffer->SetDrawBuffers(count, bufs);
   10902   } else {  // backbuffer
   10903     if (count > 1 ||
   10904         (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
   10905       LOCAL_SET_GL_ERROR(
   10906           GL_INVALID_OPERATION,
   10907           "glDrawBuffersEXT",
   10908           "more than one buffer or bufs not GL_NONE or GL_BACK");
   10909       return;
   10910     }
   10911     GLenum mapped_buf = bufs[0];
   10912     if (GetBackbufferServiceId() != 0 &&  // emulated backbuffer
   10913         bufs[0] == GL_BACK) {
   10914       mapped_buf = GL_COLOR_ATTACHMENT0;
   10915     }
   10916     glDrawBuffersARB(count, &mapped_buf);
   10917     group_->set_draw_buffer(bufs[0]);
   10918   }
   10919 }
   10920 
   10921 void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
   10922   group_->LoseContexts(other);
   10923   reset_status_ = current;
   10924   current_decoder_error_ = error::kLostContext;
   10925 }
   10926 
   10927 void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
   10928                                              const GLfloat* matrix) {
   10929   DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
   10930          matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
   10931   if (!features().chromium_path_rendering) {
   10932     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   10933                        "glMatrixLoadfCHROMIUM",
   10934                        "function not available");
   10935     return;
   10936   }
   10937 
   10938   GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
   10939                                ? state_.projection_matrix
   10940                                : state_.modelview_matrix;
   10941   memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
   10942   // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
   10943   // since the values of the _NV and _CHROMIUM tokens match.
   10944   glMatrixLoadfEXT(matrix_mode, matrix);
   10945 }
   10946 
   10947 void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
   10948   DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
   10949          matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
   10950 
   10951   if (!features().chromium_path_rendering) {
   10952     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
   10953                        "glMatrixLoadIdentityCHROMIUM",
   10954                        "function not available");
   10955     return;
   10956   }
   10957 
   10958   static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   10959                                         0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
   10960                                         0.0f, 0.0f, 0.0f, 1.0f};
   10961 
   10962   GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
   10963                                ? state_.projection_matrix
   10964                                : state_.modelview_matrix;
   10965   memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
   10966   // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
   10967   // since the values of the _NV and _CHROMIUM tokens match.
   10968   glMatrixLoadIdentityEXT(matrix_mode);
   10969 }
   10970 
   10971 bool GLES2DecoderImpl::ValidateAsyncTransfer(
   10972     const char* function_name,
   10973     TextureRef* texture_ref,
   10974     GLenum target,
   10975     GLint level,
   10976     const void * data) {
   10977   // We only support async uploads to 2D textures for now.
   10978   if (GL_TEXTURE_2D != target) {
   10979     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
   10980     return false;
   10981   }
   10982   // We only support uploads to level zero for now.
   10983   if (level != 0) {
   10984     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
   10985     return false;
   10986   }
   10987   // A transfer buffer must be bound, even for asyncTexImage2D.
   10988   if (data == NULL) {
   10989     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
   10990     return false;
   10991   }
   10992   // We only support one async transfer in progress.
   10993   if (!texture_ref ||
   10994       async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
   10995     LOCAL_SET_GL_ERROR(
   10996         GL_INVALID_OPERATION,
   10997         function_name, "transfer already in progress");
   10998     return false;
   10999   }
   11000   return true;
   11001 }
   11002 
   11003 base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
   11004     uint32 async_upload_token,
   11005     uint32 sync_data_shm_id,
   11006     uint32 sync_data_shm_offset) {
   11007   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
   11008   if (!buffer.get() ||
   11009       !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
   11010     return base::Closure();
   11011 
   11012   AsyncMemoryParams mem_params(buffer,
   11013                                sync_data_shm_offset,
   11014                                sizeof(AsyncUploadSync));
   11015 
   11016   scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
   11017       new AsyncUploadTokenCompletionObserver(async_upload_token));
   11018 
   11019   return base::Bind(
   11020       &AsyncPixelTransferManager::AsyncNotifyCompletion,
   11021       base::Unretained(GetAsyncPixelTransferManager()),
   11022       mem_params,
   11023       observer);
   11024 }
   11025 
   11026 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
   11027     uint32 immediate_data_size,
   11028     const void* cmd_data) {
   11029   const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
   11030       *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
   11031   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
   11032   GLenum target = static_cast<GLenum>(c.target);
   11033   GLint level = static_cast<GLint>(c.level);
   11034   GLenum internal_format = static_cast<GLenum>(c.internalformat);
   11035   GLsizei width = static_cast<GLsizei>(c.width);
   11036   GLsizei height = static_cast<GLsizei>(c.height);
   11037   GLint border = static_cast<GLint>(c.border);
   11038   GLenum format = static_cast<GLenum>(c.format);
   11039   GLenum type = static_cast<GLenum>(c.type);
   11040   uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
   11041   uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
   11042   uint32 pixels_size;
   11043   uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
   11044   uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
   11045   uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
   11046 
   11047   base::ScopedClosureRunner scoped_completion_callback;
   11048   if (async_upload_token) {
   11049     base::Closure completion_closure =
   11050         AsyncUploadTokenCompletionClosure(async_upload_token,
   11051                                           sync_data_shm_id,
   11052                                           sync_data_shm_offset);
   11053     if (completion_closure.is_null())
   11054       return error::kInvalidArguments;
   11055 
   11056     scoped_completion_callback.Reset(completion_closure);
   11057   }
   11058 
   11059   // TODO(epenner): Move this and copies of this memory validation
   11060   // into ValidateTexImage2D step.
   11061   if (!GLES2Util::ComputeImageDataSizes(
   11062       width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
   11063       NULL)) {
   11064     return error::kOutOfBounds;
   11065   }
   11066   const void* pixels = NULL;
   11067   if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
   11068     pixels = GetSharedMemoryAs<const void*>(
   11069         pixels_shm_id, pixels_shm_offset, pixels_size);
   11070     if (!pixels) {
   11071       return error::kOutOfBounds;
   11072     }
   11073   }
   11074 
   11075   TextureManager::DoTextImage2DArguments args = {
   11076     target, level, internal_format, width, height, border, format, type,
   11077     pixels, pixels_size};
   11078   TextureRef* texture_ref;
   11079   // All the normal glTexSubImage2D validation.
   11080   if (!texture_manager()->ValidateTexImage2D(
   11081       &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
   11082     return error::kNoError;
   11083   }
   11084 
   11085   // Extra async validation.
   11086   Texture* texture = texture_ref->texture();
   11087   if (!ValidateAsyncTransfer(
   11088       "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
   11089     return error::kNoError;
   11090 
   11091   // Don't allow async redefinition of a textures.
   11092   if (texture->IsDefined()) {
   11093     LOCAL_SET_GL_ERROR(
   11094         GL_INVALID_OPERATION,
   11095         "glAsyncTexImage2DCHROMIUM", "already defined");
   11096     return error::kNoError;
   11097   }
   11098 
   11099   if (!EnsureGPUMemoryAvailable(pixels_size)) {
   11100     LOCAL_SET_GL_ERROR(
   11101         GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
   11102     return error::kNoError;
   11103   }
   11104 
   11105   // Setup the parameters.
   11106   AsyncTexImage2DParams tex_params = {
   11107       target, level, static_cast<GLenum>(internal_format),
   11108       width, height, border, format, type};
   11109   AsyncMemoryParams mem_params(
   11110       GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
   11111 
   11112   // Set up the async state if needed, and make the texture
   11113   // immutable so the async state stays valid. The level info
   11114   // is set up lazily when the transfer completes.
   11115   AsyncPixelTransferDelegate* delegate =
   11116       async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
   11117                                                                  tex_params);
   11118   texture->SetImmutable(true);
   11119 
   11120   delegate->AsyncTexImage2D(
   11121       tex_params,
   11122       mem_params,
   11123       base::Bind(&TextureManager::SetLevelInfoFromParams,
   11124                  // The callback is only invoked if the transfer delegate still
   11125                  // exists, which implies through manager->texture_ref->state
   11126                  // ownership that both of these pointers are valid.
   11127                  base::Unretained(texture_manager()),
   11128                  base::Unretained(texture_ref),
   11129                  tex_params));
   11130   return error::kNoError;
   11131 }
   11132 
   11133 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
   11134     uint32 immediate_data_size,
   11135     const void* cmd_data) {
   11136   const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
   11137       *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
   11138   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
   11139   GLenum target = static_cast<GLenum>(c.target);
   11140   GLint level = static_cast<GLint>(c.level);
   11141   GLint xoffset = static_cast<GLint>(c.xoffset);
   11142   GLint yoffset = static_cast<GLint>(c.yoffset);
   11143   GLsizei width = static_cast<GLsizei>(c.width);
   11144   GLsizei height = static_cast<GLsizei>(c.height);
   11145   GLenum format = static_cast<GLenum>(c.format);
   11146   GLenum type = static_cast<GLenum>(c.type);
   11147   uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
   11148   uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
   11149   uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
   11150 
   11151   base::ScopedClosureRunner scoped_completion_callback;
   11152   if (async_upload_token) {
   11153     base::Closure completion_closure =
   11154         AsyncUploadTokenCompletionClosure(async_upload_token,
   11155                                           sync_data_shm_id,
   11156                                           sync_data_shm_offset);
   11157     if (completion_closure.is_null())
   11158       return error::kInvalidArguments;
   11159 
   11160     scoped_completion_callback.Reset(completion_closure);
   11161   }
   11162 
   11163   // TODO(epenner): Move this and copies of this memory validation
   11164   // into ValidateTexSubImage2D step.
   11165   uint32 data_size;
   11166   if (!GLES2Util::ComputeImageDataSizes(
   11167       width, height, format, type, state_.unpack_alignment, &data_size,
   11168       NULL, NULL)) {
   11169     return error::kOutOfBounds;
   11170   }
   11171   const void* pixels = GetSharedMemoryAs<const void*>(
   11172       c.data_shm_id, c.data_shm_offset, data_size);
   11173 
   11174   // All the normal glTexSubImage2D validation.
   11175   error::Error error = error::kNoError;
   11176   if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
   11177       target, level, xoffset, yoffset, width, height, format, type, pixels)) {
   11178     return error;
   11179   }
   11180 
   11181   // Extra async validation.
   11182   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   11183       &state_, target);
   11184   Texture* texture = texture_ref->texture();
   11185   if (!ValidateAsyncTransfer(
   11186          "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
   11187     return error::kNoError;
   11188 
   11189   // Guarantee async textures are always 'cleared' as follows:
   11190   // - AsyncTexImage2D can not redefine an existing texture
   11191   // - AsyncTexImage2D must initialize the entire image via non-null buffer.
   11192   // - AsyncTexSubImage2D clears synchronously if not already cleared.
   11193   // - Textures become immutable after an async call.
   11194   // This way we know in all cases that an async texture is always clear.
   11195   if (!texture->SafeToRenderFrom()) {
   11196     if (!texture_manager()->ClearTextureLevel(this, texture_ref,
   11197                                               target, level)) {
   11198       LOCAL_SET_GL_ERROR(
   11199           GL_OUT_OF_MEMORY,
   11200           "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
   11201       return error::kNoError;
   11202     }
   11203   }
   11204 
   11205   // Setup the parameters.
   11206   AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
   11207                                               width, height, format, type};
   11208   AsyncMemoryParams mem_params(
   11209       GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
   11210   AsyncPixelTransferDelegate* delegate =
   11211       async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
   11212   if (!delegate) {
   11213     // TODO(epenner): We may want to enforce exclusive use
   11214     // of async APIs in which case this should become an error,
   11215     // (the texture should have been async defined).
   11216     AsyncTexImage2DParams define_params = {target, level,
   11217                                                 0, 0, 0, 0, 0, 0};
   11218     texture->GetLevelSize(target, level, &define_params.width,
   11219                                          &define_params.height);
   11220     texture->GetLevelType(target, level, &define_params.type,
   11221                                          &define_params.internal_format);
   11222     // Set up the async state if needed, and make the texture
   11223     // immutable so the async state stays valid.
   11224     delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
   11225         texture_ref, define_params);
   11226     texture->SetImmutable(true);
   11227   }
   11228 
   11229   delegate->AsyncTexSubImage2D(tex_params, mem_params);
   11230   return error::kNoError;
   11231 }
   11232 
   11233 error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
   11234     uint32 immediate_data_size,
   11235     const void* cmd_data) {
   11236   const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
   11237       *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
   11238   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
   11239   GLenum target = static_cast<GLenum>(c.target);
   11240 
   11241   if (GL_TEXTURE_2D != target) {
   11242     LOCAL_SET_GL_ERROR(
   11243         GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
   11244     return error::kNoError;
   11245   }
   11246   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
   11247       &state_, target);
   11248   if (!texture_ref) {
   11249       LOCAL_SET_GL_ERROR(
   11250           GL_INVALID_OPERATION,
   11251           "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
   11252     return error::kNoError;
   11253   }
   11254   AsyncPixelTransferDelegate* delegate =
   11255       async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
   11256   if (!delegate) {
   11257       LOCAL_SET_GL_ERROR(
   11258           GL_INVALID_OPERATION,
   11259           "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
   11260     return error::kNoError;
   11261   }
   11262   delegate->WaitForTransferCompletion();
   11263   ProcessFinishedAsyncTransfers();
   11264   return error::kNoError;
   11265 }
   11266 
   11267 error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
   11268     uint32 immediate_data_size,
   11269     const void* data) {
   11270   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
   11271 
   11272   GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
   11273   ProcessFinishedAsyncTransfers();
   11274   return error::kNoError;
   11275 }
   11276 
   11277 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
   11278     TextureRef* texture_ref) {
   11279   Texture* texture = texture_ref->texture();
   11280   DoDidUseTexImageIfNeeded(texture, texture->target());
   11281 }
   11282 
   11283 void GLES2DecoderImpl::OnOutOfMemoryError() {
   11284   if (lose_context_when_out_of_memory_) {
   11285     group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
   11286     LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
   11287   }
   11288 }
   11289 
   11290 // Include the auto-generated part of this file. We split this because it means
   11291 // we can easily edit the non-auto generated parts right here in this file
   11292 // instead of having to edit some template or the code generator.
   11293 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
   11294 
   11295 }  // namespace gles2
   11296 }  // namespace gpu
   11297