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