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