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