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