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