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