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