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