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/float_util.h"
23#include "base/memory/scoped_ptr.h"
24#include "base/numerics/safe_math.h"
25#include "base/strings/string_number_conversions.h"
26#include "base/strings/string_split.h"
27#include "build/build_config.h"
28#define GLES2_GPU_SERVICE 1
29#include "gpu/command_buffer/common/debug_marker_manager.h"
30#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
32#include "gpu/command_buffer/common/id_allocator.h"
33#include "gpu/command_buffer/common/mailbox.h"
34#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
36#include "gpu/command_buffer/service/buffer_manager.h"
37#include "gpu/command_buffer/service/cmd_buffer_engine.h"
38#include "gpu/command_buffer/service/context_group.h"
39#include "gpu/command_buffer/service/context_state.h"
40#include "gpu/command_buffer/service/error_state.h"
41#include "gpu/command_buffer/service/feature_info.h"
42#include "gpu/command_buffer/service/framebuffer_manager.h"
43#include "gpu/command_buffer/service/gl_utils.h"
44#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
45#include "gpu/command_buffer/service/gles2_cmd_validation.h"
46#include "gpu/command_buffer/service/gpu_state_tracer.h"
47#include "gpu/command_buffer/service/gpu_switches.h"
48#include "gpu/command_buffer/service/gpu_tracer.h"
49#include "gpu/command_buffer/service/image_manager.h"
50#include "gpu/command_buffer/service/mailbox_manager.h"
51#include "gpu/command_buffer/service/memory_tracking.h"
52#include "gpu/command_buffer/service/program_manager.h"
53#include "gpu/command_buffer/service/query_manager.h"
54#include "gpu/command_buffer/service/renderbuffer_manager.h"
55#include "gpu/command_buffer/service/shader_manager.h"
56#include "gpu/command_buffer/service/shader_translator.h"
57#include "gpu/command_buffer/service/shader_translator_cache.h"
58#include "gpu/command_buffer/service/texture_manager.h"
59#include "gpu/command_buffer/service/vertex_array_manager.h"
60#include "gpu/command_buffer/service/vertex_attrib_manager.h"
61#include "third_party/smhasher/src/City.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 <IOSurface/IOSurfaceAPI.h>
69// Note that this must be included after gl_bindings.h to avoid conflicts.
70#include <OpenGL/CGLIOSurface.h>
71#endif
72
73#if defined(OS_WIN)
74#include "base/win/win_util.h"
75#endif
76
77namespace gpu {
78namespace gles2 {
79
80namespace {
81
82static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
83static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
84static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
85static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
86
87static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
88                                            GLint rangeMax,
89                                            GLint precision) {
90  return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
91}
92
93static void GetShaderPrecisionFormatImpl(GLenum shader_type,
94                                         GLenum precision_type,
95                                         GLint *range, GLint *precision) {
96  switch (precision_type) {
97    case GL_LOW_INT:
98    case GL_MEDIUM_INT:
99    case GL_HIGH_INT:
100      // These values are for a 32-bit twos-complement integer format.
101      range[0] = 31;
102      range[1] = 30;
103      *precision = 0;
104      break;
105    case GL_LOW_FLOAT:
106    case GL_MEDIUM_FLOAT:
107    case GL_HIGH_FLOAT:
108      // These values are for an IEEE single-precision floating-point format.
109      range[0] = 127;
110      range[1] = 127;
111      *precision = 23;
112      break;
113    default:
114      NOTREACHED();
115      break;
116  }
117
118  if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
119      gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
120    // This function is sometimes defined even though it's really just
121    // a stub, so we need to set range and precision as if it weren't
122    // defined before calling it.
123    // On Mac OS with some GPUs, calling this generates a
124    // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
125    // platforms.
126    glGetShaderPrecisionFormat(shader_type, precision_type,
127                               range, precision);
128
129    // TODO(brianderson): Make the following official workarounds.
130
131    // Some drivers have bugs where they report the ranges as a negative number.
132    // Taking the absolute value here shouldn't hurt because negative numbers
133    // aren't expected anyway.
134    range[0] = abs(range[0]);
135    range[1] = abs(range[1]);
136
137    // If the driver reports a precision for highp float that isn't actually
138    // highp, don't pretend like it's supported because shader compilation will
139    // fail anyway.
140    if (precision_type == GL_HIGH_FLOAT &&
141        !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
142      range[0] = 0;
143      range[1] = 0;
144      *precision = 0;
145    }
146  }
147}
148
149static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
150  switch (plane_transform) {
151    case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
152      return gfx::OVERLAY_TRANSFORM_NONE;
153    case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
154      return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
155    case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
156      return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
157    case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
158      return gfx::OVERLAY_TRANSFORM_ROTATE_90;
159    case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
160      return gfx::OVERLAY_TRANSFORM_ROTATE_180;
161    case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
162      return gfx::OVERLAY_TRANSFORM_ROTATE_270;
163    default:
164      return gfx::OVERLAY_TRANSFORM_INVALID;
165  }
166}
167
168}  // namespace
169
170class GLES2DecoderImpl;
171
172// Local versions of the SET_GL_ERROR macros
173#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
174    ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
175#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
176    ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
177                                         function_name, value, label)
178#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
179    ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
180                                          function_name, pname)
181#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
182    ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
183                                              function_name)
184#define LOCAL_PEEK_GL_ERROR(function_name) \
185    ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
186#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
187    ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
188#define LOCAL_PERFORMANCE_WARNING(msg) \
189    PerformanceWarning(__FILE__, __LINE__, msg)
190#define LOCAL_RENDER_WARNING(msg) \
191    RenderWarning(__FILE__, __LINE__, msg)
192
193// Check that certain assumptions the code makes are true. There are places in
194// the code where shared memory is passed direclty to GL. Example, glUniformiv,
195// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
196// a few others) are 32bits. If they are not 32bits the code will have to change
197// to call those GL functions with service side memory and then copy the results
198// to shared memory, converting the sizes.
199COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32),  // NOLINT
200               GLint_not_same_size_as_uint32);
201COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32),  // NOLINT
202               GLint_not_same_size_as_uint32);
203COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float),  // NOLINT
204               GLfloat_not_same_size_as_float);
205
206// TODO(kbr): the use of this anonymous namespace core dumps the
207// linker on Mac OS X 10.6 when the symbol ordering file is used
208// namespace {
209
210// Returns the address of the first byte after a struct.
211template <typename T>
212const void* AddressAfterStruct(const T& pod) {
213  return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
214}
215
216// Returns the address of the frst byte after the struct or NULL if size >
217// immediate_data_size.
218template <typename RETURN_TYPE, typename COMMAND_TYPE>
219RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
220                               uint32 size,
221                               uint32 immediate_data_size) {
222  return (size <= immediate_data_size) ?
223      static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
224      NULL;
225}
226
227// Computes the data size for certain gl commands like glUniform.
228bool ComputeDataSize(
229    GLuint count,
230    size_t size,
231    unsigned int elements_per_unit,
232    uint32* dst) {
233  uint32 value;
234  if (!SafeMultiplyUint32(count, size, &value)) {
235    return false;
236  }
237  if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
238    return false;
239  }
240  *dst = value;
241  return true;
242}
243
244// Return true if a character belongs to the ASCII subset as defined in
245// GLSL ES 1.0 spec section 3.1.
246static bool CharacterIsValidForGLES(unsigned char c) {
247  // Printing characters are valid except " $ ` @ \ ' DEL.
248  if (c >= 32 && c <= 126 &&
249      c != '"' &&
250      c != '$' &&
251      c != '`' &&
252      c != '@' &&
253      c != '\\' &&
254      c != '\'') {
255    return true;
256  }
257  // Horizontal tab, line feed, vertical tab, form feed, carriage return
258  // are also valid.
259  if (c >= 9 && c <= 13) {
260    return true;
261  }
262
263  return false;
264}
265
266static bool StringIsValidForGLES(const char* str) {
267  for (; *str; ++str) {
268    if (!CharacterIsValidForGLES(*str)) {
269      return false;
270    }
271  }
272  return true;
273}
274
275// This class prevents any GL errors that occur when it is in scope from
276// being reported to the client.
277class ScopedGLErrorSuppressor {
278 public:
279  explicit ScopedGLErrorSuppressor(
280      const char* function_name, ErrorState* error_state);
281  ~ScopedGLErrorSuppressor();
282 private:
283  const char* function_name_;
284  ErrorState* error_state_;
285  DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
286};
287
288// Temporarily changes a decoder's bound texture and restore it when this
289// object goes out of scope. Also temporarily switches to using active texture
290// unit zero in case the client has changed that to something invalid.
291class ScopedTextureBinder {
292 public:
293  explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
294  ~ScopedTextureBinder();
295
296 private:
297  ContextState* state_;
298  GLenum target_;
299  DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
300};
301
302// Temporarily changes a decoder's bound render buffer and restore it when this
303// object goes out of scope.
304class ScopedRenderBufferBinder {
305 public:
306  explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
307  ~ScopedRenderBufferBinder();
308
309 private:
310  ContextState* state_;
311  DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
312};
313
314// Temporarily changes a decoder's bound frame buffer and restore it when this
315// object goes out of scope.
316class ScopedFrameBufferBinder {
317 public:
318  explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
319  ~ScopedFrameBufferBinder();
320
321 private:
322  GLES2DecoderImpl* decoder_;
323  DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
324};
325
326// Temporarily changes a decoder's bound frame buffer to a resolved version of
327// the multisampled offscreen render buffer if that buffer is multisampled, and,
328// if it is bound or enforce_internal_framebuffer is true. If internal is
329// true, the resolved framebuffer is not visible to the parent.
330class ScopedResolvedFrameBufferBinder {
331 public:
332  explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
333                                           bool enforce_internal_framebuffer,
334                                           bool internal);
335  ~ScopedResolvedFrameBufferBinder();
336
337 private:
338  GLES2DecoderImpl* decoder_;
339  bool resolve_and_bind_;
340  DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
341};
342
343class ScopedModifyPixels {
344 public:
345  explicit ScopedModifyPixels(TextureRef* ref);
346  ~ScopedModifyPixels();
347
348 private:
349  TextureRef* ref_;
350};
351
352ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
353  if (ref_)
354    ref_->texture()->OnWillModifyPixels();
355}
356
357ScopedModifyPixels::~ScopedModifyPixels() {
358  if (ref_)
359    ref_->texture()->OnDidModifyPixels();
360}
361
362class ScopedRenderTo {
363 public:
364  explicit ScopedRenderTo(Framebuffer* framebuffer);
365  ~ScopedRenderTo();
366
367 private:
368  const Framebuffer* framebuffer_;
369};
370
371ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
372    : framebuffer_(framebuffer) {
373  if (framebuffer)
374    framebuffer_->OnWillRenderTo();
375}
376
377ScopedRenderTo::~ScopedRenderTo() {
378  if (framebuffer_)
379    framebuffer_->OnDidRenderTo();
380}
381
382// Encapsulates an OpenGL texture.
383class BackTexture {
384 public:
385  explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
386  ~BackTexture();
387
388  // Create a new render texture.
389  void Create();
390
391  // Set the initial size and format of a render texture or resize it.
392  bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
393
394  // Copy the contents of the currently bound frame buffer.
395  void Copy(const gfx::Size& size, GLenum format);
396
397  // Destroy the render texture. This must be explicitly called before
398  // destroying this object.
399  void Destroy();
400
401  // Invalidate the texture. This can be used when a context is lost and it is
402  // not possible to make it current in order to free the resource.
403  void Invalidate();
404
405  GLuint id() const {
406    return id_;
407  }
408
409  gfx::Size size() const {
410    return size_;
411  }
412
413 private:
414  MemoryTypeTracker memory_tracker_;
415  ContextState* state_;
416  size_t bytes_allocated_;
417  GLuint id_;
418  gfx::Size size_;
419  DISALLOW_COPY_AND_ASSIGN(BackTexture);
420};
421
422// Encapsulates an OpenGL render buffer of any format.
423class BackRenderbuffer {
424 public:
425  explicit BackRenderbuffer(
426      RenderbufferManager* renderbuffer_manager,
427      MemoryTracker* memory_tracker,
428      ContextState* state);
429  ~BackRenderbuffer();
430
431  // Create a new render buffer.
432  void Create();
433
434  // Set the initial size and format of a render buffer or resize it.
435  bool AllocateStorage(const FeatureInfo* feature_info,
436                       const gfx::Size& size,
437                       GLenum format,
438                       GLsizei samples);
439
440  // Destroy the render buffer. This must be explicitly called before destroying
441  // this object.
442  void Destroy();
443
444  // Invalidate the render buffer. This can be used when a context is lost and
445  // it is not possible to make it current in order to free the resource.
446  void Invalidate();
447
448  GLuint id() const {
449    return id_;
450  }
451
452 private:
453  RenderbufferManager* renderbuffer_manager_;
454  MemoryTypeTracker memory_tracker_;
455  ContextState* state_;
456  size_t bytes_allocated_;
457  GLuint id_;
458  DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
459};
460
461// Encapsulates an OpenGL frame buffer.
462class BackFramebuffer {
463 public:
464  explicit BackFramebuffer(GLES2DecoderImpl* decoder);
465  ~BackFramebuffer();
466
467  // Create a new frame buffer.
468  void Create();
469
470  // Attach a color render buffer to a frame buffer.
471  void AttachRenderTexture(BackTexture* texture);
472
473  // Attach a render buffer to a frame buffer. Note that this unbinds any
474  // currently bound frame buffer.
475  void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
476
477  // Destroy the frame buffer. This must be explicitly called before destroying
478  // this object.
479  void Destroy();
480
481  // Invalidate the frame buffer. This can be used when a context is lost and it
482  // is not possible to make it current in order to free the resource.
483  void Invalidate();
484
485  // See glCheckFramebufferStatusEXT.
486  GLenum CheckStatus();
487
488  GLuint id() const {
489    return id_;
490  }
491
492 private:
493  GLES2DecoderImpl* decoder_;
494  GLuint id_;
495  DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
496};
497
498struct FenceCallback {
499  explicit FenceCallback()
500      : fence(gfx::GLFence::Create()) {
501    DCHECK(fence);
502  }
503  std::vector<base::Closure> callbacks;
504  scoped_ptr<gfx::GLFence> fence;
505};
506
507class AsyncUploadTokenCompletionObserver
508    : public AsyncPixelTransferCompletionObserver {
509 public:
510  explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
511      : async_upload_token_(async_upload_token) {
512  }
513
514  virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
515    DCHECK(mem_params.buffer().get());
516    void* data = mem_params.GetDataAddress();
517    AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
518    sync->SetAsyncUploadToken(async_upload_token_);
519  }
520
521 private:
522  virtual ~AsyncUploadTokenCompletionObserver() {
523  }
524
525  uint32 async_upload_token_;
526
527  DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
528};
529
530// }  // anonymous namespace.
531
532// static
533const unsigned int GLES2Decoder::kDefaultStencilMask =
534    static_cast<unsigned int>(-1);
535
536bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
537                                       uint32* service_texture_id) {
538  return false;
539}
540
541GLES2Decoder::GLES2Decoder()
542    : initialized_(false),
543      debug_(false),
544      log_commands_(false) {
545}
546
547GLES2Decoder::~GLES2Decoder() {
548}
549
550void GLES2Decoder::BeginDecoding() {}
551
552void GLES2Decoder::EndDecoding() {}
553
554// This class implements GLES2Decoder so we don't have to expose all the GLES2
555// cmd stuff to outside this class.
556class GLES2DecoderImpl : public GLES2Decoder,
557                         public FramebufferManager::TextureDetachObserver,
558                         public ErrorStateClient {
559 public:
560  explicit GLES2DecoderImpl(ContextGroup* group);
561  virtual ~GLES2DecoderImpl();
562
563  // Overridden from AsyncAPIInterface.
564  virtual Error DoCommand(unsigned int command,
565                          unsigned int arg_count,
566                          const void* args) OVERRIDE;
567
568  virtual error::Error DoCommands(unsigned int num_commands,
569                                  const void* buffer,
570                                  int num_entries,
571                                  int* entries_processed) OVERRIDE;
572
573  template <bool DebugImpl>
574  error::Error DoCommandsImpl(unsigned int num_commands,
575                              const void* buffer,
576                              int num_entries,
577                              int* entries_processed);
578
579  // Overridden from AsyncAPIInterface.
580  virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
581
582  // Overridden from GLES2Decoder.
583  virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584                          const scoped_refptr<gfx::GLContext>& context,
585                          bool offscreen,
586                          const gfx::Size& size,
587                          const DisallowedFeatures& disallowed_features,
588                          const std::vector<int32>& attribs) OVERRIDE;
589  virtual void Destroy(bool have_context) OVERRIDE;
590  virtual void SetSurface(
591      const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
592  virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
593  virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
594  void UpdateParentTextureInfo();
595  virtual bool MakeCurrent() OVERRIDE;
596  virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
597  virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
598  virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
599  virtual Capabilities GetCapabilities() OVERRIDE;
600  virtual void RestoreState(const ContextState* prev_state) OVERRIDE;
601
602  virtual void RestoreActiveTexture() const OVERRIDE {
603    state_.RestoreActiveTexture();
604  }
605  virtual void RestoreAllTextureUnitBindings(
606      const ContextState* prev_state) const OVERRIDE {
607    state_.RestoreAllTextureUnitBindings(prev_state);
608  }
609  virtual void RestoreActiveTextureUnitBinding(
610      unsigned int target) const OVERRIDE {
611    state_.RestoreActiveTextureUnitBinding(target);
612  }
613  virtual void RestoreBufferBindings() const OVERRIDE {
614    state_.RestoreBufferBindings();
615  }
616  virtual void RestoreGlobalState() const OVERRIDE {
617    state_.RestoreGlobalState(NULL);
618  }
619  virtual void RestoreProgramBindings() const OVERRIDE {
620    state_.RestoreProgramBindings();
621  }
622  virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
623    state_.RestoreTextureUnitBindings(unit, NULL);
624  }
625  virtual void RestoreFramebufferBindings() const OVERRIDE;
626  virtual void RestoreRenderbufferBindings() OVERRIDE;
627  virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
628
629  virtual void ClearAllAttributes() const OVERRIDE;
630  virtual void RestoreAllAttributes() const OVERRIDE;
631
632  virtual QueryManager* GetQueryManager() OVERRIDE {
633    return query_manager_.get();
634  }
635  virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
636    return vertex_array_manager_.get();
637  }
638  virtual ImageManager* GetImageManager() OVERRIDE {
639    return image_manager_.get();
640  }
641  virtual bool ProcessPendingQueries() OVERRIDE;
642  virtual bool HasMoreIdleWork() OVERRIDE;
643  virtual void PerformIdleWork() OVERRIDE;
644
645  virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
646
647  virtual void SetResizeCallback(
648      const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
649
650  virtual Logger* GetLogger() OVERRIDE;
651
652  virtual void BeginDecoding() OVERRIDE;
653  virtual void EndDecoding() OVERRIDE;
654
655  virtual ErrorState* GetErrorState() OVERRIDE;
656  virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
657
658  virtual void SetShaderCacheCallback(
659      const ShaderCacheCallback& callback) OVERRIDE;
660  virtual void SetWaitSyncPointCallback(
661      const WaitSyncPointCallback& callback) OVERRIDE;
662
663  virtual AsyncPixelTransferManager*
664      GetAsyncPixelTransferManager() OVERRIDE;
665  virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
666  virtual void SetAsyncPixelTransferManagerForTest(
667      AsyncPixelTransferManager* manager) OVERRIDE;
668  virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
669  void ProcessFinishedAsyncTransfers();
670
671  virtual bool GetServiceTextureId(uint32 client_texture_id,
672                                   uint32* service_texture_id) OVERRIDE;
673
674  virtual uint32 GetTextureUploadCount() OVERRIDE;
675  virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
676  virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
677  virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
678
679  // Restores the current state to the user's settings.
680  void RestoreCurrentFramebufferBindings();
681
682  // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
683  void ApplyDirtyState();
684
685  // These check the state of the currently bound framebuffer or the
686  // backbuffer if no framebuffer is bound.
687  // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
688  // check with all attached and enabled color attachments.
689  bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
690  bool BoundFramebufferHasDepthAttachment();
691  bool BoundFramebufferHasStencilAttachment();
692
693  virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
694
695  // Overridden from FramebufferManager::TextureDetachObserver:
696  virtual void OnTextureRefDetachedFromFramebuffer(
697      TextureRef* texture) OVERRIDE;
698
699  // Overriden from ErrorStateClient.
700  virtual void OnOutOfMemoryError() OVERRIDE;
701
702  // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
703  void EnsureRenderbufferBound();
704
705  // Helpers to facilitate calling into compatible extensions.
706  static void RenderbufferStorageMultisampleHelper(
707      const FeatureInfo* feature_info,
708      GLenum target,
709      GLsizei samples,
710      GLenum internal_format,
711      GLsizei width,
712      GLsizei height);
713
714  void BlitFramebufferHelper(GLint srcX0,
715                             GLint srcY0,
716                             GLint srcX1,
717                             GLint srcY1,
718                             GLint dstX0,
719                             GLint dstY0,
720                             GLint dstX1,
721                             GLint dstY1,
722                             GLbitfield mask,
723                             GLenum filter);
724
725 private:
726  friend class ScopedFrameBufferBinder;
727  friend class ScopedResolvedFrameBufferBinder;
728  friend class BackFramebuffer;
729
730  // Initialize or re-initialize the shader translator.
731  bool InitializeShaderTranslator();
732
733  void UpdateCapabilities();
734
735  // Helpers for the glGen and glDelete functions.
736  bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
737  void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
738  bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
739  void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
740  bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
741  void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
742  bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
743  void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
744  bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
745  void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
746  bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
747  void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
748
749  // Helper for async upload token completion notification callback.
750  base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
751                                                  uint32 sync_data_shm_id,
752                                                  uint32 sync_data_shm_offset);
753
754
755
756  // Workarounds
757  void OnFboChanged() const;
758  void OnUseFramebuffer() const;
759
760  // TODO(gman): Cache these pointers?
761  BufferManager* buffer_manager() {
762    return group_->buffer_manager();
763  }
764
765  RenderbufferManager* renderbuffer_manager() {
766    return group_->renderbuffer_manager();
767  }
768
769  FramebufferManager* framebuffer_manager() {
770    return group_->framebuffer_manager();
771  }
772
773  ProgramManager* program_manager() {
774    return group_->program_manager();
775  }
776
777  ShaderManager* shader_manager() {
778    return group_->shader_manager();
779  }
780
781  ShaderTranslatorCache* shader_translator_cache() {
782    return group_->shader_translator_cache();
783  }
784
785  const TextureManager* texture_manager() const {
786    return group_->texture_manager();
787  }
788
789  TextureManager* texture_manager() {
790    return group_->texture_manager();
791  }
792
793  MailboxManager* mailbox_manager() {
794    return group_->mailbox_manager();
795  }
796
797  ImageManager* image_manager() { return image_manager_.get(); }
798
799  VertexArrayManager* vertex_array_manager() {
800    return vertex_array_manager_.get();
801  }
802
803  MemoryTracker* memory_tracker() {
804    return group_->memory_tracker();
805  }
806
807  bool EnsureGPUMemoryAvailable(size_t estimated_size) {
808    MemoryTracker* tracker = memory_tracker();
809    if (tracker) {
810      return tracker->EnsureGPUMemoryAvailable(estimated_size);
811    }
812    return true;
813  }
814
815  bool IsOffscreenBufferMultisampled() const {
816    return offscreen_target_samples_ > 1;
817  }
818
819  // Creates a Texture for the given texture.
820  TextureRef* CreateTexture(
821      GLuint client_id, GLuint service_id) {
822    return texture_manager()->CreateTexture(client_id, service_id);
823  }
824
825  // Gets the texture info for the given texture. Returns NULL if none exists.
826  TextureRef* GetTexture(GLuint client_id) const {
827    return texture_manager()->GetTexture(client_id);
828  }
829
830  // Deletes the texture info for the given texture.
831  void RemoveTexture(GLuint client_id) {
832    texture_manager()->RemoveTexture(client_id);
833  }
834
835  // Get the size (in pixels) of the currently bound frame buffer (either FBO
836  // or regular back buffer).
837  gfx::Size GetBoundReadFrameBufferSize();
838
839  // Get the format of the currently bound frame buffer (either FBO or regular
840  // back buffer)
841  GLenum GetBoundReadFrameBufferTextureType();
842  GLenum GetBoundReadFrameBufferInternalFormat();
843  GLenum GetBoundDrawFrameBufferInternalFormat();
844
845  // Wrapper for CompressedTexImage2D commands.
846  error::Error DoCompressedTexImage2D(
847      GLenum target,
848      GLint level,
849      GLenum internal_format,
850      GLsizei width,
851      GLsizei height,
852      GLint border,
853      GLsizei image_size,
854      const void* data);
855
856  // Wrapper for CompressedTexSubImage2D.
857  void DoCompressedTexSubImage2D(
858      GLenum target,
859      GLint level,
860      GLint xoffset,
861      GLint yoffset,
862      GLsizei width,
863      GLsizei height,
864      GLenum format,
865      GLsizei imageSize,
866      const void * data);
867
868  // Wrapper for CopyTexImage2D.
869  void DoCopyTexImage2D(
870      GLenum target,
871      GLint level,
872      GLenum internal_format,
873      GLint x,
874      GLint y,
875      GLsizei width,
876      GLsizei height,
877      GLint border);
878
879  // Wrapper for SwapBuffers.
880  void DoSwapBuffers();
881
882  // Wrapper for CopyTexSubImage2D.
883  void DoCopyTexSubImage2D(
884      GLenum target,
885      GLint level,
886      GLint xoffset,
887      GLint yoffset,
888      GLint x,
889      GLint y,
890      GLsizei width,
891      GLsizei height);
892
893  // Validation for TexSubImage2D.
894  bool ValidateTexSubImage2D(
895      error::Error* error,
896      const char* function_name,
897      GLenum target,
898      GLint level,
899      GLint xoffset,
900      GLint yoffset,
901      GLsizei width,
902      GLsizei height,
903      GLenum format,
904      GLenum type,
905      const void * data);
906
907  // Wrapper for TexSubImage2D.
908  error::Error DoTexSubImage2D(
909      GLenum target,
910      GLint level,
911      GLint xoffset,
912      GLint yoffset,
913      GLsizei width,
914      GLsizei height,
915      GLenum format,
916      GLenum type,
917      const void * data);
918
919  // Extra validation for async tex(Sub)Image2D.
920  bool ValidateAsyncTransfer(
921      const char* function_name,
922      TextureRef* texture_ref,
923      GLenum target,
924      GLint level,
925      const void * data);
926
927  // Wrapper for TexImageIOSurface2DCHROMIUM.
928  void DoTexImageIOSurface2DCHROMIUM(
929      GLenum target,
930      GLsizei width,
931      GLsizei height,
932      GLuint io_surface_id,
933      GLuint plane);
934
935  void DoCopyTextureCHROMIUM(
936      GLenum target,
937      GLuint source_id,
938      GLuint target_id,
939      GLint level,
940      GLenum internal_format,
941      GLenum dest_type);
942
943  // Wrapper for TexStorage2DEXT.
944  void DoTexStorage2DEXT(
945      GLenum target,
946      GLint levels,
947      GLenum internal_format,
948      GLsizei width,
949      GLsizei height);
950
951  void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
952  void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
953      const GLbyte* key);
954  void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
955      GLenum target, const GLbyte* data);
956
957  void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
958  void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
959    GLuint client_id);
960
961  void DoBindTexImage2DCHROMIUM(
962      GLenum target,
963      GLint image_id);
964  void DoReleaseTexImage2DCHROMIUM(
965      GLenum target,
966      GLint image_id);
967
968  void DoTraceEndCHROMIUM(void);
969
970  void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
971
972  void DoLoseContextCHROMIUM(GLenum current, GLenum other);
973
974  void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
975  void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
976
977  // Creates a Program for the given program.
978  Program* CreateProgram(
979      GLuint client_id, GLuint service_id) {
980    return program_manager()->CreateProgram(client_id, service_id);
981  }
982
983  // Gets the program info for the given program. Returns NULL if none exists.
984  Program* GetProgram(GLuint client_id) {
985    return program_manager()->GetProgram(client_id);
986  }
987
988#if defined(NDEBUG)
989  void LogClientServiceMapping(
990      const char* /* function_name */,
991      GLuint /* client_id */,
992      GLuint /* service_id */) {
993  }
994  template<typename T>
995  void LogClientServiceForInfo(
996      T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
997  }
998#else
999  void LogClientServiceMapping(
1000      const char* function_name, GLuint client_id, GLuint service_id) {
1001    if (service_logging_) {
1002      VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1003              << ": client_id = " << client_id
1004              << ", service_id = " << service_id;
1005    }
1006  }
1007  template<typename T>
1008  void LogClientServiceForInfo(
1009      T* info, GLuint client_id, const char* function_name) {
1010    if (info) {
1011      LogClientServiceMapping(function_name, client_id, info->service_id());
1012    }
1013  }
1014#endif
1015
1016  // Gets the program info for the given program. If it's not a program
1017  // generates a GL error. Returns NULL if not program.
1018  Program* GetProgramInfoNotShader(
1019      GLuint client_id, const char* function_name) {
1020    Program* program = GetProgram(client_id);
1021    if (!program) {
1022      if (GetShader(client_id)) {
1023        LOCAL_SET_GL_ERROR(
1024            GL_INVALID_OPERATION, function_name, "shader passed for program");
1025      } else {
1026        LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
1027      }
1028    }
1029    LogClientServiceForInfo(program, client_id, function_name);
1030    return program;
1031  }
1032
1033
1034  // Creates a Shader for the given shader.
1035  Shader* CreateShader(
1036      GLuint client_id,
1037      GLuint service_id,
1038      GLenum shader_type) {
1039    return shader_manager()->CreateShader(
1040        client_id, service_id, shader_type);
1041  }
1042
1043  // Gets the shader info for the given shader. Returns NULL if none exists.
1044  Shader* GetShader(GLuint client_id) {
1045    return shader_manager()->GetShader(client_id);
1046  }
1047
1048  // Gets the shader info for the given shader. If it's not a shader generates a
1049  // GL error. Returns NULL if not shader.
1050  Shader* GetShaderInfoNotProgram(
1051      GLuint client_id, const char* function_name) {
1052    Shader* shader = GetShader(client_id);
1053    if (!shader) {
1054      if (GetProgram(client_id)) {
1055        LOCAL_SET_GL_ERROR(
1056            GL_INVALID_OPERATION, function_name, "program passed for shader");
1057      } else {
1058        LOCAL_SET_GL_ERROR(
1059            GL_INVALID_VALUE, function_name, "unknown shader");
1060      }
1061    }
1062    LogClientServiceForInfo(shader, client_id, function_name);
1063    return shader;
1064  }
1065
1066  // Creates a buffer info for the given buffer.
1067  void CreateBuffer(GLuint client_id, GLuint service_id) {
1068    return buffer_manager()->CreateBuffer(client_id, service_id);
1069  }
1070
1071  // Gets the buffer info for the given buffer.
1072  Buffer* GetBuffer(GLuint client_id) {
1073    Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1074    return buffer;
1075  }
1076
1077  // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1078  // on glDeleteBuffers so we can make sure the user does not try to render
1079  // with deleted buffers.
1080  void RemoveBuffer(GLuint client_id);
1081
1082  // Creates a framebuffer info for the given framebuffer.
1083  void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1084    return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
1085  }
1086
1087  // Gets the framebuffer info for the given framebuffer.
1088  Framebuffer* GetFramebuffer(GLuint client_id) {
1089    return framebuffer_manager()->GetFramebuffer(client_id);
1090  }
1091
1092  // Removes the framebuffer info for the given framebuffer.
1093  void RemoveFramebuffer(GLuint client_id) {
1094    framebuffer_manager()->RemoveFramebuffer(client_id);
1095  }
1096
1097  // Creates a renderbuffer info for the given renderbuffer.
1098  void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1099    return renderbuffer_manager()->CreateRenderbuffer(
1100        client_id, service_id);
1101  }
1102
1103  // Gets the renderbuffer info for the given renderbuffer.
1104  Renderbuffer* GetRenderbuffer(GLuint client_id) {
1105    return renderbuffer_manager()->GetRenderbuffer(client_id);
1106  }
1107
1108  // Removes the renderbuffer info for the given renderbuffer.
1109  void RemoveRenderbuffer(GLuint client_id) {
1110    renderbuffer_manager()->RemoveRenderbuffer(client_id);
1111  }
1112
1113  // Gets the vertex attrib manager for the given vertex array.
1114  VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1115    VertexAttribManager* info =
1116        vertex_array_manager()->GetVertexAttribManager(client_id);
1117    return info;
1118  }
1119
1120  // Removes the vertex attrib manager for the given vertex array.
1121  void RemoveVertexAttribManager(GLuint client_id) {
1122    vertex_array_manager()->RemoveVertexAttribManager(client_id);
1123  }
1124
1125  // Creates a vertex attrib manager for the given vertex array.
1126  scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1127      GLuint client_id,
1128      GLuint service_id,
1129      bool client_visible) {
1130    return vertex_array_manager()->CreateVertexAttribManager(
1131        client_id, service_id, group_->max_vertex_attribs(), client_visible);
1132  }
1133
1134  void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
1135  void DoBindUniformLocationCHROMIUM(
1136      GLuint client_id, GLint location, const char* name);
1137
1138  error::Error GetAttribLocationHelper(
1139    GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1140    const std::string& name_str);
1141
1142  error::Error GetUniformLocationHelper(
1143    GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1144    const std::string& name_str);
1145
1146  // Helper for glShaderSource.
1147  error::Error ShaderSourceHelper(
1148      GLuint client_id, const char* data, uint32 data_size);
1149
1150  // Clear any textures used by the current program.
1151  bool ClearUnclearedTextures();
1152
1153  // Clears any uncleared attachments attached to the given frame buffer.
1154  // Returns false if there was a generated GL error.
1155  void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
1156
1157  // overridden from GLES2Decoder
1158  virtual bool ClearLevel(unsigned service_id,
1159                          unsigned bind_target,
1160                          unsigned target,
1161                          int level,
1162                          unsigned internal_format,
1163                          unsigned format,
1164                          unsigned type,
1165                          int width,
1166                          int height,
1167                          bool is_texture_immutable) OVERRIDE;
1168
1169  // Restore all GL state that affects clearing.
1170  void RestoreClearState();
1171
1172  // Remembers the state of some capabilities.
1173  // Returns: true if glEnable/glDisable should actually be called.
1174  bool SetCapabilityState(GLenum cap, bool enabled);
1175
1176  // Check that the currently bound framebuffers are valid.
1177  // Generates GL error if not.
1178  bool CheckBoundFramebuffersValid(const char* func_name);
1179
1180  // Check that the currently bound read framebuffer has a color image
1181  // attached. Generates GL error if not.
1182  bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1183
1184  // Check if a framebuffer meets our requirements.
1185  bool CheckFramebufferValid(
1186      Framebuffer* framebuffer,
1187      GLenum target,
1188      const char* func_name);
1189
1190  // Checks if the current program exists and is valid. If not generates the
1191  // appropriate GL error.  Returns true if the current program is in a usable
1192  // state.
1193  bool CheckCurrentProgram(const char* function_name);
1194
1195  // Checks if the current program exists and is valid and that location is not
1196  // -1. If the current program is not valid generates the appropriate GL
1197  // error. Returns true if the current program is in a usable state and
1198  // location is not -1.
1199  bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1200
1201  // Gets the type of a uniform for a location in the current program. Sets GL
1202  // errors if the current program is not valid. Returns true if the current
1203  // program is valid and the location exists. Adjusts count so it
1204  // does not overflow the uniform.
1205  bool PrepForSetUniformByLocation(GLint fake_location,
1206                                   const char* function_name,
1207                                   Program::UniformApiType api_type,
1208                                   GLint* real_location,
1209                                   GLenum* type,
1210                                   GLsizei* count);
1211
1212  // Gets the service id for any simulated backbuffer fbo.
1213  GLuint GetBackbufferServiceId() const;
1214
1215  // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1216  bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1217
1218  // Helper for glGetVertexAttrib
1219  void GetVertexAttribHelper(
1220    const VertexAttrib* attrib, GLenum pname, GLint* param);
1221
1222  // Wrapper for glCreateProgram
1223  bool CreateProgramHelper(GLuint client_id);
1224
1225  // Wrapper for glCreateShader
1226  bool CreateShaderHelper(GLenum type, GLuint client_id);
1227
1228  // Wrapper for glActiveTexture
1229  void DoActiveTexture(GLenum texture_unit);
1230
1231  // Wrapper for glAttachShader
1232  void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1233
1234  // Wrapper for glBindBuffer since we need to track the current targets.
1235  void DoBindBuffer(GLenum target, GLuint buffer);
1236
1237  // Wrapper for glBindFramebuffer since we need to track the current targets.
1238  void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1239
1240  // Wrapper for glBindRenderbuffer since we need to track the current targets.
1241  void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1242
1243  // Wrapper for glBindTexture since we need to track the current targets.
1244  void DoBindTexture(GLenum target, GLuint texture);
1245
1246  // Wrapper for glBindVertexArrayOES
1247  void DoBindVertexArrayOES(GLuint array);
1248  void EmulateVertexArrayState();
1249
1250  // Wrapper for glBlitFramebufferCHROMIUM.
1251  void DoBlitFramebufferCHROMIUM(
1252      GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1253      GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1254      GLbitfield mask, GLenum filter);
1255
1256  // Wrapper for glBufferSubData.
1257  void DoBufferSubData(
1258    GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1259
1260  // Wrapper for glCheckFramebufferStatus
1261  GLenum DoCheckFramebufferStatus(GLenum target);
1262
1263  // Wrapper for glClear
1264  error::Error DoClear(GLbitfield mask);
1265
1266  // Wrappers for various state.
1267  void DoDepthRangef(GLclampf znear, GLclampf zfar);
1268  void DoSampleCoverage(GLclampf value, GLboolean invert);
1269
1270  // Wrapper for glCompileShader.
1271  void DoCompileShader(GLuint shader);
1272
1273  // Helper for DeleteSharedIdsCHROMIUM commands.
1274  void DoDeleteSharedIdsCHROMIUM(
1275      GLuint namespace_id, GLsizei n, const GLuint* ids);
1276
1277  // Wrapper for glDetachShader
1278  void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1279
1280  // Wrapper for glDisable
1281  void DoDisable(GLenum cap);
1282
1283  // Wrapper for glDisableVertexAttribArray.
1284  void DoDisableVertexAttribArray(GLuint index);
1285
1286  // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1287  // attachments.
1288  void DoDiscardFramebufferEXT(GLenum target,
1289                               GLsizei numAttachments,
1290                               const GLenum* attachments);
1291
1292  // Wrapper for glEnable
1293  void DoEnable(GLenum cap);
1294
1295  // Wrapper for glEnableVertexAttribArray.
1296  void DoEnableVertexAttribArray(GLuint index);
1297
1298  // Wrapper for glFinish.
1299  void DoFinish();
1300
1301  // Wrapper for glFlush.
1302  void DoFlush();
1303
1304  // Wrapper for glFramebufferRenderbufffer.
1305  void DoFramebufferRenderbuffer(
1306      GLenum target, GLenum attachment, GLenum renderbuffertarget,
1307      GLuint renderbuffer);
1308
1309  // Wrapper for glFramebufferTexture2D.
1310  void DoFramebufferTexture2D(
1311      GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1312      GLint level);
1313
1314  // Wrapper for glFramebufferTexture2DMultisampleEXT.
1315  void DoFramebufferTexture2DMultisample(
1316      GLenum target, GLenum attachment, GLenum textarget,
1317      GLuint texture, GLint level, GLsizei samples);
1318
1319  // Common implementation for both DoFramebufferTexture2D wrappers.
1320  void DoFramebufferTexture2DCommon(const char* name,
1321      GLenum target, GLenum attachment, GLenum textarget,
1322      GLuint texture, GLint level, GLsizei samples);
1323
1324  // Wrapper for glGenerateMipmap
1325  void DoGenerateMipmap(GLenum target);
1326
1327  // Helper for GenSharedIdsCHROMIUM commands.
1328  void DoGenSharedIdsCHROMIUM(
1329      GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1330
1331  // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1332  // to account for different pname values defined in different extension
1333  // variants.
1334  GLenum AdjustGetPname(GLenum pname);
1335
1336  // Wrapper for DoGetBooleanv.
1337  void DoGetBooleanv(GLenum pname, GLboolean* params);
1338
1339  // Wrapper for DoGetFloatv.
1340  void DoGetFloatv(GLenum pname, GLfloat* params);
1341
1342  // Wrapper for glGetFramebufferAttachmentParameteriv.
1343  void DoGetFramebufferAttachmentParameteriv(
1344      GLenum target, GLenum attachment, GLenum pname, GLint* params);
1345
1346  // Wrapper for glGetIntegerv.
1347  void DoGetIntegerv(GLenum pname, GLint* params);
1348
1349  // Gets the max value in a range in a buffer.
1350  GLuint DoGetMaxValueInBufferCHROMIUM(
1351      GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1352
1353  // Wrapper for glGetBufferParameteriv.
1354  void DoGetBufferParameteriv(
1355      GLenum target, GLenum pname, GLint* params);
1356
1357  // Wrapper for glGetProgramiv.
1358  void DoGetProgramiv(
1359      GLuint program_id, GLenum pname, GLint* params);
1360
1361  // Wrapper for glRenderbufferParameteriv.
1362  void DoGetRenderbufferParameteriv(
1363      GLenum target, GLenum pname, GLint* params);
1364
1365  // Wrapper for glGetShaderiv
1366  void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1367
1368  // Wrappers for glGetTexParameter.
1369  void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1370  void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1371  void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1372
1373  // Wrappers for glGetVertexAttrib.
1374  void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1375  void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1376
1377  // Wrappers for glIsXXX functions.
1378  bool DoIsEnabled(GLenum cap);
1379  bool DoIsBuffer(GLuint client_id);
1380  bool DoIsFramebuffer(GLuint client_id);
1381  bool DoIsProgram(GLuint client_id);
1382  bool DoIsRenderbuffer(GLuint client_id);
1383  bool DoIsShader(GLuint client_id);
1384  bool DoIsTexture(GLuint client_id);
1385  bool DoIsVertexArrayOES(GLuint client_id);
1386
1387  // Wrapper for glLinkProgram
1388  void DoLinkProgram(GLuint program);
1389
1390  // Helper for RegisterSharedIdsCHROMIUM.
1391  void DoRegisterSharedIdsCHROMIUM(
1392      GLuint namespace_id, GLsizei n, const GLuint* ids);
1393
1394  // Wrapper for glRenderbufferStorage.
1395  void DoRenderbufferStorage(
1396      GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
1397
1398  // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1399  void DoRenderbufferStorageMultisampleCHROMIUM(
1400      GLenum target, GLsizei samples, GLenum internalformat,
1401      GLsizei width, GLsizei height);
1402
1403  // Handler for glRenderbufferStorageMultisampleEXT
1404  // (multisampled_render_to_texture).
1405  void DoRenderbufferStorageMultisampleEXT(
1406      GLenum target, GLsizei samples, GLenum internalformat,
1407      GLsizei width, GLsizei height);
1408
1409  // Common validation for multisample extensions.
1410  bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1411                                              GLenum internalformat,
1412                                              GLsizei width,
1413                                              GLsizei height);
1414
1415  // Verifies that the currently bound multisample renderbuffer is valid
1416  // Very slow! Only done on platforms with driver bugs that return invalid
1417  // buffers under memory pressure
1418  bool VerifyMultisampleRenderbufferIntegrity(
1419      GLuint renderbuffer, GLenum format);
1420
1421  // Wrapper for glReleaseShaderCompiler.
1422  void DoReleaseShaderCompiler() { }
1423
1424  // Wrappers for glTexParameter functions.
1425  void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1426  void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1427  void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1428  void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1429
1430  // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1431  // spec only these 2 functions can be used to set sampler uniforms.
1432  void DoUniform1i(GLint fake_location, GLint v0);
1433  void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1434  void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1435  void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1436  void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
1437
1438  // Wrappers for glUniformfv because some drivers don't correctly accept
1439  // bool uniforms.
1440  void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1441  void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1442  void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1443  void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
1444
1445  void DoUniformMatrix2fv(
1446      GLint fake_location, GLsizei count, GLboolean transpose,
1447      const GLfloat* value);
1448  void DoUniformMatrix3fv(
1449      GLint fake_location, GLsizei count, GLboolean transpose,
1450      const GLfloat* value);
1451  void DoUniformMatrix4fv(
1452      GLint fake_location, GLsizei count, GLboolean transpose,
1453      const GLfloat* value);
1454
1455  bool SetVertexAttribValue(
1456    const char* function_name, GLuint index, const GLfloat* value);
1457
1458  // Wrappers for glVertexAttrib??
1459  void DoVertexAttrib1f(GLuint index, GLfloat v0);
1460  void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1461  void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1462  void DoVertexAttrib4f(
1463      GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1464  void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1465  void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1466  void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1467  void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1468
1469  // Wrapper for glViewport
1470  void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1471
1472  // Wrapper for glUseProgram
1473  void DoUseProgram(GLuint program);
1474
1475  // Wrapper for glValidateProgram.
1476  void DoValidateProgram(GLuint program_client_id);
1477
1478  void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1479  void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1480  void DoPopGroupMarkerEXT(void);
1481
1482  // Gets the number of values that will be returned by glGetXXX. Returns
1483  // false if pname is unknown.
1484  bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1485
1486  // Checks if the current program and vertex attributes are valid for drawing.
1487  bool IsDrawValid(
1488      const char* function_name, GLuint max_vertex_accessed, bool instanced,
1489      GLsizei primcount);
1490
1491  // Returns true if successful, simulated will be true if attrib0 was
1492  // simulated.
1493  bool SimulateAttrib0(
1494      const char* function_name, GLuint max_vertex_accessed, bool* simulated);
1495  void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
1496
1497  // If an image is bound to texture, this will call Will/DidUseTexImage
1498  // if needed.
1499  void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1500  void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1501
1502  // Returns false if textures were replaced.
1503  bool PrepareTexturesForRender();
1504  void RestoreStateForTextures();
1505
1506  // Returns true if GL_FIXED attribs were simulated.
1507  bool SimulateFixedAttribs(
1508      const char* function_name,
1509      GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
1510  void RestoreStateForSimulatedFixedAttribs();
1511
1512  // Handle DrawArrays and DrawElements for both instanced and non-instanced
1513  // cases (primcount is always 1 for non-instanced).
1514  error::Error DoDrawArrays(
1515      const char* function_name,
1516      bool instanced, GLenum mode, GLint first, GLsizei count,
1517      GLsizei primcount);
1518  error::Error DoDrawElements(
1519      const char* function_name,
1520      bool instanced, GLenum mode, GLsizei count, GLenum type,
1521      int32 offset, GLsizei primcount);
1522
1523  GLenum GetBindTargetForSamplerType(GLenum type) {
1524    DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
1525           type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1526    switch (type) {
1527      case GL_SAMPLER_2D:
1528        return GL_TEXTURE_2D;
1529      case GL_SAMPLER_CUBE:
1530        return GL_TEXTURE_CUBE_MAP;
1531      case GL_SAMPLER_EXTERNAL_OES:
1532        return GL_TEXTURE_EXTERNAL_OES;
1533      case GL_SAMPLER_2D_RECT_ARB:
1534        return GL_TEXTURE_RECTANGLE_ARB;
1535    }
1536
1537    NOTREACHED();
1538    return 0;
1539  }
1540
1541  // Gets the framebuffer info for a particular target.
1542  Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1543    Framebuffer* framebuffer = NULL;
1544    switch (target) {
1545      case GL_FRAMEBUFFER:
1546      case GL_DRAW_FRAMEBUFFER_EXT:
1547        framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
1548        break;
1549      case GL_READ_FRAMEBUFFER_EXT:
1550        framebuffer = framebuffer_state_.bound_read_framebuffer.get();
1551        break;
1552      default:
1553        NOTREACHED();
1554        break;
1555    }
1556    return framebuffer;
1557  }
1558
1559  Renderbuffer* GetRenderbufferInfoForTarget(
1560      GLenum target) {
1561    Renderbuffer* renderbuffer = NULL;
1562    switch (target) {
1563      case GL_RENDERBUFFER:
1564        renderbuffer = state_.bound_renderbuffer.get();
1565        break;
1566      default:
1567        NOTREACHED();
1568        break;
1569    }
1570    return renderbuffer;
1571  }
1572
1573  // Validates the program and location for a glGetUniform call and returns
1574  // a SizeResult setup to receive the result. Returns true if glGetUniform
1575  // should be called.
1576  bool GetUniformSetup(
1577      GLuint program, GLint fake_location,
1578      uint32 shm_id, uint32 shm_offset,
1579      error::Error* error, GLint* real_location, GLuint* service_id,
1580      void** result, GLenum* result_type);
1581
1582  virtual bool WasContextLost() OVERRIDE;
1583  virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
1584  virtual void LoseContext(uint32 reset_status) OVERRIDE;
1585
1586#if defined(OS_MACOSX)
1587  void ReleaseIOSurfaceForTexture(GLuint texture_id);
1588#endif
1589
1590  bool ValidateCompressedTexDimensions(
1591      const char* function_name,
1592      GLint level, GLsizei width, GLsizei height, GLenum format);
1593  bool ValidateCompressedTexFuncData(
1594      const char* function_name,
1595      GLsizei width, GLsizei height, GLenum format, size_t size);
1596  bool ValidateCompressedTexSubDimensions(
1597    const char* function_name,
1598    GLenum target, GLint level, GLint xoffset, GLint yoffset,
1599    GLsizei width, GLsizei height, GLenum format,
1600    Texture* texture);
1601
1602  void RenderWarning(const char* filename, int line, const std::string& msg);
1603  void PerformanceWarning(
1604      const char* filename, int line, const std::string& msg);
1605
1606  const FeatureInfo::FeatureFlags& features() const {
1607    return feature_info_->feature_flags();
1608  }
1609
1610  const FeatureInfo::Workarounds& workarounds() const {
1611    return feature_info_->workarounds();
1612  }
1613
1614  bool ShouldDeferDraws() {
1615    return !offscreen_target_frame_buffer_.get() &&
1616           framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
1617           surface_->DeferDraws();
1618  }
1619
1620  bool ShouldDeferReads() {
1621    return !offscreen_target_frame_buffer_.get() &&
1622           framebuffer_state_.bound_read_framebuffer.get() == NULL &&
1623           surface_->DeferDraws();
1624  }
1625
1626  error::Error WillAccessBoundFramebufferForDraw() {
1627    if (ShouldDeferDraws())
1628      return error::kDeferCommandUntilLater;
1629    if (!offscreen_target_frame_buffer_.get() &&
1630        !framebuffer_state_.bound_draw_framebuffer.get() &&
1631        !surface_->SetBackbufferAllocation(true))
1632      return error::kLostContext;
1633    return error::kNoError;
1634  }
1635
1636  error::Error WillAccessBoundFramebufferForRead() {
1637    if (ShouldDeferReads())
1638      return error::kDeferCommandUntilLater;
1639    if (!offscreen_target_frame_buffer_.get() &&
1640        !framebuffer_state_.bound_read_framebuffer.get() &&
1641        !surface_->SetBackbufferAllocation(true))
1642      return error::kLostContext;
1643    return error::kNoError;
1644  }
1645
1646  // Set remaining commands to process to 0 to force DoCommands to return
1647  // and allow context preemption and GPU watchdog checks in GpuScheduler().
1648  void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1649
1650  void ProcessPendingReadPixels();
1651  void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1652
1653  // Generate a member function prototype for each command in an automated and
1654  // typesafe way.
1655#define GLES2_CMD_OP(name) \
1656  Error Handle##name(uint32 immediate_data_size, const void* data);
1657
1658  GLES2_COMMAND_LIST(GLES2_CMD_OP)
1659
1660  #undef GLES2_CMD_OP
1661
1662  // The GL context this decoder renders to on behalf of the client.
1663  scoped_refptr<gfx::GLSurface> surface_;
1664  scoped_refptr<gfx::GLContext> context_;
1665
1666  // The ContextGroup for this decoder uses to track resources.
1667  scoped_refptr<ContextGroup> group_;
1668
1669  DebugMarkerManager debug_marker_manager_;
1670  Logger logger_;
1671
1672  // All the state for this context.
1673  ContextState state_;
1674
1675  // Current width and height of the offscreen frame buffer.
1676  gfx::Size offscreen_size_;
1677
1678  // Util to help with GL.
1679  GLES2Util util_;
1680
1681  // unpack flip y as last set by glPixelStorei
1682  bool unpack_flip_y_;
1683
1684  // unpack (un)premultiply alpha as last set by glPixelStorei
1685  bool unpack_premultiply_alpha_;
1686  bool unpack_unpremultiply_alpha_;
1687
1688  // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1689  GLuint attrib_0_buffer_id_;
1690
1691  // The value currently in attrib_0.
1692  Vec4 attrib_0_value_;
1693
1694  // Whether or not the attrib_0 buffer holds the attrib_0_value.
1695  bool attrib_0_buffer_matches_value_;
1696
1697  // The size of attrib 0.
1698  GLsizei attrib_0_size_;
1699
1700  // The buffer used to simulate GL_FIXED attribs.
1701  GLuint fixed_attrib_buffer_id_;
1702
1703  // The size of fiixed attrib buffer.
1704  GLsizei fixed_attrib_buffer_size_;
1705
1706  // The offscreen frame buffer that the client renders to. With EGL, the
1707  // depth and stencil buffers are separate. With regular GL there is a single
1708  // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1709  // offscreen_target_stencil_render_buffer_ is unused.
1710  scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1711  scoped_ptr<BackTexture> offscreen_target_color_texture_;
1712  scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1713  scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1714  scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
1715  GLenum offscreen_target_color_format_;
1716  GLenum offscreen_target_depth_format_;
1717  GLenum offscreen_target_stencil_format_;
1718  GLsizei offscreen_target_samples_;
1719  GLboolean offscreen_target_buffer_preserved_;
1720
1721  // The copy that is saved when SwapBuffers is called.
1722  scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1723  scoped_ptr<BackTexture> offscreen_saved_color_texture_;
1724  scoped_refptr<TextureRef>
1725      offscreen_saved_color_texture_info_;
1726
1727  // The copy that is used as the destination for multi-sample resolves.
1728  scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1729  scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
1730  GLenum offscreen_saved_color_format_;
1731
1732  scoped_ptr<QueryManager> query_manager_;
1733
1734  scoped_ptr<VertexArrayManager> vertex_array_manager_;
1735
1736  scoped_ptr<ImageManager> image_manager_;
1737
1738  base::Callback<void(gfx::Size, float)> resize_callback_;
1739
1740  WaitSyncPointCallback wait_sync_point_callback_;
1741
1742  ShaderCacheCallback shader_cache_callback_;
1743
1744  scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
1745
1746  // The format of the back buffer_
1747  GLenum back_buffer_color_format_;
1748  bool back_buffer_has_depth_;
1749  bool back_buffer_has_stencil_;
1750
1751  bool surfaceless_;
1752
1753  // Backbuffer attachments that are currently undefined.
1754  uint32 backbuffer_needs_clear_bits_;
1755
1756  // The current decoder error communicates the decoder error through command
1757  // processing functions that do not return the error value. Should be set only
1758  // if not returning an error.
1759  error::Error current_decoder_error_;
1760
1761  bool use_shader_translator_;
1762  scoped_refptr<ShaderTranslator> vertex_translator_;
1763  scoped_refptr<ShaderTranslator> fragment_translator_;
1764
1765  DisallowedFeatures disallowed_features_;
1766
1767  // Cached from ContextGroup
1768  const Validators* validators_;
1769  scoped_refptr<FeatureInfo> feature_info_;
1770
1771  int frame_number_;
1772
1773  // Number of commands remaining to be processed in DoCommands().
1774  int commands_to_process_;
1775
1776  bool has_robustness_extension_;
1777  GLenum reset_status_;
1778  bool reset_by_robustness_extension_;
1779  bool supports_post_sub_buffer_;
1780
1781  // These flags are used to override the state of the shared feature_info_
1782  // member.  Because the same FeatureInfo instance may be shared among many
1783  // contexts, the assumptions on the availablity of extensions in WebGL
1784  // contexts may be broken.  These flags override the shared state to preserve
1785  // WebGL semantics.
1786  bool force_webgl_glsl_validation_;
1787  bool derivatives_explicitly_enabled_;
1788  bool frag_depth_explicitly_enabled_;
1789  bool draw_buffers_explicitly_enabled_;
1790  bool shader_texture_lod_explicitly_enabled_;
1791
1792  bool compile_shader_always_succeeds_;
1793
1794  // An optional behaviour to lose the context and group when OOM.
1795  bool lose_context_when_out_of_memory_;
1796
1797  // Log extra info.
1798  bool service_logging_;
1799
1800#if defined(OS_MACOSX)
1801  typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
1802  TextureToIOSurfaceMap texture_to_io_surface_map_;
1803#endif
1804
1805  scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1806
1807  // Cached values of the currently assigned viewport dimensions.
1808  GLsizei viewport_max_width_;
1809  GLsizei viewport_max_height_;
1810
1811  // Command buffer stats.
1812  base::TimeDelta total_processing_commands_time_;
1813
1814  // States related to each manager.
1815  DecoderTextureState texture_state_;
1816  DecoderFramebufferState framebuffer_state_;
1817
1818  scoped_ptr<GPUTracer> gpu_tracer_;
1819  scoped_ptr<GPUStateTracer> gpu_state_tracer_;
1820  const unsigned char* cb_command_trace_category_;
1821  int gpu_trace_level_;
1822  bool gpu_trace_commands_;
1823  bool gpu_debug_commands_;
1824
1825  std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1826
1827  // Used to validate multisample renderbuffers if needed
1828  GLuint validation_texture_;
1829  GLuint validation_fbo_multisample_;
1830  GLuint validation_fbo_;
1831
1832  typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1833      uint32 immediate_data_size,
1834      const void* data);
1835
1836  // A struct to hold info about each command.
1837  struct CommandInfo {
1838    CmdHandler cmd_handler;
1839    uint8 arg_flags;   // How to handle the arguments for this command
1840    uint8 cmd_flags;   // How to handle this command
1841    uint16 arg_count;  // How many arguments are expected for this command.
1842  };
1843
1844  // A table of CommandInfo for all the commands.
1845  static const CommandInfo command_info[kNumCommands - kStartPoint];
1846
1847  DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1848};
1849
1850const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1851#define GLES2_CMD_OP(name)                                   \
1852  {                                                          \
1853    &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags,  \
1854        cmds::name::cmd_flags,                               \
1855        sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1856  }                                                          \
1857  , /* NOLINT */
1858    GLES2_COMMAND_LIST(GLES2_CMD_OP)
1859#undef GLES2_CMD_OP
1860};
1861
1862ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1863    const char* function_name, ErrorState* error_state)
1864    : function_name_(function_name),
1865      error_state_(error_state) {
1866  ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
1867}
1868
1869ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1870  ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
1871}
1872
1873static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
1874  TextureUnit& info = state->texture_units[0];
1875  GLuint last_id;
1876  scoped_refptr<TextureRef> texture_ref;
1877  switch (target) {
1878    case GL_TEXTURE_2D:
1879      texture_ref = info.bound_texture_2d;
1880      break;
1881    case GL_TEXTURE_CUBE_MAP:
1882      texture_ref = info.bound_texture_cube_map;
1883      break;
1884    case GL_TEXTURE_EXTERNAL_OES:
1885      texture_ref = info.bound_texture_external_oes;
1886      break;
1887    case GL_TEXTURE_RECTANGLE_ARB:
1888      texture_ref = info.bound_texture_rectangle_arb;
1889      break;
1890    default:
1891      NOTREACHED();
1892      break;
1893  }
1894  if (texture_ref.get()) {
1895    last_id = texture_ref->service_id();
1896  } else {
1897    last_id = 0;
1898  }
1899
1900  glBindTexture(target, last_id);
1901  glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1902}
1903
1904ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1905                                         GLuint id,
1906                                         GLenum target)
1907    : state_(state),
1908      target_(target) {
1909  ScopedGLErrorSuppressor suppressor(
1910      "ScopedTextureBinder::ctor", state_->GetErrorState());
1911
1912  // TODO(apatrick): Check if there are any other states that need to be reset
1913  // before binding a new texture.
1914  glActiveTexture(GL_TEXTURE0);
1915  glBindTexture(target, id);
1916}
1917
1918ScopedTextureBinder::~ScopedTextureBinder() {
1919  ScopedGLErrorSuppressor suppressor(
1920      "ScopedTextureBinder::dtor", state_->GetErrorState());
1921  RestoreCurrentTextureBindings(state_, target_);
1922}
1923
1924ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
1925                                                   GLuint id)
1926    : state_(state) {
1927  ScopedGLErrorSuppressor suppressor(
1928      "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
1929  glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1930}
1931
1932ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1933  ScopedGLErrorSuppressor suppressor(
1934      "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1935  state_->RestoreRenderbufferBindings();
1936}
1937
1938ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1939                                                 GLuint id)
1940    : decoder_(decoder) {
1941  ScopedGLErrorSuppressor suppressor(
1942      "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
1943  glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1944  decoder->OnFboChanged();
1945}
1946
1947ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1948  ScopedGLErrorSuppressor suppressor(
1949      "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
1950  decoder_->RestoreCurrentFramebufferBindings();
1951}
1952
1953ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
1954    GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
1955    : decoder_(decoder) {
1956  resolve_and_bind_ = (
1957      decoder_->offscreen_target_frame_buffer_.get() &&
1958      decoder_->IsOffscreenBufferMultisampled() &&
1959      (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1960       enforce_internal_framebuffer));
1961  if (!resolve_and_bind_)
1962    return;
1963
1964  ScopedGLErrorSuppressor suppressor(
1965      "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
1966  glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1967                       decoder_->offscreen_target_frame_buffer_->id());
1968  GLuint targetid;
1969  if (internal) {
1970    if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1971      decoder_->offscreen_resolved_frame_buffer_.reset(
1972          new BackFramebuffer(decoder_));
1973      decoder_->offscreen_resolved_frame_buffer_->Create();
1974      decoder_->offscreen_resolved_color_texture_.reset(
1975          new BackTexture(decoder->memory_tracker(), &decoder->state_));
1976      decoder_->offscreen_resolved_color_texture_->Create();
1977
1978      DCHECK(decoder_->offscreen_saved_color_format_);
1979      decoder_->offscreen_resolved_color_texture_->AllocateStorage(
1980          decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1981          false);
1982      decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1983          decoder_->offscreen_resolved_color_texture_.get());
1984      if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1985          GL_FRAMEBUFFER_COMPLETE) {
1986        LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1987                   << "because offscreen resolved FBO was incomplete.";
1988        return;
1989      }
1990    }
1991    targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1992  } else {
1993    targetid = decoder_->offscreen_saved_frame_buffer_->id();
1994  }
1995  glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
1996  const int width = decoder_->offscreen_size_.width();
1997  const int height = decoder_->offscreen_size_.height();
1998  decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
1999  decoder->BlitFramebufferHelper(0,
2000                                 0,
2001                                 width,
2002                                 height,
2003                                 0,
2004                                 0,
2005                                 width,
2006                                 height,
2007                                 GL_COLOR_BUFFER_BIT,
2008                                 GL_NEAREST);
2009  glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
2010}
2011
2012ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2013  if (!resolve_and_bind_)
2014    return;
2015
2016  ScopedGLErrorSuppressor suppressor(
2017      "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
2018  decoder_->RestoreCurrentFramebufferBindings();
2019  if (decoder_->state_.enable_flags.scissor_test) {
2020    decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
2021  }
2022}
2023
2024BackTexture::BackTexture(
2025    MemoryTracker* memory_tracker,
2026    ContextState* state)
2027    : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2028      state_(state),
2029      bytes_allocated_(0),
2030      id_(0) {
2031}
2032
2033BackTexture::~BackTexture() {
2034  // This does not destroy the render texture because that would require that
2035  // the associated GL context was current. Just check that it was explicitly
2036  // destroyed.
2037  DCHECK_EQ(id_, 0u);
2038}
2039
2040void BackTexture::Create() {
2041  ScopedGLErrorSuppressor suppressor("BackTexture::Create",
2042                                     state_->GetErrorState());
2043  Destroy();
2044  glGenTextures(1, &id_);
2045  ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
2046  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2047  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2048  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2049  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2050
2051  // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2052  // never called on an offscreen context, no data will ever be uploaded to the
2053  // saved offscreen color texture (it is deferred until to when SwapBuffers
2054  // is called). My idea is that some nvidia drivers might have a bug where
2055  // deleting a texture that has never been populated might cause a
2056  // crash.
2057  glTexImage2D(
2058      GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2059
2060  bytes_allocated_ = 16u * 16u * 4u;
2061  memory_tracker_.TrackMemAlloc(bytes_allocated_);
2062}
2063
2064bool BackTexture::AllocateStorage(
2065    const gfx::Size& size, GLenum format, bool zero) {
2066  DCHECK_NE(id_, 0u);
2067  ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
2068                                     state_->GetErrorState());
2069  ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
2070  uint32 image_size = 0;
2071  GLES2Util::ComputeImageDataSizes(
2072      size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2073      NULL, NULL);
2074
2075  if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2076    return false;
2077  }
2078
2079  scoped_ptr<char[]> zero_data;
2080  if (zero) {
2081    zero_data.reset(new char[image_size]);
2082    memset(zero_data.get(), 0, image_size);
2083  }
2084
2085  glTexImage2D(GL_TEXTURE_2D,
2086               0,  // mip level
2087               format,
2088               size.width(),
2089               size.height(),
2090               0,  // border
2091               format,
2092               GL_UNSIGNED_BYTE,
2093               zero_data.get());
2094
2095  size_ = size;
2096
2097  bool success = glGetError() == GL_NO_ERROR;
2098  if (success) {
2099    memory_tracker_.TrackMemFree(bytes_allocated_);
2100    bytes_allocated_ = image_size;
2101    memory_tracker_.TrackMemAlloc(bytes_allocated_);
2102  }
2103  return success;
2104}
2105
2106void BackTexture::Copy(const gfx::Size& size, GLenum format) {
2107  DCHECK_NE(id_, 0u);
2108  ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
2109                                     state_->GetErrorState());
2110  ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
2111  glCopyTexImage2D(GL_TEXTURE_2D,
2112                   0,  // level
2113                   format,
2114                   0, 0,
2115                   size.width(),
2116                   size.height(),
2117                   0);  // border
2118}
2119
2120void BackTexture::Destroy() {
2121  if (id_ != 0) {
2122    ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
2123                                       state_->GetErrorState());
2124    glDeleteTextures(1, &id_);
2125    id_ = 0;
2126  }
2127  memory_tracker_.TrackMemFree(bytes_allocated_);
2128  bytes_allocated_ = 0;
2129}
2130
2131void BackTexture::Invalidate() {
2132  id_ = 0;
2133}
2134
2135BackRenderbuffer::BackRenderbuffer(
2136    RenderbufferManager* renderbuffer_manager,
2137    MemoryTracker* memory_tracker,
2138    ContextState* state)
2139    : renderbuffer_manager_(renderbuffer_manager),
2140      memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2141      state_(state),
2142      bytes_allocated_(0),
2143      id_(0) {
2144}
2145
2146BackRenderbuffer::~BackRenderbuffer() {
2147  // This does not destroy the render buffer because that would require that
2148  // the associated GL context was current. Just check that it was explicitly
2149  // destroyed.
2150  DCHECK_EQ(id_, 0u);
2151}
2152
2153void BackRenderbuffer::Create() {
2154  ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
2155                                     state_->GetErrorState());
2156  Destroy();
2157  glGenRenderbuffersEXT(1, &id_);
2158}
2159
2160bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2161                                       const gfx::Size& size,
2162                                       GLenum format,
2163                                       GLsizei samples) {
2164  ScopedGLErrorSuppressor suppressor(
2165      "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2166  ScopedRenderBufferBinder binder(state_, id_);
2167
2168  uint32 estimated_size = 0;
2169  if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
2170           size.width(), size.height(), samples, format, &estimated_size)) {
2171    return false;
2172  }
2173
2174  if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2175    return false;
2176  }
2177
2178  if (samples <= 1) {
2179    glRenderbufferStorageEXT(GL_RENDERBUFFER,
2180                             format,
2181                             size.width(),
2182                             size.height());
2183  } else {
2184    GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2185                                                           GL_RENDERBUFFER,
2186                                                           samples,
2187                                                           format,
2188                                                           size.width(),
2189                                                           size.height());
2190  }
2191  bool success = glGetError() == GL_NO_ERROR;
2192  if (success) {
2193    // Mark the previously allocated bytes as free.
2194    memory_tracker_.TrackMemFree(bytes_allocated_);
2195    bytes_allocated_ = estimated_size;
2196    // Track the newly allocated bytes.
2197    memory_tracker_.TrackMemAlloc(bytes_allocated_);
2198  }
2199  return success;
2200}
2201
2202void BackRenderbuffer::Destroy() {
2203  if (id_ != 0) {
2204    ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
2205                                       state_->GetErrorState());
2206    glDeleteRenderbuffersEXT(1, &id_);
2207    id_ = 0;
2208  }
2209  memory_tracker_.TrackMemFree(bytes_allocated_);
2210  bytes_allocated_ = 0;
2211}
2212
2213void BackRenderbuffer::Invalidate() {
2214  id_ = 0;
2215}
2216
2217BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
2218    : decoder_(decoder),
2219      id_(0) {
2220}
2221
2222BackFramebuffer::~BackFramebuffer() {
2223  // This does not destroy the frame buffer because that would require that
2224  // the associated GL context was current. Just check that it was explicitly
2225  // destroyed.
2226  DCHECK_EQ(id_, 0u);
2227}
2228
2229void BackFramebuffer::Create() {
2230  ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2231                                     decoder_->GetErrorState());
2232  Destroy();
2233  glGenFramebuffersEXT(1, &id_);
2234}
2235
2236void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
2237  DCHECK_NE(id_, 0u);
2238  ScopedGLErrorSuppressor suppressor(
2239      "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
2240  ScopedFrameBufferBinder binder(decoder_, id_);
2241  GLuint attach_id = texture ? texture->id() : 0;
2242  glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2243                            GL_COLOR_ATTACHMENT0,
2244                            GL_TEXTURE_2D,
2245                            attach_id,
2246                            0);
2247}
2248
2249void BackFramebuffer::AttachRenderBuffer(GLenum target,
2250                                         BackRenderbuffer* render_buffer) {
2251  DCHECK_NE(id_, 0u);
2252  ScopedGLErrorSuppressor suppressor(
2253      "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
2254  ScopedFrameBufferBinder binder(decoder_, id_);
2255  GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2256  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
2257                               target,
2258                               GL_RENDERBUFFER,
2259                               attach_id);
2260}
2261
2262void BackFramebuffer::Destroy() {
2263  if (id_ != 0) {
2264    ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2265                                       decoder_->GetErrorState());
2266    glDeleteFramebuffersEXT(1, &id_);
2267    id_ = 0;
2268  }
2269}
2270
2271void BackFramebuffer::Invalidate() {
2272  id_ = 0;
2273}
2274
2275GLenum BackFramebuffer::CheckStatus() {
2276  DCHECK_NE(id_, 0u);
2277  ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2278                                     decoder_->GetErrorState());
2279  ScopedFrameBufferBinder binder(decoder_, id_);
2280  return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2281}
2282
2283GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2284  return new GLES2DecoderImpl(group);
2285}
2286
2287GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
2288    : GLES2Decoder(),
2289      group_(group),
2290      logger_(&debug_marker_manager_),
2291      state_(group_->feature_info(), this, &logger_),
2292      unpack_flip_y_(false),
2293      unpack_premultiply_alpha_(false),
2294      unpack_unpremultiply_alpha_(false),
2295      attrib_0_buffer_id_(0),
2296      attrib_0_buffer_matches_value_(true),
2297      attrib_0_size_(0),
2298      fixed_attrib_buffer_id_(0),
2299      fixed_attrib_buffer_size_(0),
2300      offscreen_target_color_format_(0),
2301      offscreen_target_depth_format_(0),
2302      offscreen_target_stencil_format_(0),
2303      offscreen_target_samples_(0),
2304      offscreen_target_buffer_preserved_(true),
2305      offscreen_saved_color_format_(0),
2306      back_buffer_color_format_(0),
2307      back_buffer_has_depth_(false),
2308      back_buffer_has_stencil_(false),
2309      surfaceless_(false),
2310      backbuffer_needs_clear_bits_(0),
2311      current_decoder_error_(error::kNoError),
2312      use_shader_translator_(true),
2313      validators_(group_->feature_info()->validators()),
2314      feature_info_(group_->feature_info()),
2315      frame_number_(0),
2316      has_robustness_extension_(false),
2317      reset_status_(GL_NO_ERROR),
2318      reset_by_robustness_extension_(false),
2319      supports_post_sub_buffer_(false),
2320      force_webgl_glsl_validation_(false),
2321      derivatives_explicitly_enabled_(false),
2322      frag_depth_explicitly_enabled_(false),
2323      draw_buffers_explicitly_enabled_(false),
2324      shader_texture_lod_explicitly_enabled_(false),
2325      compile_shader_always_succeeds_(false),
2326      lose_context_when_out_of_memory_(false),
2327      service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2328          switches::kEnableGPUServiceLoggingGPU)),
2329      viewport_max_width_(0),
2330      viewport_max_height_(0),
2331      texture_state_(group_->feature_info()
2332                         ->workarounds()
2333                         .texsubimage2d_faster_than_teximage2d),
2334      cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2335          TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2336      gpu_trace_level_(2),
2337      gpu_trace_commands_(false),
2338      gpu_debug_commands_(false),
2339      validation_texture_(0),
2340      validation_fbo_multisample_(0),
2341      validation_fbo_(0) {
2342  DCHECK(group);
2343
2344  attrib_0_value_.v[0] = 0.0f;
2345  attrib_0_value_.v[1] = 0.0f;
2346  attrib_0_value_.v[2] = 0.0f;
2347  attrib_0_value_.v[3] = 1.0f;
2348
2349  // The shader translator is used for WebGL even when running on EGL
2350  // because additional restrictions are needed (like only enabling
2351  // GL_OES_standard_derivatives on demand).  It is used for the unit
2352  // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2353  // the empty string to CompileShader and this is not a valid shader.
2354  if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
2355      CommandLine::ForCurrentProcess()->HasSwitch(
2356          switches::kDisableGLSLTranslator)) {
2357    use_shader_translator_ = false;
2358  }
2359}
2360
2361GLES2DecoderImpl::~GLES2DecoderImpl() {
2362}
2363
2364bool GLES2DecoderImpl::Initialize(
2365    const scoped_refptr<gfx::GLSurface>& surface,
2366    const scoped_refptr<gfx::GLContext>& context,
2367    bool offscreen,
2368    const gfx::Size& size,
2369    const DisallowedFeatures& disallowed_features,
2370    const std::vector<int32>& attribs) {
2371  TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
2372  DCHECK(context->IsCurrent(surface.get()));
2373  DCHECK(!context_.get());
2374
2375  surfaceless_ = surface->IsSurfaceless();
2376
2377  set_initialized();
2378  gpu_tracer_.reset(new GPUTracer(this));
2379  gpu_state_tracer_ = GPUStateTracer::Create(&state_);
2380
2381  if (CommandLine::ForCurrentProcess()->HasSwitch(
2382      switches::kEnableGPUDebugging)) {
2383    set_debug(true);
2384  }
2385
2386  if (CommandLine::ForCurrentProcess()->HasSwitch(
2387      switches::kEnableGPUCommandLogging)) {
2388    set_log_commands(true);
2389  }
2390
2391  compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2392      switches::kCompileShaderAlwaysSucceeds);
2393
2394
2395  // Take ownership of the context and surface. The surface can be replaced with
2396  // SetSurface.
2397  context_ = context;
2398  surface_ = surface;
2399
2400  ContextCreationAttribHelper attrib_parser;
2401  if (!attrib_parser.Parse(attribs))
2402    return false;
2403
2404  // Save the loseContextWhenOutOfMemory context creation attribute.
2405  lose_context_when_out_of_memory_ =
2406      attrib_parser.lose_context_when_out_of_memory;
2407
2408  // If the failIfMajorPerformanceCaveat context creation attribute was true
2409  // and we are using a software renderer, fail.
2410  if (attrib_parser.fail_if_major_perf_caveat &&
2411      feature_info_->feature_flags().is_swiftshader) {
2412    group_ = NULL;  // Must not destroy ContextGroup if it is not initialized.
2413    Destroy(true);
2414    return false;
2415  }
2416
2417  if (!group_->Initialize(this, disallowed_features)) {
2418    LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
2419               << "failed to initialize.";
2420    group_ = NULL;  // Must not destroy ContextGroup if it is not initialized.
2421    Destroy(true);
2422    return false;
2423  }
2424  CHECK_GL_ERROR();
2425
2426  disallowed_features_ = disallowed_features;
2427
2428  state_.attrib_values.resize(group_->max_vertex_attribs());
2429  vertex_array_manager_.reset(new VertexArrayManager());
2430
2431  GLuint default_vertex_attrib_service_id = 0;
2432  if (features().native_vertex_array_object) {
2433    glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2434    glBindVertexArrayOES(default_vertex_attrib_service_id);
2435  }
2436
2437  state_.default_vertex_attrib_manager =
2438      CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2439
2440  state_.default_vertex_attrib_manager->Initialize(
2441      group_->max_vertex_attribs(),
2442      feature_info_->workarounds().init_vertex_attributes);
2443
2444  // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
2445  DoBindVertexArrayOES(0);
2446
2447  query_manager_.reset(new QueryManager(this, feature_info_.get()));
2448
2449  image_manager_.reset(new ImageManager);
2450
2451  util_.set_num_compressed_texture_formats(
2452      validators_->compressed_texture_format.GetValues().size());
2453
2454  if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2455    // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2456    // OpenGL ES 2.0 does not have this issue.
2457    glEnableVertexAttribArray(0);
2458  }
2459  glGenBuffersARB(1, &attrib_0_buffer_id_);
2460  glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2461  glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2462  glBindBuffer(GL_ARRAY_BUFFER, 0);
2463  glGenBuffersARB(1, &fixed_attrib_buffer_id_);
2464
2465  state_.texture_units.resize(group_->max_texture_units());
2466  for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
2467    glActiveTexture(GL_TEXTURE0 + tt);
2468    // We want the last bind to be 2D.
2469    TextureRef* ref;
2470    if (features().oes_egl_image_external) {
2471      ref = texture_manager()->GetDefaultTextureInfo(
2472          GL_TEXTURE_EXTERNAL_OES);
2473      state_.texture_units[tt].bound_texture_external_oes = ref;
2474      glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
2475    }
2476    if (features().arb_texture_rectangle) {
2477      ref = texture_manager()->GetDefaultTextureInfo(
2478          GL_TEXTURE_RECTANGLE_ARB);
2479      state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2480      glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
2481    }
2482    ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2483    state_.texture_units[tt].bound_texture_cube_map = ref;
2484    glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
2485    ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2486    state_.texture_units[tt].bound_texture_2d = ref;
2487    glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
2488  }
2489  glActiveTexture(GL_TEXTURE0);
2490  CHECK_GL_ERROR();
2491
2492  if (offscreen) {
2493    if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
2494        features().chromium_framebuffer_multisample) {
2495      // Per ext_framebuffer_multisample spec, need max bound on sample count.
2496      // max_sample_count must be initialized to a sane value.  If
2497      // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2498      GLint max_sample_count = 1;
2499      glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2500      offscreen_target_samples_ = std::min(attrib_parser.samples,
2501                                           max_sample_count);
2502    } else {
2503      offscreen_target_samples_ = 1;
2504    }
2505    offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
2506
2507    if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2508      const bool rgb8_supported =
2509          context_->HasExtension("GL_OES_rgb8_rgba8");
2510      // The only available default render buffer formats in GLES2 have very
2511      // little precision.  Don't enable multisampling unless 8-bit render
2512      // buffer formats are available--instead fall back to 8-bit textures.
2513      if (rgb8_supported && offscreen_target_samples_ > 1) {
2514        offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
2515            GL_RGBA8 : GL_RGB8;
2516      } else {
2517        offscreen_target_samples_ = 1;
2518        offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
2519            GL_RGBA : GL_RGB;
2520      }
2521
2522      // ANGLE only supports packed depth/stencil formats, so use it if it is
2523      // available.
2524      const bool depth24_stencil8_supported =
2525          feature_info_->feature_flags().packed_depth24_stencil8;
2526      VLOG(1) << "GL_OES_packed_depth_stencil "
2527              << (depth24_stencil8_supported ? "" : "not ") << "supported.";
2528      if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
2529          depth24_stencil8_supported) {
2530        offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2531        offscreen_target_stencil_format_ = 0;
2532      } else {
2533        // It may be the case that this depth/stencil combination is not
2534        // supported, but this will be checked later by CheckFramebufferStatus.
2535        offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
2536            GL_DEPTH_COMPONENT16 : 0;
2537        offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
2538            GL_STENCIL_INDEX8 : 0;
2539      }
2540    } else {
2541      offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
2542          GL_RGBA : GL_RGB;
2543
2544      // If depth is requested at all, use the packed depth stencil format if
2545      // it's available, as some desktop GL drivers don't support any non-packed
2546      // formats for depth attachments.
2547      const bool depth24_stencil8_supported =
2548          feature_info_->feature_flags().packed_depth24_stencil8;
2549      VLOG(1) << "GL_EXT_packed_depth_stencil "
2550              << (depth24_stencil8_supported ? "" : "not ") << "supported.";
2551
2552      if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
2553          depth24_stencil8_supported) {
2554        offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2555        offscreen_target_stencil_format_ = 0;
2556      } else {
2557        offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
2558            GL_DEPTH_COMPONENT : 0;
2559        offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
2560            GL_STENCIL_INDEX : 0;
2561      }
2562    }
2563
2564    offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
2565        GL_RGBA : GL_RGB;
2566
2567    // Create the target frame buffer. This is the one that the client renders
2568    // directly to.
2569    offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
2570    offscreen_target_frame_buffer_->Create();
2571    // Due to GLES2 format limitations, either the color texture (for
2572    // non-multisampling) or the color render buffer (for multisampling) will be
2573    // attached to the offscreen frame buffer.  The render buffer has more
2574    // limited formats available to it, but the texture can't do multisampling.
2575    if (IsOffscreenBufferMultisampled()) {
2576      offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2577          renderbuffer_manager(), memory_tracker(), &state_));
2578      offscreen_target_color_render_buffer_->Create();
2579    } else {
2580      offscreen_target_color_texture_.reset(new BackTexture(
2581          memory_tracker(), &state_));
2582      offscreen_target_color_texture_->Create();
2583    }
2584    offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2585        renderbuffer_manager(), memory_tracker(), &state_));
2586    offscreen_target_depth_render_buffer_->Create();
2587    offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2588        renderbuffer_manager(), memory_tracker(), &state_));
2589    offscreen_target_stencil_render_buffer_->Create();
2590
2591    // Create the saved offscreen texture. The target frame buffer is copied
2592    // here when SwapBuffers is called.
2593    offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
2594    offscreen_saved_frame_buffer_->Create();
2595    //
2596    offscreen_saved_color_texture_.reset(new BackTexture(
2597        memory_tracker(), &state_));
2598    offscreen_saved_color_texture_->Create();
2599
2600    // Allocate the render buffers at their initial size and check the status
2601    // of the frame buffers is okay.
2602    if (!ResizeOffscreenFrameBuffer(size)) {
2603      LOG(ERROR) << "Could not allocate offscreen buffer storage.";
2604      Destroy(true);
2605      return false;
2606    }
2607
2608    // Allocate the offscreen saved color texture.
2609    DCHECK(offscreen_saved_color_format_);
2610    offscreen_saved_color_texture_->AllocateStorage(
2611        gfx::Size(1, 1), offscreen_saved_color_format_, true);
2612
2613    offscreen_saved_frame_buffer_->AttachRenderTexture(
2614        offscreen_saved_color_texture_.get());
2615    if (offscreen_saved_frame_buffer_->CheckStatus() !=
2616        GL_FRAMEBUFFER_COMPLETE) {
2617      LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2618      Destroy(true);
2619      return false;
2620    }
2621
2622    // Bind to the new default frame buffer (the offscreen target frame buffer).
2623    // This should now be associated with ID zero.
2624    DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2625  } else {
2626    glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2627    // These are NOT if the back buffer has these proprorties. They are
2628    // if we want the command buffer to enforce them regardless of what
2629    // the real backbuffer is assuming the real back buffer gives us more than
2630    // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2631    // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2632    // can't do anything about that.
2633
2634    if (!surfaceless_) {
2635      GLint v = 0;
2636      glGetIntegerv(GL_ALPHA_BITS, &v);
2637      // This checks if the user requested RGBA and we have RGBA then RGBA. If
2638      // the user requested RGB then RGB. If the user did not specify a
2639      // preference than use whatever we were given. Same for DEPTH and STENCIL.
2640      back_buffer_color_format_ =
2641          (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2642      glGetIntegerv(GL_DEPTH_BITS, &v);
2643      back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2644      glGetIntegerv(GL_STENCIL_BITS, &v);
2645      back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2646    }
2647  }
2648
2649  // OpenGL ES 2.0 implicitly enables the desktop GL capability
2650  // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2651  // isn't well documented; it was discovered in the Khronos OpenGL ES
2652  // mailing list archives. It also implicitly enables the desktop GL
2653  // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2654  // variable in fragment shaders.
2655  if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2656    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
2657    glEnable(GL_POINT_SPRITE);
2658  }
2659
2660  has_robustness_extension_ =
2661      context->HasExtension("GL_ARB_robustness") ||
2662      context->HasExtension("GL_EXT_robustness");
2663
2664  if (!InitializeShaderTranslator()) {
2665    return false;
2666  }
2667
2668  state_.viewport_width = size.width();
2669  state_.viewport_height = size.height();
2670
2671  GLint viewport_params[4] = { 0 };
2672  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
2673  viewport_max_width_ = viewport_params[0];
2674  viewport_max_height_ = viewport_params[1];
2675
2676  state_.scissor_width = state_.viewport_width;
2677  state_.scissor_height = state_.viewport_height;
2678
2679  // Set all the default state because some GL drivers get it wrong.
2680  state_.InitCapabilities(NULL);
2681  state_.InitState(NULL);
2682  glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
2683
2684  DoBindBuffer(GL_ARRAY_BUFFER, 0);
2685  DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2686  DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2687  DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2688
2689  bool call_gl_clear = !surfaceless_;
2690#if defined(OS_ANDROID)
2691  // Temporary workaround for Android WebView because this clear ignores the
2692  // clip and corrupts that external UI of the App. Not calling glClear is ok
2693  // because the system already clears the buffer before each draw. Proper
2694  // fix might be setting the scissor clip properly before initialize. See
2695  // crbug.com/259023 for details.
2696  call_gl_clear = surface_->GetHandle();
2697#endif
2698  if (call_gl_clear) {
2699    // Clear the backbuffer.
2700    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2701  }
2702
2703  supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2704  if (feature_info_->workarounds()
2705          .disable_post_sub_buffers_for_onscreen_surfaces &&
2706      !surface->IsOffscreen())
2707    supports_post_sub_buffer_ = false;
2708
2709  if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
2710    glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2711  }
2712
2713  if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2714    context_->SetUnbindFboOnMakeCurrent();
2715  }
2716
2717  // Only compositor contexts are known to use only the subset of GL
2718  // that can be safely migrated between the iGPU and the dGPU. Mark
2719  // those contexts as safe to forcibly transition between the GPUs.
2720  // http://crbug.com/180876, http://crbug.com/227228
2721  if (!offscreen)
2722    context_->SetSafeToForceGpuSwitch();
2723
2724  async_pixel_transfer_manager_.reset(
2725      AsyncPixelTransferManager::Create(context.get()));
2726  async_pixel_transfer_manager_->Initialize(texture_manager());
2727
2728  framebuffer_manager()->AddObserver(this);
2729
2730  return true;
2731}
2732
2733Capabilities GLES2DecoderImpl::GetCapabilities() {
2734  DCHECK(initialized());
2735
2736  Capabilities caps;
2737
2738  caps.egl_image_external =
2739      feature_info_->feature_flags().oes_egl_image_external;
2740  caps.texture_format_bgra8888 =
2741      feature_info_->feature_flags().ext_texture_format_bgra8888;
2742  caps.texture_format_etc1 =
2743      feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2744  caps.texture_format_etc1_npot =
2745      caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
2746  caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2747  caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2748  caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2749  caps.discard_framebuffer =
2750      feature_info_->feature_flags().ext_discard_framebuffer;
2751  caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
2752
2753#if defined(OS_MACOSX)
2754  // This is unconditionally true on mac, no need to test for it at runtime.
2755  caps.iosurface = true;
2756#endif
2757
2758  caps.post_sub_buffer = supports_post_sub_buffer_;
2759  caps.map_image = true;
2760
2761  return caps;
2762}
2763
2764void GLES2DecoderImpl::UpdateCapabilities() {
2765  util_.set_num_compressed_texture_formats(
2766      validators_->compressed_texture_format.GetValues().size());
2767  util_.set_num_shader_binary_formats(
2768      validators_->shader_binary_format.GetValues().size());
2769}
2770
2771bool GLES2DecoderImpl::InitializeShaderTranslator() {
2772  TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2773
2774  if (!use_shader_translator_) {
2775    return true;
2776  }
2777  ShBuiltInResources resources;
2778  ShInitBuiltInResources(&resources);
2779  resources.MaxVertexAttribs = group_->max_vertex_attribs();
2780  resources.MaxVertexUniformVectors =
2781      group_->max_vertex_uniform_vectors();
2782  resources.MaxVaryingVectors = group_->max_varying_vectors();
2783  resources.MaxVertexTextureImageUnits =
2784      group_->max_vertex_texture_image_units();
2785  resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2786  resources.MaxTextureImageUnits = group_->max_texture_image_units();
2787  resources.MaxFragmentUniformVectors =
2788      group_->max_fragment_uniform_vectors();
2789  resources.MaxDrawBuffers = group_->max_draw_buffers();
2790  resources.MaxExpressionComplexity = 256;
2791  resources.MaxCallStackDepth = 256;
2792
2793  GLint range[2] = { 0, 0 };
2794  GLint precision = 0;
2795  GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2796                               range, &precision);
2797  resources.FragmentPrecisionHigh =
2798      PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
2799
2800  if (force_webgl_glsl_validation_) {
2801    resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2802    resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
2803    resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
2804    if (!draw_buffers_explicitly_enabled_)
2805      resources.MaxDrawBuffers = 1;
2806    resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
2807  } else {
2808    resources.OES_standard_derivatives =
2809        features().oes_standard_derivatives ? 1 : 0;
2810    resources.ARB_texture_rectangle =
2811        features().arb_texture_rectangle ? 1 : 0;
2812    resources.OES_EGL_image_external =
2813        features().oes_egl_image_external ? 1 : 0;
2814    resources.EXT_draw_buffers =
2815        features().ext_draw_buffers ? 1 : 0;
2816    resources.EXT_frag_depth =
2817        features().ext_frag_depth ? 1 : 0;
2818    resources.EXT_shader_texture_lod =
2819        features().ext_shader_texture_lod ? 1 : 0;
2820  }
2821
2822  ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2823                                                          : SH_GLES2_SPEC;
2824  if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
2825    resources.HashFunction = &CityHash64;
2826  else
2827    resources.HashFunction = NULL;
2828  ShaderTranslatorInterface::GlslImplementationType implementation_type =
2829      gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2830          ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2831  int driver_bug_workarounds = 0;
2832  if (workarounds().needs_glsl_built_in_function_emulation)
2833    driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
2834  if (workarounds().init_gl_position_in_vertex_shader)
2835    driver_bug_workarounds |= SH_INIT_GL_POSITION;
2836  if (workarounds().unfold_short_circuit_as_ternary_operation)
2837    driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
2838  if (workarounds().init_varyings_without_static_use)
2839    driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
2840  if (workarounds().unroll_for_loop_with_sampler_array_index)
2841    driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
2842  if (workarounds().scalarize_vec_and_mat_constructor_args)
2843    driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
2844  if (workarounds().regenerate_struct_names)
2845    driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
2846
2847  vertex_translator_ = shader_translator_cache()->GetTranslator(
2848      GL_VERTEX_SHADER,
2849      shader_spec,
2850      &resources,
2851      implementation_type,
2852      static_cast<ShCompileOptions>(driver_bug_workarounds));
2853  if (!vertex_translator_.get()) {
2854    LOG(ERROR) << "Could not initialize vertex shader translator.";
2855    Destroy(true);
2856    return false;
2857  }
2858
2859  fragment_translator_ = shader_translator_cache()->GetTranslator(
2860      GL_FRAGMENT_SHADER,
2861      shader_spec,
2862      &resources,
2863      implementation_type,
2864      static_cast<ShCompileOptions>(driver_bug_workarounds));
2865  if (!fragment_translator_.get()) {
2866    LOG(ERROR) << "Could not initialize fragment shader translator.";
2867    Destroy(true);
2868    return false;
2869  }
2870  return true;
2871}
2872
2873bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
2874  for (GLsizei ii = 0; ii < n; ++ii) {
2875    if (GetBuffer(client_ids[ii])) {
2876      return false;
2877    }
2878  }
2879  scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2880  glGenBuffersARB(n, service_ids.get());
2881  for (GLsizei ii = 0; ii < n; ++ii) {
2882    CreateBuffer(client_ids[ii], service_ids[ii]);
2883  }
2884  return true;
2885}
2886
2887bool GLES2DecoderImpl::GenFramebuffersHelper(
2888    GLsizei n, const GLuint* client_ids) {
2889  for (GLsizei ii = 0; ii < n; ++ii) {
2890    if (GetFramebuffer(client_ids[ii])) {
2891      return false;
2892    }
2893  }
2894  scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2895  glGenFramebuffersEXT(n, service_ids.get());
2896  for (GLsizei ii = 0; ii < n; ++ii) {
2897    CreateFramebuffer(client_ids[ii], service_ids[ii]);
2898  }
2899  return true;
2900}
2901
2902bool GLES2DecoderImpl::GenRenderbuffersHelper(
2903    GLsizei n, const GLuint* client_ids) {
2904  for (GLsizei ii = 0; ii < n; ++ii) {
2905    if (GetRenderbuffer(client_ids[ii])) {
2906      return false;
2907    }
2908  }
2909  scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2910  glGenRenderbuffersEXT(n, service_ids.get());
2911  for (GLsizei ii = 0; ii < n; ++ii) {
2912    CreateRenderbuffer(client_ids[ii], service_ids[ii]);
2913  }
2914  return true;
2915}
2916
2917bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2918  for (GLsizei ii = 0; ii < n; ++ii) {
2919    if (GetTexture(client_ids[ii])) {
2920      return false;
2921    }
2922  }
2923  scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2924  glGenTextures(n, service_ids.get());
2925  for (GLsizei ii = 0; ii < n; ++ii) {
2926    CreateTexture(client_ids[ii], service_ids[ii]);
2927  }
2928  return true;
2929}
2930
2931void GLES2DecoderImpl::DeleteBuffersHelper(
2932    GLsizei n, const GLuint* client_ids) {
2933  for (GLsizei ii = 0; ii < n; ++ii) {
2934    Buffer* buffer = GetBuffer(client_ids[ii]);
2935    if (buffer && !buffer->IsDeleted()) {
2936      state_.vertex_attrib_manager->Unbind(buffer);
2937      if (state_.bound_array_buffer.get() == buffer) {
2938        state_.bound_array_buffer = NULL;
2939      }
2940      RemoveBuffer(client_ids[ii]);
2941    }
2942  }
2943}
2944
2945void GLES2DecoderImpl::DeleteFramebuffersHelper(
2946    GLsizei n, const GLuint* client_ids) {
2947  bool supports_separate_framebuffer_binds =
2948     features().chromium_framebuffer_multisample;
2949
2950  for (GLsizei ii = 0; ii < n; ++ii) {
2951    Framebuffer* framebuffer =
2952        GetFramebuffer(client_ids[ii]);
2953    if (framebuffer && !framebuffer->IsDeleted()) {
2954      if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2955        framebuffer_state_.bound_draw_framebuffer = NULL;
2956        framebuffer_state_.clear_state_dirty = true;
2957        GLenum target = supports_separate_framebuffer_binds ?
2958            GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
2959        glBindFramebufferEXT(target, GetBackbufferServiceId());
2960      }
2961      if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2962        framebuffer_state_.bound_read_framebuffer = NULL;
2963        GLenum target = supports_separate_framebuffer_binds ?
2964            GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
2965        glBindFramebufferEXT(target, GetBackbufferServiceId());
2966      }
2967      OnFboChanged();
2968      RemoveFramebuffer(client_ids[ii]);
2969    }
2970  }
2971}
2972
2973void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2974    GLsizei n, const GLuint* client_ids) {
2975  bool supports_separate_framebuffer_binds =
2976     features().chromium_framebuffer_multisample;
2977  for (GLsizei ii = 0; ii < n; ++ii) {
2978    Renderbuffer* renderbuffer =
2979        GetRenderbuffer(client_ids[ii]);
2980    if (renderbuffer && !renderbuffer->IsDeleted()) {
2981      if (state_.bound_renderbuffer.get() == renderbuffer) {
2982        state_.bound_renderbuffer = NULL;
2983      }
2984      // Unbind from current framebuffers.
2985      if (supports_separate_framebuffer_binds) {
2986        if (framebuffer_state_.bound_read_framebuffer.get()) {
2987          framebuffer_state_.bound_read_framebuffer
2988              ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
2989        }
2990        if (framebuffer_state_.bound_draw_framebuffer.get()) {
2991          framebuffer_state_.bound_draw_framebuffer
2992              ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
2993        }
2994      } else {
2995        if (framebuffer_state_.bound_draw_framebuffer.get()) {
2996          framebuffer_state_.bound_draw_framebuffer
2997              ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
2998        }
2999      }
3000      framebuffer_state_.clear_state_dirty = true;
3001      RemoveRenderbuffer(client_ids[ii]);
3002    }
3003  }
3004}
3005
3006void GLES2DecoderImpl::DeleteTexturesHelper(
3007    GLsizei n, const GLuint* client_ids) {
3008  bool supports_separate_framebuffer_binds =
3009     features().chromium_framebuffer_multisample;
3010  for (GLsizei ii = 0; ii < n; ++ii) {
3011    TextureRef* texture_ref = GetTexture(client_ids[ii]);
3012    if (texture_ref) {
3013      Texture* texture = texture_ref->texture();
3014      if (texture->IsAttachedToFramebuffer()) {
3015        framebuffer_state_.clear_state_dirty = true;
3016      }
3017      // Unbind texture_ref from texture_ref units.
3018      for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
3019        state_.texture_units[jj].Unbind(texture_ref);
3020      }
3021      // Unbind from current framebuffers.
3022      if (supports_separate_framebuffer_binds) {
3023        if (framebuffer_state_.bound_read_framebuffer.get()) {
3024          framebuffer_state_.bound_read_framebuffer
3025              ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
3026        }
3027        if (framebuffer_state_.bound_draw_framebuffer.get()) {
3028          framebuffer_state_.bound_draw_framebuffer
3029              ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
3030        }
3031      } else {
3032        if (framebuffer_state_.bound_draw_framebuffer.get()) {
3033          framebuffer_state_.bound_draw_framebuffer
3034              ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
3035        }
3036      }
3037#if defined(OS_MACOSX)
3038      GLuint service_id = texture->service_id();
3039      if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3040        ReleaseIOSurfaceForTexture(service_id);
3041      }
3042#endif
3043      RemoveTexture(client_ids[ii]);
3044    }
3045  }
3046}
3047
3048// }  // anonymous namespace
3049
3050bool GLES2DecoderImpl::MakeCurrent() {
3051  if (!context_.get())
3052    return false;
3053
3054  if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
3055    LOG(ERROR) << "  GLES2DecoderImpl: Context lost during MakeCurrent.";
3056
3057    // Some D3D drivers cannot recover from device lost in the GPU process
3058    // sandbox. Allow a new GPU process to launch.
3059    if (workarounds().exit_on_context_lost) {
3060      LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
3061                 << " a D3D device in the Chrome GPU process sandbox.";
3062#if defined(OS_WIN)
3063      base::win::SetShouldCrashOnProcessDetach(false);
3064#endif
3065      exit(0);
3066    }
3067
3068    return false;
3069  }
3070
3071  ProcessFinishedAsyncTransfers();
3072
3073  // Rebind the FBO if it was unbound by the context.
3074  if (workarounds().unbind_fbo_on_context_switch)
3075    RestoreFramebufferBindings();
3076
3077  framebuffer_state_.clear_state_dirty = true;
3078
3079  return true;
3080}
3081
3082void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
3083  ProcessPendingReadPixels();
3084  if (engine() && query_manager_.get())
3085    query_manager_->ProcessPendingTransferQueries();
3086
3087  // TODO(epenner): Is there a better place to do this?
3088  // This needs to occur before we execute any batch of commands
3089  // from the client, as the client may have recieved an async
3090  // completion while issuing those commands.
3091  // "DidFlushStart" would be ideal if we had such a callback.
3092  async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
3093}
3094
3095static void RebindCurrentFramebuffer(
3096    GLenum target,
3097    Framebuffer* framebuffer,
3098    GLuint back_buffer_service_id) {
3099  GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
3100
3101  if (framebuffer_id == 0) {
3102    framebuffer_id = back_buffer_service_id;
3103  }
3104
3105  glBindFramebufferEXT(target, framebuffer_id);
3106}
3107
3108void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
3109  framebuffer_state_.clear_state_dirty = true;
3110
3111  if (!features().chromium_framebuffer_multisample) {
3112    RebindCurrentFramebuffer(
3113        GL_FRAMEBUFFER,
3114        framebuffer_state_.bound_draw_framebuffer.get(),
3115        GetBackbufferServiceId());
3116  } else {
3117    RebindCurrentFramebuffer(
3118        GL_READ_FRAMEBUFFER_EXT,
3119        framebuffer_state_.bound_read_framebuffer.get(),
3120        GetBackbufferServiceId());
3121    RebindCurrentFramebuffer(
3122        GL_DRAW_FRAMEBUFFER_EXT,
3123        framebuffer_state_.bound_draw_framebuffer.get(),
3124        GetBackbufferServiceId());
3125  }
3126  OnFboChanged();
3127}
3128
3129bool GLES2DecoderImpl::CheckFramebufferValid(
3130    Framebuffer* framebuffer,
3131    GLenum target, const char* func_name) {
3132  if (!framebuffer) {
3133    if (surfaceless_)
3134      return false;
3135    if (backbuffer_needs_clear_bits_) {
3136      glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3137          offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3138      state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3139      glClearStencil(0);
3140      state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3141      state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
3142      glClearDepth(1.0f);
3143      state_.SetDeviceDepthMask(GL_TRUE);
3144      state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3145      bool reset_draw_buffer = false;
3146      if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3147          group_->draw_buffer() == GL_NONE) {
3148        reset_draw_buffer = true;
3149        GLenum buf = GL_BACK;
3150        if (GetBackbufferServiceId() != 0)  // emulated backbuffer
3151          buf = GL_COLOR_ATTACHMENT0;
3152        glDrawBuffersARB(1, &buf);
3153      }
3154      glClear(backbuffer_needs_clear_bits_);
3155      if (reset_draw_buffer) {
3156        GLenum buf = GL_NONE;
3157        glDrawBuffersARB(1, &buf);
3158      }
3159      backbuffer_needs_clear_bits_ = 0;
3160      RestoreClearState();
3161    }
3162    return true;
3163  }
3164
3165  if (framebuffer_manager()->IsComplete(framebuffer)) {
3166    return true;
3167  }
3168
3169  GLenum completeness = framebuffer->IsPossiblyComplete();
3170  if (completeness != GL_FRAMEBUFFER_COMPLETE) {
3171    LOCAL_SET_GL_ERROR(
3172        GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
3173    return false;
3174  }
3175
3176  // Are all the attachments cleared?
3177  if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3178      texture_manager()->HaveUnclearedMips()) {
3179    if (!framebuffer->IsCleared()) {
3180      // Can we clear them?
3181      if (framebuffer->GetStatus(texture_manager(), target) !=
3182          GL_FRAMEBUFFER_COMPLETE) {
3183        LOCAL_SET_GL_ERROR(
3184            GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3185            "framebuffer incomplete (clear)");
3186        return false;
3187      }
3188      ClearUnclearedAttachments(target, framebuffer);
3189    }
3190  }
3191
3192  if (!framebuffer_manager()->IsComplete(framebuffer)) {
3193    if (framebuffer->GetStatus(texture_manager(), target) !=
3194        GL_FRAMEBUFFER_COMPLETE) {
3195      LOCAL_SET_GL_ERROR(
3196          GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3197          "framebuffer incomplete (check)");
3198      return false;
3199    }
3200    framebuffer_manager()->MarkAsComplete(framebuffer);
3201  }
3202
3203  // NOTE: At this point we don't know if the framebuffer is complete but
3204  // we DO know that everything that needs to be cleared has been cleared.
3205  return true;
3206}
3207
3208bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
3209  if (!features().chromium_framebuffer_multisample) {
3210    bool valid = CheckFramebufferValid(
3211        framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3212        func_name);
3213
3214    if (valid)
3215      OnUseFramebuffer();
3216
3217    return valid;
3218  }
3219  return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
3220                               GL_DRAW_FRAMEBUFFER_EXT,
3221                               func_name) &&
3222         CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
3223                               GL_READ_FRAMEBUFFER_EXT,
3224                               func_name);
3225}
3226
3227bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3228    const char* func_name) {
3229  Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3230      framebuffer_state_.bound_read_framebuffer.get() :
3231      framebuffer_state_.bound_draw_framebuffer.get();
3232  if (!framebuffer)
3233    return true;
3234  if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3235    LOCAL_SET_GL_ERROR(
3236        GL_INVALID_OPERATION, func_name, "no color image attached");
3237    return false;
3238  }
3239  return true;
3240}
3241
3242gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
3243  Framebuffer* framebuffer =
3244      GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3245  if (framebuffer != NULL) {
3246    const Framebuffer::Attachment* attachment =
3247        framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
3248    if (attachment) {
3249      return gfx::Size(attachment->width(), attachment->height());
3250    }
3251    return gfx::Size(0, 0);
3252  } else if (offscreen_target_frame_buffer_.get()) {
3253    return offscreen_size_;
3254  } else {
3255    return surface_->GetSize();
3256  }
3257}
3258
3259GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3260  Framebuffer* framebuffer =
3261    GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3262  if (framebuffer != NULL) {
3263    return framebuffer->GetColorAttachmentTextureType();
3264  } else {
3265    return GL_UNSIGNED_BYTE;
3266  }
3267}
3268
3269GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
3270  Framebuffer* framebuffer =
3271      GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3272  if (framebuffer != NULL) {
3273    return framebuffer->GetColorAttachmentFormat();
3274  } else if (offscreen_target_frame_buffer_.get()) {
3275    return offscreen_target_color_format_;
3276  } else {
3277    return back_buffer_color_format_;
3278  }
3279}
3280
3281GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
3282  Framebuffer* framebuffer =
3283      GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3284  if (framebuffer != NULL) {
3285    return framebuffer->GetColorAttachmentFormat();
3286  } else if (offscreen_target_frame_buffer_.get()) {
3287    return offscreen_target_color_format_;
3288  } else {
3289    return back_buffer_color_format_;
3290  }
3291}
3292
3293void GLES2DecoderImpl::UpdateParentTextureInfo() {
3294  if (!offscreen_saved_color_texture_info_.get())
3295    return;
3296  GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3297  glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3298  texture_manager()->SetLevelInfo(
3299      offscreen_saved_color_texture_info_.get(),
3300      GL_TEXTURE_2D,
3301      0,  // level
3302      GL_RGBA,
3303      offscreen_size_.width(),
3304      offscreen_size_.height(),
3305      1,  // depth
3306      0,  // border
3307      GL_RGBA,
3308      GL_UNSIGNED_BYTE,
3309      true);
3310  texture_manager()->SetParameteri(
3311      "UpdateParentTextureInfo",
3312      GetErrorState(),
3313      offscreen_saved_color_texture_info_.get(),
3314      GL_TEXTURE_MAG_FILTER,
3315      GL_LINEAR);
3316  texture_manager()->SetParameteri(
3317      "UpdateParentTextureInfo",
3318      GetErrorState(),
3319      offscreen_saved_color_texture_info_.get(),
3320      GL_TEXTURE_MIN_FILTER,
3321      GL_LINEAR);
3322  texture_manager()->SetParameteri(
3323      "UpdateParentTextureInfo",
3324      GetErrorState(),
3325      offscreen_saved_color_texture_info_.get(),
3326      GL_TEXTURE_WRAP_S,
3327      GL_CLAMP_TO_EDGE);
3328  texture_manager()->SetParameteri(
3329      "UpdateParentTextureInfo",
3330      GetErrorState(),
3331      offscreen_saved_color_texture_info_.get(),
3332      GL_TEXTURE_WRAP_T,
3333      GL_CLAMP_TO_EDGE);
3334  TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3335      &state_, target);
3336  glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
3337}
3338
3339void GLES2DecoderImpl::SetResizeCallback(
3340    const base::Callback<void(gfx::Size, float)>& callback) {
3341  resize_callback_ = callback;
3342}
3343
3344Logger* GLES2DecoderImpl::GetLogger() {
3345  return &logger_;
3346}
3347
3348void GLES2DecoderImpl::BeginDecoding() {
3349  gpu_tracer_->BeginDecoding();
3350  gpu_trace_commands_ = gpu_tracer_->IsTracing();
3351  gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3352                        (*cb_command_trace_category_ != 0);
3353}
3354
3355void GLES2DecoderImpl::EndDecoding() {
3356  gpu_tracer_->EndDecoding();
3357}
3358
3359ErrorState* GLES2DecoderImpl::GetErrorState() {
3360  return state_.GetErrorState();
3361}
3362
3363void GLES2DecoderImpl::SetShaderCacheCallback(
3364    const ShaderCacheCallback& callback) {
3365  shader_cache_callback_ = callback;
3366}
3367
3368void GLES2DecoderImpl::SetWaitSyncPointCallback(
3369    const WaitSyncPointCallback& callback) {
3370  wait_sync_point_callback_ = callback;
3371}
3372
3373AsyncPixelTransferManager*
3374    GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3375  return async_pixel_transfer_manager_.get();
3376}
3377
3378void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3379  async_pixel_transfer_manager_.reset();
3380}
3381
3382void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3383    AsyncPixelTransferManager* manager) {
3384  async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3385}
3386
3387bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3388                                           uint32* service_texture_id) {
3389  TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3390  if (texture_ref) {
3391    *service_texture_id = texture_ref->service_id();
3392    return true;
3393  }
3394  return false;
3395}
3396
3397uint32 GLES2DecoderImpl::GetTextureUploadCount() {
3398  return texture_state_.texture_upload_count +
3399         async_pixel_transfer_manager_->GetTextureUploadCount();
3400}
3401
3402base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
3403  return texture_state_.total_texture_upload_time +
3404         async_pixel_transfer_manager_->GetTotalTextureUploadTime();
3405}
3406
3407base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3408  return total_processing_commands_time_;
3409}
3410
3411void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3412  total_processing_commands_time_ += time;
3413}
3414
3415void GLES2DecoderImpl::Destroy(bool have_context) {
3416  if (!initialized())
3417    return;
3418
3419  DCHECK(!have_context || context_->IsCurrent(NULL));
3420
3421  // Unbind everything.
3422  state_.vertex_attrib_manager = NULL;
3423  state_.default_vertex_attrib_manager = NULL;
3424  state_.texture_units.clear();
3425  state_.bound_array_buffer = NULL;
3426  state_.current_queries.clear();
3427  framebuffer_state_.bound_read_framebuffer = NULL;
3428  framebuffer_state_.bound_draw_framebuffer = NULL;
3429  state_.bound_renderbuffer = NULL;
3430
3431  if (offscreen_saved_color_texture_info_.get()) {
3432    DCHECK(offscreen_target_color_texture_);
3433    DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3434              offscreen_saved_color_texture_->id());
3435    offscreen_saved_color_texture_->Invalidate();
3436    offscreen_saved_color_texture_info_ = NULL;
3437  }
3438  if (have_context) {
3439    if (copy_texture_CHROMIUM_.get()) {
3440      copy_texture_CHROMIUM_->Destroy();
3441      copy_texture_CHROMIUM_.reset();
3442    }
3443
3444    if (state_.current_program.get()) {
3445      program_manager()->UnuseProgram(shader_manager(),
3446                                      state_.current_program.get());
3447    }
3448
3449    if (attrib_0_buffer_id_) {
3450      glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3451    }
3452    if (fixed_attrib_buffer_id_) {
3453      glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3454    }
3455
3456    if (validation_texture_) {
3457      glDeleteTextures(1, &validation_texture_);
3458      glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3459      glDeleteFramebuffersEXT(1, &validation_fbo_);
3460    }
3461
3462    if (offscreen_target_frame_buffer_.get())
3463      offscreen_target_frame_buffer_->Destroy();
3464    if (offscreen_target_color_texture_.get())
3465      offscreen_target_color_texture_->Destroy();
3466    if (offscreen_target_color_render_buffer_.get())
3467      offscreen_target_color_render_buffer_->Destroy();
3468    if (offscreen_target_depth_render_buffer_.get())
3469      offscreen_target_depth_render_buffer_->Destroy();
3470    if (offscreen_target_stencil_render_buffer_.get())
3471      offscreen_target_stencil_render_buffer_->Destroy();
3472    if (offscreen_saved_frame_buffer_.get())
3473      offscreen_saved_frame_buffer_->Destroy();
3474    if (offscreen_saved_color_texture_.get())
3475      offscreen_saved_color_texture_->Destroy();
3476    if (offscreen_resolved_frame_buffer_.get())
3477      offscreen_resolved_frame_buffer_->Destroy();
3478    if (offscreen_resolved_color_texture_.get())
3479      offscreen_resolved_color_texture_->Destroy();
3480  } else {
3481    if (offscreen_target_frame_buffer_.get())
3482      offscreen_target_frame_buffer_->Invalidate();
3483    if (offscreen_target_color_texture_.get())
3484      offscreen_target_color_texture_->Invalidate();
3485    if (offscreen_target_color_render_buffer_.get())
3486      offscreen_target_color_render_buffer_->Invalidate();
3487    if (offscreen_target_depth_render_buffer_.get())
3488      offscreen_target_depth_render_buffer_->Invalidate();
3489    if (offscreen_target_stencil_render_buffer_.get())
3490      offscreen_target_stencil_render_buffer_->Invalidate();
3491    if (offscreen_saved_frame_buffer_.get())
3492      offscreen_saved_frame_buffer_->Invalidate();
3493    if (offscreen_saved_color_texture_.get())
3494      offscreen_saved_color_texture_->Invalidate();
3495    if (offscreen_resolved_frame_buffer_.get())
3496      offscreen_resolved_frame_buffer_->Invalidate();
3497    if (offscreen_resolved_color_texture_.get())
3498      offscreen_resolved_color_texture_->Invalidate();
3499  }
3500
3501  // Current program must be cleared after calling ProgramManager::UnuseProgram.
3502  // Otherwise, we can leak objects. http://crbug.com/258772.
3503  // state_.current_program must be reset before group_ is reset because
3504  // the later deletes the ProgramManager object that referred by
3505  // state_.current_program object.
3506  state_.current_program = NULL;
3507
3508  copy_texture_CHROMIUM_.reset();
3509
3510  if (query_manager_.get()) {
3511    query_manager_->Destroy(have_context);
3512    query_manager_.reset();
3513  }
3514
3515  if (vertex_array_manager_ .get()) {
3516    vertex_array_manager_->Destroy(have_context);
3517    vertex_array_manager_.reset();
3518  }
3519
3520  if (image_manager_.get()) {
3521    image_manager_->Destroy(have_context);
3522    image_manager_.reset();
3523  }
3524
3525  offscreen_target_frame_buffer_.reset();
3526  offscreen_target_color_texture_.reset();
3527  offscreen_target_color_render_buffer_.reset();
3528  offscreen_target_depth_render_buffer_.reset();
3529  offscreen_target_stencil_render_buffer_.reset();
3530  offscreen_saved_frame_buffer_.reset();
3531  offscreen_saved_color_texture_.reset();
3532  offscreen_resolved_frame_buffer_.reset();
3533  offscreen_resolved_color_texture_.reset();
3534
3535  // Need to release these before releasing |group_| which may own the
3536  // ShaderTranslatorCache.
3537  fragment_translator_ = NULL;
3538  vertex_translator_ = NULL;
3539
3540  // Should destroy the transfer manager before the texture manager held
3541  // by the context group.
3542  async_pixel_transfer_manager_.reset();
3543
3544  if (group_.get()) {
3545    framebuffer_manager()->RemoveObserver(this);
3546    group_->Destroy(this, have_context);
3547    group_ = NULL;
3548  }
3549
3550  if (context_.get()) {
3551    context_->ReleaseCurrent(NULL);
3552    context_ = NULL;
3553  }
3554
3555#if defined(OS_MACOSX)
3556  for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3557       it != texture_to_io_surface_map_.end(); ++it) {
3558    CFRelease(it->second);
3559  }
3560  texture_to_io_surface_map_.clear();
3561#endif
3562}
3563
3564void GLES2DecoderImpl::SetSurface(
3565    const scoped_refptr<gfx::GLSurface>& surface) {
3566  DCHECK(context_->IsCurrent(NULL));
3567  DCHECK(surface_.get());
3568  surface_ = surface;
3569  RestoreCurrentFramebufferBindings();
3570}
3571
3572void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3573  if (!offscreen_saved_color_texture_.get()) {
3574    LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3575    return;
3576  }
3577  if (!offscreen_saved_color_texture_info_.get()) {
3578    GLuint service_id = offscreen_saved_color_texture_->id();
3579    offscreen_saved_color_texture_info_ = TextureRef::Create(
3580        texture_manager(), 0, service_id);
3581    texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3582                                 GL_TEXTURE_2D);
3583    UpdateParentTextureInfo();
3584  }
3585  mailbox_manager()->ProduceTexture(
3586      GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
3587}
3588
3589bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3590  bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3591  if (!is_offscreen) {
3592    LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3593               << " with an onscreen framebuffer.";
3594    return false;
3595  }
3596
3597  if (offscreen_size_ == size)
3598    return true;
3599
3600  offscreen_size_ = size;
3601  int w = offscreen_size_.width();
3602  int h = offscreen_size_.height();
3603  if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3604    LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3605               << "to allocate storage due to excessive dimensions.";
3606    return false;
3607  }
3608
3609  // Reallocate the offscreen target buffers.
3610  DCHECK(offscreen_target_color_format_);
3611  if (IsOffscreenBufferMultisampled()) {
3612    if (!offscreen_target_color_render_buffer_->AllocateStorage(
3613            feature_info_.get(),
3614            offscreen_size_,
3615            offscreen_target_color_format_,
3616            offscreen_target_samples_)) {
3617      LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3618                 << "to allocate storage for offscreen target color buffer.";
3619      return false;
3620    }
3621  } else {
3622    if (!offscreen_target_color_texture_->AllocateStorage(
3623        offscreen_size_, offscreen_target_color_format_, false)) {
3624      LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3625                 << "to allocate storage for offscreen target color texture.";
3626      return false;
3627    }
3628  }
3629  if (offscreen_target_depth_format_ &&
3630      !offscreen_target_depth_render_buffer_->AllocateStorage(
3631          feature_info_.get(),
3632          offscreen_size_,
3633          offscreen_target_depth_format_,
3634          offscreen_target_samples_)) {
3635    LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3636               << "to allocate storage for offscreen target depth buffer.";
3637    return false;
3638  }
3639  if (offscreen_target_stencil_format_ &&
3640      !offscreen_target_stencil_render_buffer_->AllocateStorage(
3641          feature_info_.get(),
3642          offscreen_size_,
3643          offscreen_target_stencil_format_,
3644          offscreen_target_samples_)) {
3645    LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3646               << "to allocate storage for offscreen target stencil buffer.";
3647    return false;
3648  }
3649
3650  // Attach the offscreen target buffers to the target frame buffer.
3651  if (IsOffscreenBufferMultisampled()) {
3652    offscreen_target_frame_buffer_->AttachRenderBuffer(
3653        GL_COLOR_ATTACHMENT0,
3654        offscreen_target_color_render_buffer_.get());
3655  } else {
3656    offscreen_target_frame_buffer_->AttachRenderTexture(
3657        offscreen_target_color_texture_.get());
3658  }
3659  if (offscreen_target_depth_format_) {
3660    offscreen_target_frame_buffer_->AttachRenderBuffer(
3661        GL_DEPTH_ATTACHMENT,
3662        offscreen_target_depth_render_buffer_.get());
3663  }
3664  const bool packed_depth_stencil =
3665      offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3666  if (packed_depth_stencil) {
3667    offscreen_target_frame_buffer_->AttachRenderBuffer(
3668        GL_STENCIL_ATTACHMENT,
3669        offscreen_target_depth_render_buffer_.get());
3670  } else if (offscreen_target_stencil_format_) {
3671    offscreen_target_frame_buffer_->AttachRenderBuffer(
3672        GL_STENCIL_ATTACHMENT,
3673        offscreen_target_stencil_render_buffer_.get());
3674  }
3675
3676  if (offscreen_target_frame_buffer_->CheckStatus() !=
3677      GL_FRAMEBUFFER_COMPLETE) {
3678      LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3679                 << "because offscreen FBO was incomplete.";
3680    return false;
3681  }
3682
3683  // Clear the target frame buffer.
3684  {
3685    ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3686    glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3687        offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3688    state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3689    glClearStencil(0);
3690    state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3691    state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
3692    glClearDepth(0);
3693    state_.SetDeviceDepthMask(GL_TRUE);
3694    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3695    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3696    RestoreClearState();
3697  }
3698
3699  // Destroy the offscreen resolved framebuffers.
3700  if (offscreen_resolved_frame_buffer_.get())
3701    offscreen_resolved_frame_buffer_->Destroy();
3702  if (offscreen_resolved_color_texture_.get())
3703    offscreen_resolved_color_texture_->Destroy();
3704  offscreen_resolved_color_texture_.reset();
3705  offscreen_resolved_frame_buffer_.reset();
3706
3707  return true;
3708}
3709
3710error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3711                                                    const void* cmd_data) {
3712  const gles2::cmds::ResizeCHROMIUM& c =
3713      *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
3714  if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
3715    return error::kDeferCommandUntilLater;
3716
3717  GLuint width = static_cast<GLuint>(c.width);
3718  GLuint height = static_cast<GLuint>(c.height);
3719  GLfloat scale_factor = c.scale_factor;
3720  TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
3721
3722  width = std::max(1U, width);
3723  height = std::max(1U, height);
3724
3725#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3726    !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
3727  // Make sure that we are done drawing to the back buffer before resizing.
3728  glFinish();
3729#endif
3730  bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3731  if (is_offscreen) {
3732    if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3733      LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3734                 << "ResizeOffscreenFrameBuffer failed.";
3735      return error::kLostContext;
3736    }
3737  }
3738
3739  if (!resize_callback_.is_null()) {
3740    resize_callback_.Run(gfx::Size(width, height), scale_factor);
3741    DCHECK(context_->IsCurrent(surface_.get()));
3742    if (!context_->IsCurrent(surface_.get())) {
3743      LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3744                 << "current after resize callback.";
3745      return error::kLostContext;
3746    }
3747  }
3748
3749  return error::kNoError;
3750}
3751
3752const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3753  if (command_id > kStartPoint && command_id < kNumCommands) {
3754    return gles2::GetCommandName(static_cast<CommandId>(command_id));
3755  }
3756  return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3757}
3758
3759// Decode a command, and call the corresponding GL functions.
3760// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3761// of commands at once, and is now only used for tests that need to track
3762// individual commands.
3763error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3764                                         unsigned int arg_count,
3765                                         const void* cmd_data) {
3766  return DoCommands(1, cmd_data, arg_count + 1, 0);
3767}
3768
3769// Decode multiple commands, and call the corresponding GL functions.
3770// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3771// changed by a (malicious) client at any time, so if validation has to happen,
3772// it should operate on a copy of them.
3773// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3774// interest of performance in this critical execution loop.
3775template <bool DebugImpl>
3776error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3777                                              const void* buffer,
3778                                              int num_entries,
3779                                              int* entries_processed) {
3780  commands_to_process_ = num_commands;
3781  error::Error result = error::kNoError;
3782  const CommandBufferEntry* cmd_data =
3783      static_cast<const CommandBufferEntry*>(buffer);
3784  int process_pos = 0;
3785  unsigned int command = 0;
3786
3787  while (process_pos < num_entries && result == error::kNoError &&
3788         commands_to_process_--) {
3789    const unsigned int size = cmd_data->value_header.size;
3790    command = cmd_data->value_header.command;
3791
3792    if (size == 0) {
3793      result = error::kInvalidSize;
3794      break;
3795    }
3796
3797    if (static_cast<int>(size) + process_pos > num_entries) {
3798      result = error::kOutOfBounds;
3799      break;
3800    }
3801
3802    if (DebugImpl) {
3803      TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3804                         GetCommandName(command));
3805
3806      if (log_commands()) {
3807        LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3808                   << "cmd: " << GetCommandName(command);
3809      }
3810    }
3811
3812    const unsigned int arg_count = size - 1;
3813    unsigned int command_index = command - kStartPoint - 1;
3814    if (command_index < arraysize(command_info)) {
3815      const CommandInfo& info = command_info[command_index];
3816      unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3817      if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3818          (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3819        bool doing_gpu_trace = false;
3820        if (DebugImpl && gpu_trace_commands_) {
3821          if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3822            doing_gpu_trace = true;
3823            gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3824          }
3825        }
3826
3827        uint32 immediate_data_size = (arg_count - info_arg_count) *
3828                                     sizeof(CommandBufferEntry);  // NOLINT
3829
3830        result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
3831
3832        if (DebugImpl && doing_gpu_trace)
3833          gpu_tracer_->End(kTraceDecoder);
3834
3835        if (DebugImpl && debug()) {
3836          GLenum error;
3837          while ((error = glGetError()) != GL_NO_ERROR) {
3838            LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3839                       << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3840                       << " : " << GetCommandName(command);
3841            LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3842          }
3843        }
3844      } else {
3845        result = error::kInvalidArguments;
3846      }
3847    } else {
3848      result = DoCommonCommand(command, arg_count, cmd_data);
3849    }
3850
3851    if (DebugImpl) {
3852      TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3853                       GetCommandName(command));
3854    }
3855
3856    if (result == error::kNoError &&
3857        current_decoder_error_ != error::kNoError) {
3858      result = current_decoder_error_;
3859      current_decoder_error_ = error::kNoError;
3860    }
3861
3862    if (result != error::kDeferCommandUntilLater) {
3863      process_pos += size;
3864      cmd_data += size;
3865    }
3866  }
3867
3868  if (entries_processed)
3869    *entries_processed = process_pos;
3870
3871  if (error::IsError(result)) {
3872    LOG(ERROR) << "Error: " << result << " for Command "
3873               << GetCommandName(command);
3874  }
3875
3876  return result;
3877}
3878
3879error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3880                                          const void* buffer,
3881                                          int num_entries,
3882                                          int* entries_processed) {
3883  if (gpu_debug_commands_) {
3884    return DoCommandsImpl<true>(
3885        num_commands, buffer, num_entries, entries_processed);
3886  } else {
3887    return DoCommandsImpl<false>(
3888        num_commands, buffer, num_entries, entries_processed);
3889  }
3890}
3891
3892void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3893  buffer_manager()->RemoveBuffer(client_id);
3894}
3895
3896bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3897  if (GetProgram(client_id)) {
3898    return false;
3899  }
3900  GLuint service_id = glCreateProgram();
3901  if (service_id != 0) {
3902    CreateProgram(client_id, service_id);
3903  }
3904  return true;
3905}
3906
3907bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3908  if (GetShader(client_id)) {
3909    return false;
3910  }
3911  GLuint service_id = glCreateShader(type);
3912  if (service_id != 0) {
3913    CreateShader(client_id, service_id, type);
3914  }
3915  return true;
3916}
3917
3918void GLES2DecoderImpl::DoFinish() {
3919  glFinish();
3920  ProcessPendingReadPixels();
3921  ProcessPendingQueries();
3922}
3923
3924void GLES2DecoderImpl::DoFlush() {
3925  glFlush();
3926  ProcessPendingQueries();
3927}
3928
3929void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
3930  GLuint texture_index = texture_unit - GL_TEXTURE0;
3931  if (texture_index >= state_.texture_units.size()) {
3932    LOCAL_SET_GL_ERROR_INVALID_ENUM(
3933        "glActiveTexture", texture_unit, "texture_unit");
3934    return;
3935  }
3936  state_.active_texture_unit = texture_index;
3937  glActiveTexture(texture_unit);
3938}
3939
3940void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
3941  Buffer* buffer = NULL;
3942  GLuint service_id = 0;
3943  if (client_id != 0) {
3944    buffer = GetBuffer(client_id);
3945    if (!buffer) {
3946      if (!group_->bind_generates_resource()) {
3947        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3948                           "glBindBuffer",
3949                           "id not generated by glGenBuffers");
3950        return;
3951      }
3952
3953      // It's a new id so make a buffer buffer for it.
3954      glGenBuffersARB(1, &service_id);
3955      CreateBuffer(client_id, service_id);
3956      buffer = GetBuffer(client_id);
3957      IdAllocatorInterface* id_allocator =
3958          group_->GetIdAllocator(id_namespaces::kBuffers);
3959      id_allocator->MarkAsUsed(client_id);
3960    }
3961  }
3962  LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3963  if (buffer) {
3964    if (!buffer_manager()->SetTarget(buffer, target)) {
3965      LOCAL_SET_GL_ERROR(
3966          GL_INVALID_OPERATION,
3967          "glBindBuffer", "buffer bound to more than 1 target");
3968      return;
3969    }
3970    service_id = buffer->service_id();
3971  }
3972  switch (target) {
3973    case GL_ARRAY_BUFFER:
3974      state_.bound_array_buffer = buffer;
3975      break;
3976    case GL_ELEMENT_ARRAY_BUFFER:
3977      state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
3978      break;
3979    default:
3980      NOTREACHED();  // Validation should prevent us getting here.
3981      break;
3982  }
3983  glBindBuffer(target, service_id);
3984}
3985
3986bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3987    bool all_draw_buffers) {
3988  Framebuffer* framebuffer =
3989      GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3990  if (!all_draw_buffers || !framebuffer) {
3991    return (GLES2Util::GetChannelsForFormat(
3992        GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3993  }
3994  return framebuffer->HasAlphaMRT();
3995}
3996
3997bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
3998  Framebuffer* framebuffer =
3999      GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4000  if (framebuffer) {
4001    return framebuffer->HasDepthAttachment();
4002  }
4003  if (offscreen_target_frame_buffer_.get()) {
4004    return offscreen_target_depth_format_ != 0;
4005  }
4006  return back_buffer_has_depth_;
4007}
4008
4009bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
4010  Framebuffer* framebuffer =
4011      GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4012  if (framebuffer) {
4013    return framebuffer->HasStencilAttachment();
4014  }
4015  if (offscreen_target_frame_buffer_.get()) {
4016    return offscreen_target_stencil_format_ != 0 ||
4017           offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4018  }
4019  return back_buffer_has_stencil_;
4020}
4021
4022void GLES2DecoderImpl::ApplyDirtyState() {
4023  if (framebuffer_state_.clear_state_dirty) {
4024    bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4025    state_.SetDeviceColorMask(state_.color_mask_red,
4026                              state_.color_mask_green,
4027                              state_.color_mask_blue,
4028                              state_.color_mask_alpha && have_alpha);
4029
4030    bool have_depth = BoundFramebufferHasDepthAttachment();
4031    state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4032
4033    bool have_stencil = BoundFramebufferHasStencilAttachment();
4034    state_.SetDeviceStencilMaskSeparate(
4035        GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
4036    state_.SetDeviceStencilMaskSeparate(
4037        GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
4038
4039    state_.SetDeviceCapabilityState(
4040        GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4041    state_.SetDeviceCapabilityState(
4042        GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
4043    framebuffer_state_.clear_state_dirty = false;
4044  }
4045}
4046
4047GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
4048  return (offscreen_target_frame_buffer_.get())
4049             ? offscreen_target_frame_buffer_->id()
4050             : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
4051}
4052
4053void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
4054  TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4055               "context", logger_.GetLogPrefix());
4056  // Restore the Framebuffer first because of bugs in Intel drivers.
4057  // Intel drivers incorrectly clip the viewport settings to
4058  // the size of the current framebuffer object.
4059  RestoreFramebufferBindings();
4060  state_.RestoreState(prev_state);
4061}
4062
4063void GLES2DecoderImpl::RestoreFramebufferBindings() const {
4064  GLuint service_id =
4065      framebuffer_state_.bound_draw_framebuffer.get()
4066          ? framebuffer_state_.bound_draw_framebuffer->service_id()
4067          : GetBackbufferServiceId();
4068  if (!features().chromium_framebuffer_multisample) {
4069    glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4070  } else {
4071    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
4072    service_id = framebuffer_state_.bound_read_framebuffer.get()
4073                     ? framebuffer_state_.bound_read_framebuffer->service_id()
4074                     : GetBackbufferServiceId();
4075    glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4076  }
4077  OnFboChanged();
4078}
4079
4080void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4081  state_.RestoreRenderbufferBindings();
4082}
4083
4084void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
4085  Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4086  if (texture) {
4087    GLenum target = texture->target();
4088    glBindTexture(target, service_id);
4089    glTexParameteri(
4090        target, GL_TEXTURE_WRAP_S, texture->wrap_s());
4091    glTexParameteri(
4092        target, GL_TEXTURE_WRAP_T, texture->wrap_t());
4093    glTexParameteri(
4094        target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
4095    glTexParameteri(
4096        target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
4097    RestoreTextureUnitBindings(state_.active_texture_unit);
4098  }
4099}
4100
4101void GLES2DecoderImpl::ClearAllAttributes() const {
4102  // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4103  // other VAOs.
4104  if (feature_info_->feature_flags().native_vertex_array_object)
4105    glBindVertexArrayOES(0);
4106
4107  for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4108    if (i != 0) // Never disable attribute 0
4109      glDisableVertexAttribArray(i);
4110    if(features().angle_instanced_arrays)
4111      glVertexAttribDivisorANGLE(i, 0);
4112  }
4113}
4114
4115void GLES2DecoderImpl::RestoreAllAttributes() const {
4116  state_.RestoreVertexAttribs();
4117}
4118
4119void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4120  state_.SetIgnoreCachedStateForTest(ignore);
4121}
4122
4123void GLES2DecoderImpl::OnFboChanged() const {
4124  if (workarounds().restore_scissor_on_fbo_change)
4125    state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4126}
4127
4128// Called after the FBO is checked for completeness.
4129void GLES2DecoderImpl::OnUseFramebuffer() const {
4130  if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4131    state_.fbo_binding_for_scissor_workaround_dirty_ = false;
4132    // The driver forgets the correct scissor when modifying the FBO binding.
4133    glScissor(state_.scissor_x,
4134              state_.scissor_y,
4135              state_.scissor_width,
4136              state_.scissor_height);
4137
4138    // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4139    // it's unclear how this bug works.
4140    glFlush();
4141  }
4142}
4143
4144void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
4145  Framebuffer* framebuffer = NULL;
4146  GLuint service_id = 0;
4147  if (client_id != 0) {
4148    framebuffer = GetFramebuffer(client_id);
4149    if (!framebuffer) {
4150      if (!group_->bind_generates_resource()) {
4151        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4152                           "glBindFramebuffer",
4153                           "id not generated by glGenFramebuffers");
4154        return;
4155      }
4156
4157      // It's a new id so make a framebuffer framebuffer for it.
4158      glGenFramebuffersEXT(1, &service_id);
4159      CreateFramebuffer(client_id, service_id);
4160      framebuffer = GetFramebuffer(client_id);
4161      IdAllocatorInterface* id_allocator =
4162          group_->GetIdAllocator(id_namespaces::kFramebuffers);
4163      id_allocator->MarkAsUsed(client_id);
4164    } else {
4165      service_id = framebuffer->service_id();
4166    }
4167    framebuffer->MarkAsValid();
4168  }
4169  LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
4170
4171  if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
4172    framebuffer_state_.bound_draw_framebuffer = framebuffer;
4173  }
4174
4175  // vmiura: This looks like dup code
4176  if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
4177    framebuffer_state_.bound_read_framebuffer = framebuffer;
4178  }
4179
4180  framebuffer_state_.clear_state_dirty = true;
4181
4182  // If we are rendering to the backbuffer get the FBO id for any simulated
4183  // backbuffer.
4184  if (framebuffer == NULL) {
4185    service_id = GetBackbufferServiceId();
4186  }
4187
4188  glBindFramebufferEXT(target, service_id);
4189  OnFboChanged();
4190}
4191
4192void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
4193  Renderbuffer* renderbuffer = NULL;
4194  GLuint service_id = 0;
4195  if (client_id != 0) {
4196    renderbuffer = GetRenderbuffer(client_id);
4197    if (!renderbuffer) {
4198      if (!group_->bind_generates_resource()) {
4199        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4200                           "glBindRenderbuffer",
4201                           "id not generated by glGenRenderbuffers");
4202        return;
4203      }
4204
4205      // It's a new id so make a renderbuffer for it.
4206      glGenRenderbuffersEXT(1, &service_id);
4207      CreateRenderbuffer(client_id, service_id);
4208      renderbuffer = GetRenderbuffer(client_id);
4209      IdAllocatorInterface* id_allocator =
4210          group_->GetIdAllocator(id_namespaces::kRenderbuffers);
4211      id_allocator->MarkAsUsed(client_id);
4212    } else {
4213      service_id = renderbuffer->service_id();
4214    }
4215    renderbuffer->MarkAsValid();
4216  }
4217  LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
4218  state_.bound_renderbuffer = renderbuffer;
4219  state_.bound_renderbuffer_valid = true;
4220  glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
4221}
4222
4223void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
4224  TextureRef* texture_ref = NULL;
4225  GLuint service_id = 0;
4226  if (client_id != 0) {
4227    texture_ref = GetTexture(client_id);
4228    if (!texture_ref) {
4229      if (!group_->bind_generates_resource()) {
4230        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4231                           "glBindTexture",
4232                           "id not generated by glGenTextures");
4233        return;
4234      }
4235
4236      // It's a new id so make a texture texture for it.
4237      glGenTextures(1, &service_id);
4238      DCHECK_NE(0u, service_id);
4239      CreateTexture(client_id, service_id);
4240      texture_ref = GetTexture(client_id);
4241      IdAllocatorInterface* id_allocator =
4242          group_->GetIdAllocator(id_namespaces::kTextures);
4243      id_allocator->MarkAsUsed(client_id);
4244    }
4245  } else {
4246    texture_ref = texture_manager()->GetDefaultTextureInfo(target);
4247  }
4248
4249  // Check the texture exists
4250  if (texture_ref) {
4251    Texture* texture = texture_ref->texture();
4252    // Check that we are not trying to bind it to a different target.
4253    if (texture->target() != 0 && texture->target() != target) {
4254      LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4255                         "glBindTexture",
4256                         "texture bound to more than 1 target.");
4257      return;
4258    }
4259    LogClientServiceForInfo(texture, client_id, "glBindTexture");
4260    if (texture->target() == 0) {
4261      texture_manager()->SetTarget(texture_ref, target);
4262    }
4263    glBindTexture(target, texture->service_id());
4264  } else {
4265    glBindTexture(target, 0);
4266  }
4267
4268  TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4269  unit.bind_target = target;
4270  switch (target) {
4271    case GL_TEXTURE_2D:
4272      unit.bound_texture_2d = texture_ref;
4273      break;
4274    case GL_TEXTURE_CUBE_MAP:
4275      unit.bound_texture_cube_map = texture_ref;
4276      break;
4277    case GL_TEXTURE_EXTERNAL_OES:
4278      unit.bound_texture_external_oes = texture_ref;
4279      break;
4280    case GL_TEXTURE_RECTANGLE_ARB:
4281      unit.bound_texture_rectangle_arb = texture_ref;
4282      break;
4283    default:
4284      NOTREACHED();  // Validation should prevent us getting here.
4285      break;
4286  }
4287}
4288
4289void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
4290  if (state_.vertex_attrib_manager->Enable(index, false)) {
4291    if (index != 0 ||
4292        gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
4293      glDisableVertexAttribArray(index);
4294    }
4295  } else {
4296    LOCAL_SET_GL_ERROR(
4297        GL_INVALID_VALUE,
4298        "glDisableVertexAttribArray", "index out of range");
4299  }
4300}
4301
4302void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4303                                               GLsizei numAttachments,
4304                                               const GLenum* attachments) {
4305  Framebuffer* framebuffer =
4306      GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4307
4308  // Validates the attachments. If one of them fails
4309  // the whole command fails.
4310  for (GLsizei i = 0; i < numAttachments; ++i) {
4311    if ((framebuffer &&
4312        !validators_->attachment.IsValid(attachments[i])) ||
4313       (!framebuffer &&
4314        !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
4315      LOCAL_SET_GL_ERROR_INVALID_ENUM(
4316          "glDiscardFramebufferEXT", attachments[i], "attachments");
4317      return;
4318    }
4319  }
4320
4321  // Marks each one of them as not cleared
4322  for (GLsizei i = 0; i < numAttachments; ++i) {
4323    if (framebuffer) {
4324      framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4325                                           texture_manager(),
4326                                           attachments[i],
4327                                           false);
4328    } else {
4329      switch (attachments[i]) {
4330        case GL_COLOR_EXT:
4331          backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4332          break;
4333        case GL_DEPTH_EXT:
4334          backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4335        case GL_STENCIL_EXT:
4336          backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4337          break;
4338        default:
4339          NOTREACHED();
4340          break;
4341      }
4342    }
4343  }
4344
4345  // If the default framebuffer is bound but we are still rendering to an
4346  // FBO, translate attachment names that refer to default framebuffer
4347  // channels to corresponding framebuffer attachments.
4348  scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4349  for (GLsizei i = 0; i < numAttachments; ++i) {
4350    GLenum attachment = attachments[i];
4351    if (!framebuffer && GetBackbufferServiceId()) {
4352      switch (attachment) {
4353        case GL_COLOR_EXT:
4354          attachment = GL_COLOR_ATTACHMENT0;
4355          break;
4356        case GL_DEPTH_EXT:
4357          attachment = GL_DEPTH_ATTACHMENT;
4358          break;
4359        case GL_STENCIL_EXT:
4360          attachment = GL_STENCIL_ATTACHMENT;
4361          break;
4362        default:
4363          NOTREACHED();
4364          return;
4365      }
4366    }
4367    translated_attachments[i] = attachment;
4368  }
4369
4370  ScopedRenderTo do_render(framebuffer);
4371  glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
4372}
4373
4374void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
4375  if (state_.vertex_attrib_manager->Enable(index, true)) {
4376    glEnableVertexAttribArray(index);
4377  } else {
4378    LOCAL_SET_GL_ERROR(
4379        GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
4380  }
4381}
4382
4383void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
4384  TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4385      &state_, target);
4386  if (!texture_ref ||
4387      !texture_manager()->CanGenerateMipmaps(texture_ref)) {
4388    LOCAL_SET_GL_ERROR(
4389        GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
4390    return;
4391  }
4392
4393  if (target == GL_TEXTURE_CUBE_MAP) {
4394    for (int i = 0; i < 6; ++i) {
4395      GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
4396      if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
4397        LOCAL_SET_GL_ERROR(
4398            GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
4399        return;
4400      }
4401    }
4402  } else {
4403    if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
4404      LOCAL_SET_GL_ERROR(
4405          GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
4406      return;
4407    }
4408  }
4409
4410  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
4411  // Workaround for Mac driver bug. In the large scheme of things setting
4412  // glTexParamter twice for glGenerateMipmap is probably not a lage performance
4413  // hit so there's probably no need to make this conditional. The bug appears
4414  // to be that if the filtering mode is set to something that doesn't require
4415  // mipmaps for rendering, or is never set to something other than the default,
4416  // then glGenerateMipmap misbehaves.
4417  if (workarounds().set_texture_filter_before_generating_mipmap) {
4418    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4419  }
4420  glGenerateMipmapEXT(target);
4421  if (workarounds().set_texture_filter_before_generating_mipmap) {
4422    glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4423                    texture_ref->texture()->min_filter());
4424  }
4425  GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
4426  if (error == GL_NO_ERROR) {
4427    texture_manager()->MarkMipmapsGenerated(texture_ref);
4428  }
4429}
4430
4431bool GLES2DecoderImpl::GetHelper(
4432    GLenum pname, GLint* params, GLsizei* num_written) {
4433  DCHECK(num_written);
4434  if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4435    switch (pname) {
4436      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4437        *num_written = 1;
4438        // Return the GL implementation's preferred format and (see below type)
4439        // if we have the GL extension that exposes this. This allows the GPU
4440        // client to use the implementation's preferred format for glReadPixels
4441        // for optimisation.
4442        //
4443        // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4444        // case when requested on integer/floating point buffers but which is
4445        // acceptable on GLES2 and with the GL_OES_read_format extension.
4446        //
4447        // Therefore if an error occurs we swallow the error and use the
4448        // internal implementation.
4449        if (params) {
4450          if (context_->HasExtension("GL_OES_read_format")) {
4451            ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4452                                               GetErrorState());
4453            glGetIntegerv(pname, params);
4454            if (glGetError() == GL_NO_ERROR)
4455              return true;
4456          }
4457          *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4458              GetBoundReadFrameBufferInternalFormat());
4459        }
4460        return true;
4461      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4462        *num_written = 1;
4463        if (params) {
4464          if (context_->HasExtension("GL_OES_read_format")) {
4465            ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4466                                               GetErrorState());
4467            glGetIntegerv(pname, params);
4468            if (glGetError() == GL_NO_ERROR)
4469              return true;
4470          }
4471          *params = GLES2Util::GetPreferredGLReadPixelsType(
4472              GetBoundReadFrameBufferInternalFormat(),
4473              GetBoundReadFrameBufferTextureType());
4474        }
4475        return true;
4476      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4477        *num_written = 1;
4478        if (params) {
4479          *params = group_->max_fragment_uniform_vectors();
4480        }
4481        return true;
4482      case GL_MAX_VARYING_VECTORS:
4483        *num_written = 1;
4484        if (params) {
4485          *params = group_->max_varying_vectors();
4486        }
4487        return true;
4488      case GL_MAX_VERTEX_UNIFORM_VECTORS:
4489        *num_written = 1;
4490        if (params) {
4491          *params = group_->max_vertex_uniform_vectors();
4492        }
4493        return true;
4494      }
4495  }
4496  switch (pname) {
4497    case GL_MAX_VIEWPORT_DIMS:
4498      if (offscreen_target_frame_buffer_.get()) {
4499        *num_written = 2;
4500        if (params) {
4501          params[0] = renderbuffer_manager()->max_renderbuffer_size();
4502          params[1] = renderbuffer_manager()->max_renderbuffer_size();
4503        }
4504        return true;
4505      }
4506      return false;
4507    case GL_MAX_SAMPLES:
4508      *num_written = 1;
4509      if (params) {
4510        params[0] = renderbuffer_manager()->max_samples();
4511      }
4512      return true;
4513    case GL_MAX_RENDERBUFFER_SIZE:
4514      *num_written = 1;
4515      if (params) {
4516        params[0] = renderbuffer_manager()->max_renderbuffer_size();
4517      }
4518      return true;
4519    case GL_MAX_TEXTURE_SIZE:
4520      *num_written = 1;
4521      if (params) {
4522        params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4523      }
4524      return true;
4525    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4526      *num_written = 1;
4527      if (params) {
4528        params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4529      }
4530      return true;
4531    case GL_MAX_COLOR_ATTACHMENTS_EXT:
4532      *num_written = 1;
4533      if (params) {
4534        params[0] = group_->max_color_attachments();
4535      }
4536      return true;
4537    case GL_MAX_DRAW_BUFFERS_ARB:
4538      *num_written = 1;
4539      if (params) {
4540        params[0] = group_->max_draw_buffers();
4541      }
4542      return true;
4543    case GL_ALPHA_BITS:
4544      *num_written = 1;
4545      if (params) {
4546        GLint v = 0;
4547        glGetIntegerv(GL_ALPHA_BITS, &v);
4548        params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
4549      }
4550      return true;
4551    case GL_DEPTH_BITS:
4552      *num_written = 1;
4553      if (params) {
4554        GLint v = 0;
4555        glGetIntegerv(GL_DEPTH_BITS, &v);
4556        params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4557      }
4558      return true;
4559    case GL_STENCIL_BITS:
4560      *num_written = 1;
4561      if (params) {
4562        GLint v = 0;
4563        glGetIntegerv(GL_STENCIL_BITS, &v);
4564        params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4565      }
4566      return true;
4567    case GL_COMPRESSED_TEXTURE_FORMATS:
4568      *num_written = validators_->compressed_texture_format.GetValues().size();
4569      if (params) {
4570        for (GLint ii = 0; ii < *num_written; ++ii) {
4571          params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4572        }
4573      }
4574      return true;
4575    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4576      *num_written = 1;
4577      if (params) {
4578        *params = validators_->compressed_texture_format.GetValues().size();
4579      }
4580      return true;
4581    case GL_NUM_SHADER_BINARY_FORMATS:
4582      *num_written = 1;
4583      if (params) {
4584        *params = validators_->shader_binary_format.GetValues().size();
4585      }
4586      return true;
4587    case GL_SHADER_BINARY_FORMATS:
4588      *num_written = validators_->shader_binary_format.GetValues().size();
4589      if (params) {
4590        for (GLint ii = 0; ii <  *num_written; ++ii) {
4591          params[ii] = validators_->shader_binary_format.GetValues()[ii];
4592        }
4593      }
4594      return true;
4595    case GL_SHADER_COMPILER:
4596      *num_written = 1;
4597      if (params) {
4598        *params = GL_TRUE;
4599      }
4600      return true;
4601    case GL_ARRAY_BUFFER_BINDING:
4602      *num_written = 1;
4603      if (params) {
4604        if (state_.bound_array_buffer.get()) {
4605          GLuint client_id = 0;
4606          buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
4607                                        &client_id);
4608          *params = client_id;
4609        } else {
4610          *params = 0;
4611        }
4612      }
4613      return true;
4614    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4615      *num_written = 1;
4616      if (params) {
4617        if (state_.vertex_attrib_manager->element_array_buffer()) {
4618          GLuint client_id = 0;
4619          buffer_manager()->GetClientId(
4620              state_.vertex_attrib_manager->element_array_buffer()->
4621                  service_id(), &client_id);
4622          *params = client_id;
4623        } else {
4624          *params = 0;
4625        }
4626      }
4627      return true;
4628    case GL_FRAMEBUFFER_BINDING:
4629    // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
4630      *num_written = 1;
4631      if (params) {
4632        Framebuffer* framebuffer =
4633            GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4634        if (framebuffer) {
4635          GLuint client_id = 0;
4636          framebuffer_manager()->GetClientId(
4637              framebuffer->service_id(), &client_id);
4638          *params = client_id;
4639        } else {
4640          *params = 0;
4641        }
4642      }
4643      return true;
4644    case GL_READ_FRAMEBUFFER_BINDING_EXT:
4645      *num_written = 1;
4646      if (params) {
4647        Framebuffer* framebuffer =
4648            GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
4649        if (framebuffer) {
4650          GLuint client_id = 0;
4651          framebuffer_manager()->GetClientId(
4652              framebuffer->service_id(), &client_id);
4653          *params = client_id;
4654        } else {
4655          *params = 0;
4656        }
4657      }
4658      return true;
4659    case GL_RENDERBUFFER_BINDING:
4660      *num_written = 1;
4661      if (params) {
4662        Renderbuffer* renderbuffer =
4663            GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4664        if (renderbuffer) {
4665          *params = renderbuffer->client_id();
4666        } else {
4667          *params = 0;
4668        }
4669      }
4670      return true;
4671    case GL_CURRENT_PROGRAM:
4672      *num_written = 1;
4673      if (params) {
4674        if (state_.current_program.get()) {
4675          GLuint client_id = 0;
4676          program_manager()->GetClientId(
4677              state_.current_program->service_id(), &client_id);
4678          *params = client_id;
4679        } else {
4680          *params = 0;
4681        }
4682      }
4683      return true;
4684    case GL_VERTEX_ARRAY_BINDING_OES:
4685      *num_written = 1;
4686      if (params) {
4687        if (state_.vertex_attrib_manager.get() !=
4688            state_.default_vertex_attrib_manager.get()) {
4689          GLuint client_id = 0;
4690          vertex_array_manager_->GetClientId(
4691              state_.vertex_attrib_manager->service_id(), &client_id);
4692          *params = client_id;
4693        } else {
4694          *params = 0;
4695        }
4696      }
4697      return true;
4698    case GL_TEXTURE_BINDING_2D:
4699      *num_written = 1;
4700      if (params) {
4701        TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4702        if (unit.bound_texture_2d.get()) {
4703          *params = unit.bound_texture_2d->client_id();
4704        } else {
4705          *params = 0;
4706        }
4707      }
4708      return true;
4709    case GL_TEXTURE_BINDING_CUBE_MAP:
4710      *num_written = 1;
4711      if (params) {
4712        TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4713        if (unit.bound_texture_cube_map.get()) {
4714          *params = unit.bound_texture_cube_map->client_id();
4715        } else {
4716          *params = 0;
4717        }
4718      }
4719      return true;
4720    case GL_TEXTURE_BINDING_EXTERNAL_OES:
4721      *num_written = 1;
4722      if (params) {
4723        TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4724        if (unit.bound_texture_external_oes.get()) {
4725          *params = unit.bound_texture_external_oes->client_id();
4726        } else {
4727          *params = 0;
4728        }
4729      }
4730      return true;
4731    case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4732      *num_written = 1;
4733      if (params) {
4734        TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4735        if (unit.bound_texture_rectangle_arb.get()) {
4736          *params = unit.bound_texture_rectangle_arb->client_id();
4737        } else {
4738          *params = 0;
4739        }
4740      }
4741      return true;
4742    case GL_UNPACK_FLIP_Y_CHROMIUM:
4743      *num_written = 1;
4744      if (params) {
4745        params[0] = unpack_flip_y_;
4746      }
4747      return true;
4748    case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4749      *num_written = 1;
4750      if (params) {
4751        params[0] = unpack_premultiply_alpha_;
4752      }
4753      return true;
4754    case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4755      *num_written = 1;
4756      if (params) {
4757        params[0] = unpack_unpremultiply_alpha_;
4758      }
4759      return true;
4760    case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4761      *num_written = 1;
4762      if (params) {
4763        params[0] = group_->bind_generates_resource() ? 1 : 0;
4764      }
4765      return true;
4766    default:
4767      if (pname >= GL_DRAW_BUFFER0_ARB &&
4768          pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4769        *num_written = 1;
4770        if (params) {
4771          Framebuffer* framebuffer =
4772              GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4773          if (framebuffer) {
4774            params[0] = framebuffer->GetDrawBuffer(pname);
4775          } else {  // backbuffer
4776            if (pname == GL_DRAW_BUFFER0_ARB)
4777              params[0] = group_->draw_buffer();
4778            else
4779              params[0] = GL_NONE;
4780          }
4781        }
4782        return true;
4783      }
4784      *num_written = util_.GLGetNumValuesReturned(pname);
4785      return false;
4786  }
4787}
4788
4789bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4790    GLenum pname, GLsizei* num_values) {
4791  if (state_.GetStateAsGLint(pname, NULL, num_values)) {
4792    return true;
4793  }
4794  return GetHelper(pname, NULL, num_values);
4795}
4796
4797GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4798  if (GL_MAX_SAMPLES == pname &&
4799      features().use_img_for_multisampled_render_to_texture) {
4800    return GL_MAX_SAMPLES_IMG;
4801  }
4802  return pname;
4803}
4804
4805void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4806  DCHECK(params);
4807  GLsizei num_written = 0;
4808  if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
4809    scoped_ptr<GLint[]> values(new GLint[num_written]);
4810    if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
4811      GetHelper(pname, values.get(), &num_written);
4812    }
4813    for (GLsizei ii = 0; ii < num_written; ++ii) {
4814      params[ii] = static_cast<GLboolean>(values[ii]);
4815    }
4816  } else {
4817    pname = AdjustGetPname(pname);
4818    glGetBooleanv(pname, params);
4819  }
4820}
4821
4822void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4823  DCHECK(params);
4824  GLsizei num_written = 0;
4825  if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
4826    if (GetHelper(pname, NULL, &num_written)) {
4827      scoped_ptr<GLint[]> values(new GLint[num_written]);
4828      GetHelper(pname, values.get(), &num_written);
4829      for (GLsizei ii = 0; ii < num_written; ++ii) {
4830        params[ii] = static_cast<GLfloat>(values[ii]);
4831      }
4832    } else {
4833      pname = AdjustGetPname(pname);
4834      glGetFloatv(pname, params);
4835    }
4836  }
4837}
4838
4839void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4840  DCHECK(params);
4841  GLsizei num_written;
4842  if (!state_.GetStateAsGLint(pname, params, &num_written) &&
4843      !GetHelper(pname, params, &num_written)) {
4844    pname = AdjustGetPname(pname);
4845    glGetIntegerv(pname, params);
4846  }
4847}
4848
4849void GLES2DecoderImpl::DoGetProgramiv(
4850    GLuint program_id, GLenum pname, GLint* params) {
4851  Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4852  if (!program) {
4853    return;
4854  }
4855  program->GetProgramiv(pname, params);
4856}
4857
4858void GLES2DecoderImpl::DoGetBufferParameteriv(
4859    GLenum target, GLenum pname, GLint* params) {
4860  // Just delegate it. Some validation is actually done before this.
4861  buffer_manager()->ValidateAndDoGetBufferParameteriv(
4862      &state_, target, pname, params);
4863}
4864
4865void GLES2DecoderImpl::DoBindAttribLocation(
4866    GLuint program_id, GLuint index, const char* name) {
4867  if (!StringIsValidForGLES(name)) {
4868    LOCAL_SET_GL_ERROR(
4869        GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
4870    return;
4871  }
4872  if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4873    LOCAL_SET_GL_ERROR(
4874        GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
4875    return;
4876  }
4877  if (index >= group_->max_vertex_attribs()) {
4878    LOCAL_SET_GL_ERROR(
4879        GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
4880    return;
4881  }
4882  Program* program = GetProgramInfoNotShader(
4883      program_id, "glBindAttribLocation");
4884  if (!program) {
4885    return;
4886  }
4887  program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4888  glBindAttribLocation(program->service_id(), index, name);
4889}
4890
4891error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4892    uint32 immediate_data_size,
4893    const void* cmd_data) {
4894  const gles2::cmds::BindAttribLocationBucket& c =
4895      *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
4896  GLuint program = static_cast<GLuint>(c.program);
4897  GLuint index = static_cast<GLuint>(c.index);
4898  Bucket* bucket = GetBucket(c.name_bucket_id);
4899  if (!bucket || bucket->size() == 0) {
4900    return error::kInvalidArguments;
4901  }
4902  std::string name_str;
4903  if (!bucket->GetAsString(&name_str)) {
4904    return error::kInvalidArguments;
4905  }
4906  DoBindAttribLocation(program, index, name_str.c_str());
4907  return error::kNoError;
4908}
4909
4910void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4911    GLuint program_id, GLint location, const char* name) {
4912  if (!StringIsValidForGLES(name)) {
4913    LOCAL_SET_GL_ERROR(
4914        GL_INVALID_VALUE,
4915        "glBindUniformLocationCHROMIUM", "Invalid character");
4916    return;
4917  }
4918  if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4919    LOCAL_SET_GL_ERROR(
4920        GL_INVALID_OPERATION,
4921        "glBindUniformLocationCHROMIUM", "reserved prefix");
4922    return;
4923  }
4924  if (location < 0 || static_cast<uint32>(location) >=
4925      (group_->max_fragment_uniform_vectors() +
4926       group_->max_vertex_uniform_vectors()) * 4) {
4927    LOCAL_SET_GL_ERROR(
4928        GL_INVALID_VALUE,
4929        "glBindUniformLocationCHROMIUM", "location out of range");
4930    return;
4931  }
4932  Program* program = GetProgramInfoNotShader(
4933      program_id, "glBindUniformLocationCHROMIUM");
4934  if (!program) {
4935    return;
4936  }
4937  if (!program->SetUniformLocationBinding(name, location)) {
4938    LOCAL_SET_GL_ERROR(
4939        GL_INVALID_VALUE,
4940        "glBindUniformLocationCHROMIUM", "location out of range");
4941  }
4942}
4943
4944error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4945    uint32 immediate_data_size,
4946    const void* cmd_data) {
4947  const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
4948      *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
4949          cmd_data);
4950  GLuint program = static_cast<GLuint>(c.program);
4951  GLint location = static_cast<GLint>(c.location);
4952  Bucket* bucket = GetBucket(c.name_bucket_id);
4953  if (!bucket || bucket->size() == 0) {
4954    return error::kInvalidArguments;
4955  }
4956  std::string name_str;
4957  if (!bucket->GetAsString(&name_str)) {
4958    return error::kInvalidArguments;
4959  }
4960  DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4961  return error::kNoError;
4962}
4963
4964error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
4965                                                  const void* cmd_data) {
4966  const gles2::cmds::DeleteShader& c =
4967      *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
4968  GLuint client_id = c.shader;
4969  if (client_id) {
4970    Shader* shader = GetShader(client_id);
4971    if (shader) {
4972      if (!shader->IsDeleted()) {
4973        glDeleteShader(shader->service_id());
4974        shader_manager()->MarkAsDeleted(shader);
4975      }
4976    } else {
4977      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
4978    }
4979  }
4980  return error::kNoError;
4981}
4982
4983error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
4984                                                   const void* cmd_data) {
4985  const gles2::cmds::DeleteProgram& c =
4986      *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
4987  GLuint client_id = c.program;
4988  if (client_id) {
4989    Program* program = GetProgram(client_id);
4990    if (program) {
4991      if (!program->IsDeleted()) {
4992        program_manager()->MarkAsDeleted(shader_manager(), program);
4993      }
4994    } else {
4995      LOCAL_SET_GL_ERROR(
4996          GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
4997    }
4998  }
4999  return error::kNoError;
5000}
5001
5002void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
5003    GLuint namespace_id, GLsizei n, const GLuint* ids) {
5004  IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
5005  for (GLsizei ii = 0; ii < n; ++ii) {
5006    id_allocator->FreeID(ids[ii]);
5007  }
5008}
5009
5010error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
5011    uint32 immediate_data_size,
5012    const void* cmd_data) {
5013  const gles2::cmds::DeleteSharedIdsCHROMIUM& c =
5014      *static_cast<const gles2::cmds::DeleteSharedIdsCHROMIUM*>(cmd_data);
5015  GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5016  GLsizei n = static_cast<GLsizei>(c.n);
5017  uint32 data_size;
5018  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5019    return error::kOutOfBounds;
5020  }
5021  const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
5022      c.ids_shm_id, c.ids_shm_offset, data_size);
5023  if (n < 0) {
5024    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
5025    return error::kNoError;
5026  }
5027  if (ids == NULL) {
5028    return error::kOutOfBounds;
5029  }
5030  DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
5031  return error::kNoError;
5032}
5033
5034void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
5035    GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
5036  IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
5037  if (id_offset == 0) {
5038    for (GLsizei ii = 0; ii < n; ++ii) {
5039      ids[ii] = id_allocator->AllocateID();
5040    }
5041  } else {
5042    for (GLsizei ii = 0; ii < n; ++ii) {
5043      ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
5044      id_offset = ids[ii] + 1;
5045    }
5046  }
5047}
5048
5049error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
5050    uint32 immediate_data_size,
5051    const void* cmd_data) {
5052  const gles2::cmds::GenSharedIdsCHROMIUM& c =
5053      *static_cast<const gles2::cmds::GenSharedIdsCHROMIUM*>(cmd_data);
5054  GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5055  GLuint id_offset = static_cast<GLuint>(c.id_offset);
5056  GLsizei n = static_cast<GLsizei>(c.n);
5057  uint32 data_size;
5058  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5059    return error::kOutOfBounds;
5060  }
5061  GLuint* ids = GetSharedMemoryAs<GLuint*>(
5062      c.ids_shm_id, c.ids_shm_offset, data_size);
5063  if (n < 0) {
5064    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
5065    return error::kNoError;
5066  }
5067  if (ids == NULL) {
5068    return error::kOutOfBounds;
5069  }
5070  DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
5071  return error::kNoError;
5072}
5073
5074void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
5075    GLuint namespace_id, GLsizei n, const GLuint* ids) {
5076  IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
5077  for (GLsizei ii = 0; ii < n; ++ii) {
5078    if (!id_allocator->MarkAsUsed(ids[ii])) {
5079      for (GLsizei jj = 0; jj < ii; ++jj) {
5080        id_allocator->FreeID(ids[jj]);
5081      }
5082      LOCAL_SET_GL_ERROR(
5083          GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
5084          "attempt to register id that already exists");
5085      return;
5086    }
5087  }
5088}
5089
5090error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
5091    uint32 immediate_data_size,
5092    const void* cmd_data) {
5093  const gles2::cmds::RegisterSharedIdsCHROMIUM& c =
5094      *static_cast<const gles2::cmds::RegisterSharedIdsCHROMIUM*>(cmd_data);
5095  GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5096  GLsizei n = static_cast<GLsizei>(c.n);
5097  uint32 data_size;
5098  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5099    return error::kOutOfBounds;
5100  }
5101  GLuint* ids = GetSharedMemoryAs<GLuint*>(
5102      c.ids_shm_id, c.ids_shm_offset, data_size);
5103  if (n < 0) {
5104    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
5105    return error::kNoError;
5106  }
5107  if (ids == NULL) {
5108    return error::kOutOfBounds;
5109  }
5110  DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
5111  return error::kNoError;
5112}
5113
5114error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
5115  DCHECK(!ShouldDeferDraws());
5116  if (CheckBoundFramebuffersValid("glClear")) {
5117    ApplyDirtyState();
5118    ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
5119    glClear(mask);
5120  }
5121  return error::kNoError;
5122}
5123
5124void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5125    GLenum target, GLenum attachment, GLenum renderbuffertarget,
5126    GLuint client_renderbuffer_id) {
5127  Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5128  if (!framebuffer) {
5129    LOCAL_SET_GL_ERROR(
5130        GL_INVALID_OPERATION,
5131        "glFramebufferRenderbuffer", "no framebuffer bound");
5132    return;
5133  }
5134  GLuint service_id = 0;
5135  Renderbuffer* renderbuffer = NULL;
5136  if (client_renderbuffer_id) {
5137    renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5138    if (!renderbuffer) {
5139      LOCAL_SET_GL_ERROR(
5140          GL_INVALID_OPERATION,
5141          "glFramebufferRenderbuffer", "unknown renderbuffer");
5142      return;
5143    }
5144    service_id = renderbuffer->service_id();
5145  }
5146  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
5147  glFramebufferRenderbufferEXT(
5148      target, attachment, renderbuffertarget, service_id);
5149  GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
5150  if (error == GL_NO_ERROR) {
5151    framebuffer->AttachRenderbuffer(attachment, renderbuffer);
5152  }
5153  if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
5154    framebuffer_state_.clear_state_dirty = true;
5155  }
5156  OnFboChanged();
5157}
5158
5159void GLES2DecoderImpl::DoDisable(GLenum cap) {
5160  if (SetCapabilityState(cap, false)) {
5161    glDisable(cap);
5162  }
5163}
5164
5165void GLES2DecoderImpl::DoEnable(GLenum cap) {
5166  if (SetCapabilityState(cap, true)) {
5167    glEnable(cap);
5168  }
5169}
5170
5171void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5172  state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5173  state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5174  glDepthRange(znear, zfar);
5175}
5176
5177void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
5178  state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5179  state_.sample_coverage_invert = (invert != 0);
5180  glSampleCoverage(state_.sample_coverage_value, invert);
5181}
5182
5183// Assumes framebuffer is complete.
5184void GLES2DecoderImpl::ClearUnclearedAttachments(
5185    GLenum target, Framebuffer* framebuffer) {
5186  if (target == GL_READ_FRAMEBUFFER_EXT) {
5187    // bind this to the DRAW point, clear then bind back to READ
5188    // TODO(gman): I don't think there is any guarantee that an FBO that
5189    //   is complete on the READ attachment will be complete as a DRAW
5190    //   attachment.
5191    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
5192    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
5193  }
5194  GLbitfield clear_bits = 0;
5195  if (framebuffer->HasUnclearedColorAttachments()) {
5196    glClearColor(
5197        0.0f, 0.0f, 0.0f,
5198        (GLES2Util::GetChannelsForFormat(
5199             framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5200                                                                       1.0f);
5201    state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5202    clear_bits |= GL_COLOR_BUFFER_BIT;
5203    if (feature_info_->feature_flags().ext_draw_buffers)
5204      framebuffer->PrepareDrawBuffersForClear();
5205  }
5206
5207  if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5208      framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
5209    glClearStencil(0);
5210    state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5211    state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
5212    clear_bits |= GL_STENCIL_BUFFER_BIT;
5213  }
5214
5215  if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5216      framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
5217    glClearDepth(1.0f);
5218    state_.SetDeviceDepthMask(GL_TRUE);
5219    clear_bits |= GL_DEPTH_BUFFER_BIT;
5220  }
5221
5222  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5223  glClear(clear_bits);
5224
5225  if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5226      feature_info_->feature_flags().ext_draw_buffers)
5227    framebuffer->RestoreDrawBuffersAfterClear();
5228
5229  framebuffer_manager()->MarkAttachmentsAsCleared(
5230      framebuffer, renderbuffer_manager(), texture_manager());
5231
5232  RestoreClearState();
5233
5234  if (target == GL_READ_FRAMEBUFFER_EXT) {
5235    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5236    Framebuffer* draw_framebuffer =
5237        GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5238    GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5239                                           GetBackbufferServiceId();
5240    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
5241  }
5242}
5243
5244void GLES2DecoderImpl::RestoreClearState() {
5245  framebuffer_state_.clear_state_dirty = true;
5246  glClearColor(
5247      state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5248      state_.color_clear_alpha);
5249  glClearStencil(state_.stencil_clear);
5250  glClearDepth(state_.depth_clear);
5251  if (state_.enable_flags.scissor_test) {
5252    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
5253  }
5254}
5255
5256GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
5257  Framebuffer* framebuffer =
5258      GetFramebufferInfoForTarget(target);
5259  if (!framebuffer) {
5260    return GL_FRAMEBUFFER_COMPLETE;
5261  }
5262  GLenum completeness = framebuffer->IsPossiblyComplete();
5263  if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5264    return completeness;
5265  }
5266  return framebuffer->GetStatus(texture_manager(), target);
5267}
5268
5269void GLES2DecoderImpl::DoFramebufferTexture2D(
5270    GLenum target, GLenum attachment, GLenum textarget,
5271    GLuint client_texture_id, GLint level) {
5272  DoFramebufferTexture2DCommon(
5273    "glFramebufferTexture2D", target, attachment,
5274    textarget, client_texture_id, level, 0);
5275}
5276
5277void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5278    GLenum target, GLenum attachment, GLenum textarget,
5279    GLuint client_texture_id, GLint level, GLsizei samples) {
5280  DoFramebufferTexture2DCommon(
5281    "glFramebufferTexture2DMultisample", target, attachment,
5282    textarget, client_texture_id, level, samples);
5283}
5284
5285void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5286    const char* name, GLenum target, GLenum attachment, GLenum textarget,
5287    GLuint client_texture_id, GLint level, GLsizei samples) {
5288  if (samples > renderbuffer_manager()->max_samples()) {
5289    LOCAL_SET_GL_ERROR(
5290        GL_INVALID_VALUE,
5291        "glFramebufferTexture2DMultisample", "samples too large");
5292    return;
5293  }
5294  Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5295  if (!framebuffer) {
5296    LOCAL_SET_GL_ERROR(
5297        GL_INVALID_OPERATION,
5298        name, "no framebuffer bound.");
5299    return;
5300  }
5301  GLuint service_id = 0;
5302  TextureRef* texture_ref = NULL;
5303  if (client_texture_id) {
5304    texture_ref = GetTexture(client_texture_id);
5305    if (!texture_ref) {
5306      LOCAL_SET_GL_ERROR(
5307          GL_INVALID_OPERATION,
5308          name, "unknown texture_ref");
5309      return;
5310    }
5311    service_id = texture_ref->service_id();
5312  }
5313
5314  if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
5315    LOCAL_SET_GL_ERROR(
5316        GL_INVALID_VALUE,
5317        name, "level out of range");
5318    return;
5319  }
5320
5321  if (texture_ref)
5322    DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5323
5324  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5325  if (0 == samples) {
5326    glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5327  } else {
5328    if (features().use_img_for_multisampled_render_to_texture) {
5329      glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5330          service_id, level, samples);
5331    } else {
5332      glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5333          service_id, level, samples);
5334    }
5335  }
5336  GLenum error = LOCAL_PEEK_GL_ERROR(name);
5337  if (error == GL_NO_ERROR) {
5338    framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5339         samples);
5340  }
5341  if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
5342    framebuffer_state_.clear_state_dirty = true;
5343  }
5344
5345  if (texture_ref)
5346    DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5347
5348  OnFboChanged();
5349}
5350
5351void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5352    GLenum target, GLenum attachment, GLenum pname, GLint* params) {
5353  Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5354  if (!framebuffer) {
5355    LOCAL_SET_GL_ERROR(
5356        GL_INVALID_OPERATION,
5357        "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
5358    return;
5359  }
5360  if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
5361    const Framebuffer::Attachment* attachment_object =
5362        framebuffer->GetAttachment(attachment);
5363    *params = attachment_object ? attachment_object->object_name() : 0;
5364  } else {
5365    if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5366        features().use_img_for_multisampled_render_to_texture) {
5367      pname = GL_TEXTURE_SAMPLES_IMG;
5368    }
5369    glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
5370  }
5371}
5372
5373void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5374    GLenum target, GLenum pname, GLint* params) {
5375  Renderbuffer* renderbuffer =
5376      GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5377  if (!renderbuffer) {
5378    LOCAL_SET_GL_ERROR(
5379        GL_INVALID_OPERATION,
5380        "glGetRenderbufferParameteriv", "no renderbuffer bound");
5381    return;
5382  }
5383
5384  EnsureRenderbufferBound();
5385  switch (pname) {
5386    case GL_RENDERBUFFER_INTERNAL_FORMAT:
5387      *params = renderbuffer->internal_format();
5388      break;
5389    case GL_RENDERBUFFER_WIDTH:
5390      *params = renderbuffer->width();
5391      break;
5392    case GL_RENDERBUFFER_HEIGHT:
5393      *params = renderbuffer->height();
5394      break;
5395    case GL_RENDERBUFFER_SAMPLES_EXT:
5396      if (features().use_img_for_multisampled_render_to_texture) {
5397        glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5398            params);
5399      } else {
5400        glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5401            params);
5402      }
5403    default:
5404      glGetRenderbufferParameterivEXT(target, pname, params);
5405      break;
5406  }
5407}
5408
5409void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
5410    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5411    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5412    GLbitfield mask, GLenum filter) {
5413  DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
5414
5415  if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
5416    return;
5417  }
5418
5419  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5420  ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
5421  BlitFramebufferHelper(
5422      srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5423  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5424                                  state_.enable_flags.scissor_test);
5425}
5426
5427void GLES2DecoderImpl::EnsureRenderbufferBound() {
5428  if (!state_.bound_renderbuffer_valid) {
5429    state_.bound_renderbuffer_valid = true;
5430    glBindRenderbufferEXT(GL_RENDERBUFFER,
5431                          state_.bound_renderbuffer.get()
5432                              ? state_.bound_renderbuffer->service_id()
5433                              : 0);
5434  }
5435}
5436
5437void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5438    const FeatureInfo* feature_info,
5439    GLenum target,
5440    GLsizei samples,
5441    GLenum internal_format,
5442    GLsizei width,
5443    GLsizei height) {
5444  // TODO(sievers): This could be resolved at the GL binding level, but the
5445  // binding process is currently a bit too 'brute force'.
5446  if (feature_info->feature_flags().is_angle) {
5447    glRenderbufferStorageMultisampleANGLE(
5448        target, samples, internal_format, width, height);
5449  } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5450    glRenderbufferStorageMultisample(
5451        target, samples, internal_format, width, height);
5452  } else {
5453    glRenderbufferStorageMultisampleEXT(
5454        target, samples, internal_format, width, height);
5455  }
5456}
5457
5458void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5459                                             GLint srcY0,
5460                                             GLint srcX1,
5461                                             GLint srcY1,
5462                                             GLint dstX0,
5463                                             GLint dstY0,
5464                                             GLint dstX1,
5465                                             GLint dstY1,
5466                                             GLbitfield mask,
5467                                             GLenum filter) {
5468  // TODO(sievers): This could be resolved at the GL binding level, but the
5469  // binding process is currently a bit too 'brute force'.
5470  if (feature_info_->feature_flags().is_angle) {
5471    glBlitFramebufferANGLE(
5472        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5473  } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5474    glBlitFramebuffer(
5475        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5476  } else {
5477    glBlitFramebufferEXT(
5478        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5479  }
5480}
5481
5482bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5483    GLsizei samples,
5484    GLenum internalformat,
5485    GLsizei width,
5486    GLsizei height) {
5487  if (samples > renderbuffer_manager()->max_samples()) {
5488    LOCAL_SET_GL_ERROR(
5489        GL_INVALID_VALUE,
5490        "glRenderbufferStorageMultisample", "samples too large");
5491    return false;
5492  }
5493
5494  if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5495      height > renderbuffer_manager()->max_renderbuffer_size()) {
5496    LOCAL_SET_GL_ERROR(
5497        GL_INVALID_VALUE,
5498        "glRenderbufferStorageMultisample", "dimensions too large");
5499    return false;
5500  }
5501
5502  uint32 estimated_size = 0;
5503  if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5504           width, height, samples, internalformat, &estimated_size)) {
5505    LOCAL_SET_GL_ERROR(
5506        GL_OUT_OF_MEMORY,
5507        "glRenderbufferStorageMultisample", "dimensions too large");
5508    return false;
5509  }
5510
5511  if (!EnsureGPUMemoryAvailable(estimated_size)) {
5512    LOCAL_SET_GL_ERROR(
5513        GL_OUT_OF_MEMORY,
5514        "glRenderbufferStorageMultisample", "out of memory");
5515    return false;
5516  }
5517
5518  return true;
5519}
5520
5521void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5522    GLenum target, GLsizei samples, GLenum internalformat,
5523    GLsizei width, GLsizei height) {
5524  Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5525  if (!renderbuffer) {
5526    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5527                       "glRenderbufferStorageMultisampleCHROMIUM",
5528                       "no renderbuffer bound");
5529    return;
5530  }
5531
5532  if (!ValidateRenderbufferStorageMultisample(
5533      samples, internalformat, width, height)) {
5534    return;
5535  }
5536
5537  EnsureRenderbufferBound();
5538  GLenum impl_format =
5539      renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5540          internalformat);
5541  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5542      "glRenderbufferStorageMultisampleCHROMIUM");
5543  RenderbufferStorageMultisampleHelper(
5544      feature_info_.get(), target, samples, impl_format, width, height);
5545  GLenum error =
5546      LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
5547  if (error == GL_NO_ERROR) {
5548
5549    if (workarounds().validate_multisample_buffer_allocation) {
5550      if (!VerifyMultisampleRenderbufferIntegrity(
5551          renderbuffer->service_id(), impl_format)) {
5552        LOCAL_SET_GL_ERROR(
5553            GL_OUT_OF_MEMORY,
5554            "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
5555        return;
5556      }
5557    }
5558
5559    // TODO(gman): If renderbuffers tracked which framebuffers they were
5560    // attached to we could just mark those framebuffers as not complete.
5561    framebuffer_manager()->IncFramebufferStateChangeCount();
5562    renderbuffer_manager()->SetInfo(
5563        renderbuffer, samples, internalformat, width, height);
5564  }
5565}
5566
5567// This is the handler for multisampled_render_to_texture extensions.
5568void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5569    GLenum target, GLsizei samples, GLenum internalformat,
5570    GLsizei width, GLsizei height) {
5571  Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5572  if (!renderbuffer) {
5573    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5574                       "glRenderbufferStorageMultisampleEXT",
5575                       "no renderbuffer bound");
5576    return;
5577  }
5578
5579  if (!ValidateRenderbufferStorageMultisample(
5580      samples, internalformat, width, height)) {
5581    return;
5582  }
5583
5584  EnsureRenderbufferBound();
5585  GLenum impl_format =
5586      renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5587          internalformat);
5588  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5589  if (features().use_img_for_multisampled_render_to_texture) {
5590    glRenderbufferStorageMultisampleIMG(
5591        target, samples, impl_format, width, height);
5592  } else {
5593    glRenderbufferStorageMultisampleEXT(
5594        target, samples, impl_format, width, height);
5595  }
5596  GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5597  if (error ==