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