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