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