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