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