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