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