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