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