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