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