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