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 <limits.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 
12 #include <algorithm>
13 #include <cmath>
14 #include <limits>
15 #include <list>
16 #include <map>
17 #include <memory>
18 #include <set>
19 #include <unordered_map>
20 #include <utility>
21 
22 #include "base/bind.h"
23 #include "base/bind_helpers.h"
24 #include "base/callback.h"
25 #include "base/callback_helpers.h"
26 #include "base/containers/flat_set.h"
27 #include "base/containers/queue.h"
28 #include "base/containers/span.h"
29 #include "base/debug/alias.h"
30 #include "base/debug/dump_without_crashing.h"
31 #include "base/hash/legacy_hash.h"
32 #include "base/logging.h"
33 #include "base/metrics/histogram_macros.h"
34 #include "base/numerics/ranges.h"
35 #include "base/numerics/safe_math.h"
36 #include "base/optional.h"
37 #include "base/stl_util.h"
38 #include "base/strings/string_number_conversions.h"
39 #include "base/strings/stringprintf.h"
40 #include "base/trace_event/trace_event.h"
41 #include "build/build_config.h"
42 #include "gpu/command_buffer/common/debug_marker_manager.h"
43 #include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
44 #include "gpu/command_buffer/common/gles2_cmd_format.h"
45 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
46 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
47 #include "gpu/command_buffer/common/mailbox.h"
48 #include "gpu/command_buffer/common/sync_token.h"
49 #include "gpu/command_buffer/service/buffer_manager.h"
50 #include "gpu/command_buffer/service/command_buffer_service.h"
51 #include "gpu/command_buffer/service/context_group.h"
52 #include "gpu/command_buffer/service/context_state.h"
53 #include "gpu/command_buffer/service/decoder_client.h"
54 #include "gpu/command_buffer/service/error_state.h"
55 #include "gpu/command_buffer/service/feature_info.h"
56 #include "gpu/command_buffer/service/framebuffer_manager.h"
57 #include "gpu/command_buffer/service/gl_stream_texture_image.h"
58 #include "gpu/command_buffer/service/gl_utils.h"
59 #include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
60 #include "gpu/command_buffer/service/gles2_cmd_copy_tex_image.h"
61 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
62 #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h"
63 #include "gpu/command_buffer/service/gles2_cmd_srgb_converter.h"
64 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
65 #include "gpu/command_buffer/service/gles2_query_manager.h"
66 #include "gpu/command_buffer/service/gpu_fence_manager.h"
67 #include "gpu/command_buffer/service/gpu_state_tracer.h"
68 #include "gpu/command_buffer/service/gpu_tracer.h"
69 #include "gpu/command_buffer/service/image_factory.h"
70 #include "gpu/command_buffer/service/image_manager.h"
71 #include "gpu/command_buffer/service/logger.h"
72 #include "gpu/command_buffer/service/mailbox_manager.h"
73 #include "gpu/command_buffer/service/memory_tracking.h"
74 #include "gpu/command_buffer/service/multi_draw_manager.h"
75 #include "gpu/command_buffer/service/program_manager.h"
76 #include "gpu/command_buffer/service/renderbuffer_manager.h"
77 #include "gpu/command_buffer/service/sampler_manager.h"
78 #include "gpu/command_buffer/service/service_discardable_manager.h"
79 #include "gpu/command_buffer/service/shader_manager.h"
80 #include "gpu/command_buffer/service/shader_translator.h"
81 #include "gpu/command_buffer/service/shared_image_factory.h"
82 #include "gpu/command_buffer/service/shared_image_representation.h"
83 #include "gpu/command_buffer/service/texture_manager.h"
84 #include "gpu/command_buffer/service/transform_feedback_manager.h"
85 #include "gpu/command_buffer/service/validating_abstract_texture_impl.h"
86 #include "gpu/command_buffer/service/vertex_array_manager.h"
87 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
88 #include "gpu/config/gpu_preferences.h"
89 #include "ui/gfx/buffer_types.h"
90 #include "ui/gfx/color_space.h"
91 #include "ui/gfx/geometry/point.h"
92 #include "ui/gfx/geometry/rect.h"
93 #include "ui/gfx/geometry/rect_conversions.h"
94 #include "ui/gfx/geometry/size.h"
95 #include "ui/gfx/gpu_fence.h"
96 #include "ui/gfx/gpu_memory_buffer.h"
97 #include "ui/gfx/transform.h"
98 #include "ui/gl/ca_renderer_layer_params.h"
99 #include "ui/gl/dc_renderer_layer_params.h"
100 #include "ui/gl/gl_bindings.h"
101 #include "ui/gl/gl_context.h"
102 #include "ui/gl/gl_enums.h"
103 #include "ui/gl/gl_fence.h"
104 #include "ui/gl/gl_gl_api_implementation.h"
105 #include "ui/gl/gl_image.h"
106 #include "ui/gl/gl_implementation.h"
107 #include "ui/gl/gl_surface.h"
108 #include "ui/gl/gl_version_info.h"
109 #include "ui/gl/gpu_preference.h"
110 #include "ui/gl/gpu_switching_manager.h"
111 #include "ui/gl/gpu_switching_observer.h"
112 #include "ui/gl/gpu_timing.h"
113 #include "ui/gl/init/create_gr_gl_interface.h"
114 #include "ui/gl/scoped_make_current.h"
115 
116 #if defined(OS_MACOSX)
117 #include <IOSurface/IOSurface.h>
118 // Note that this must be included after gl_bindings.h to avoid conflicts.
119 #include <OpenGL/CGLIOSurface.h>
120 #endif  // OS_MACOSX
121 
122 // Note: this undefs far and near so include this after other Windows headers.
123 #include "third_party/angle/src/image_util/loadimage.h"
124 
125 namespace gpu {
126 namespace gles2 {
127 
128 namespace {
129 
130 const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
131 const char kOESFboRenderMipmapExtension[] = "GL_OES_fbo_render_mipmap";
132 const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
133 const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
134 const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
135 const char kWEBGLMultiDrawExtension[] = "GL_WEBGL_multi_draw";
136 const char kWEBGLDrawInstancedBaseVertexBaseInstanceExtension[] =
137     "GL_WEBGL_draw_instanced_base_vertex_base_instance";
138 const char kWEBGLMultiDrawInstancedBaseVertexBaseInstanceExtension[] =
139     "GL_WEBGL_multi_draw_instanced_base_vertex_base_instance";
140 
141 template <typename MANAGER_TYPE, typename OBJECT_TYPE>
GetClientId(const MANAGER_TYPE * manager,const OBJECT_TYPE * object)142 GLuint GetClientId(const MANAGER_TYPE* manager, const OBJECT_TYPE* object) {
143   DCHECK(manager);
144   GLuint client_id = 0;
145   if (object) {
146     manager->GetClientId(object->service_id(), &client_id);
147   }
148   return client_id;
149 }
150 
151 template <typename OBJECT_TYPE>
GetServiceId(const OBJECT_TYPE * object)152 GLuint GetServiceId(const OBJECT_TYPE* object) {
153   return object ? object->service_id() : 0;
154 }
155 
156 struct Vec4f {
Vec4fgpu::gles2::__anon65f5645b0111::Vec4f157   explicit Vec4f(const Vec4& data) {
158     data.GetValues(v);
159   }
160 
161   GLfloat v[4];
162 };
163 
164 struct TexSubCoord3D {
TexSubCoord3Dgpu::gles2::__anon65f5645b0111::TexSubCoord3D165   TexSubCoord3D(int _xoffset, int _yoffset, int _zoffset,
166                 int _width, int _height, int _depth)
167       : xoffset(_xoffset),
168         yoffset(_yoffset),
169         zoffset(_zoffset),
170         width(_width),
171         height(_height),
172         depth(_depth) {}
173 
174   int xoffset;
175   int yoffset;
176   int zoffset;
177   int width;
178   int height;
179   int depth;
180 };
181 
182 // Check if all |ref| bits are set in |bits|.
AllBitsSet(GLbitfield bits,GLbitfield ref)183 bool AllBitsSet(GLbitfield bits, GLbitfield ref) {
184   DCHECK_NE(0u, ref);
185   return ((bits & ref) == ref);
186 }
187 
188 // Check if any of |ref| bits are set in |bits|.
AnyBitsSet(GLbitfield bits,GLbitfield ref)189 bool AnyBitsSet(GLbitfield bits, GLbitfield ref) {
190   DCHECK_NE(0u, ref);
191   return ((bits & ref) != 0);
192 }
193 
194 // Check if any bits are set in |bits| other than the bits in |ref|.
AnyOtherBitsSet(GLbitfield bits,GLbitfield ref)195 bool AnyOtherBitsSet(GLbitfield bits, GLbitfield ref) {
196   DCHECK_NE(0u, ref);
197   GLbitfield mask = ~ref;
198   return ((bits & mask) != 0);
199 }
200 
GLDebugMessageCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const GLvoid * user_param)201 void APIENTRY GLDebugMessageCallback(GLenum source,
202                                      GLenum type,
203                                      GLuint id,
204                                      GLenum severity,
205                                      GLsizei length,
206                                      const GLchar* message,
207                                      const GLvoid* user_param) {
208   Logger* error_logger = static_cast<Logger*>(const_cast<void*>(user_param));
209   LogGLDebugMessage(source, type, id, severity, length, message, error_logger);
210 }
211 
212 }  // namespace
213 
214 class GLES2DecoderImpl;
215 
216 // Local versions of the SET_GL_ERROR macros
217 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
218   ERRORSTATE_SET_GL_ERROR(error_state_.get(), error, function_name, msg)
219 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label)      \
220   ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state_.get(), function_name, \
221                                        static_cast<uint32_t>(value), label)
222 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
223   ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_.get(), function_name)
224 #define LOCAL_PEEK_GL_ERROR(function_name) \
225   ERRORSTATE_PEEK_GL_ERROR(error_state_.get(), function_name)
226 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
227   ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_.get(), function_name)
228 #define LOCAL_PERFORMANCE_WARNING(msg) \
229     PerformanceWarning(__FILE__, __LINE__, msg)
230 #define LOCAL_RENDER_WARNING(msg) \
231     RenderWarning(__FILE__, __LINE__, msg)
232 
233 // Check that certain assumptions the code makes are true. There are places in
234 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
235 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
236 // a few others) are 32bits. If they are not 32bits the code will have to change
237 // to call those GL functions with service side memory and then copy the results
238 // to shared memory, converting the sizes.
239 static_assert(sizeof(GLint) == sizeof(uint32_t),  // NOLINT
240               "GLint should be the same size as uint32_t");
241 static_assert(sizeof(GLsizei) == sizeof(uint32_t),  // NOLINT
242               "GLsizei should be the same size as uint32_t");
243 static_assert(sizeof(GLfloat) == sizeof(float),  // NOLINT
244               "GLfloat should be the same size as float");
245 
246 // TODO(kbr): the use of this anonymous namespace core dumps the
247 // linker on Mac OS X 10.6 when the symbol ordering file is used
248 // namespace {
249 
250 // Return true if a character belongs to the ASCII subset as defined in
251 // GLSL ES 1.0 spec section 3.1.
CharacterIsValidForGLES(unsigned char c)252 static bool CharacterIsValidForGLES(unsigned char c) {
253   // Printing characters are valid except " $ ` @ \ ' DEL.
254   if (c >= 32 && c <= 126 &&
255       c != '"' &&
256       c != '$' &&
257       c != '`' &&
258       c != '@' &&
259       c != '\\' &&
260       c != '\'') {
261     return true;
262   }
263   // Horizontal tab, line feed, vertical tab, form feed, carriage return
264   // are also valid.
265   if (c >= 9 && c <= 13) {
266     return true;
267   }
268 
269   return false;
270 }
271 
StringIsValidForGLES(const std::string & str)272 static bool StringIsValidForGLES(const std::string& str) {
273   return str.length() == 0 ||
274          std::find_if_not(str.begin(), str.end(), CharacterIsValidForGLES) ==
275              str.end();
276 }
277 
278 DisallowedFeatures::DisallowedFeatures() = default;
279 DisallowedFeatures::~DisallowedFeatures() = default;
280 DisallowedFeatures::DisallowedFeatures(const DisallowedFeatures&) = default;
281 
282 // This class prevents any GL errors that occur when it is in scope from
283 // being reported to the client.
284 class ScopedGLErrorSuppressor {
285  public:
286   explicit ScopedGLErrorSuppressor(
287       const char* function_name, ErrorState* error_state);
288   ~ScopedGLErrorSuppressor();
289  private:
290   const char* function_name_;
291   ErrorState* error_state_;
292   DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
293 };
294 
295 // Temporarily changes a decoder's bound texture and restore it when this
296 // object goes out of scope. Also temporarily switches to using active texture
297 // unit zero in case the client has changed that to something invalid.
298 class ScopedTextureBinder {
299  public:
300   explicit ScopedTextureBinder(ContextState* state,
301                                ErrorState* error_state,
302                                GLuint id,
303                                GLenum target);
304   ~ScopedTextureBinder();
305 
306  private:
307   ContextState* state_;
308   ErrorState* error_state_;
309   GLenum target_;
310   DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
311 };
312 
313 // Temporarily changes a decoder's bound render buffer and restore it when this
314 // object goes out of scope.
315 class ScopedRenderBufferBinder {
316  public:
317   explicit ScopedRenderBufferBinder(ContextState* state,
318                                     ErrorState* error_state,
319                                     GLuint id);
320   ~ScopedRenderBufferBinder();
321 
322  private:
323   ContextState* state_;
324   ErrorState* error_state_;
325   DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
326 };
327 
328 // Temporarily changes a decoder's bound frame buffer and restore it when this
329 // object goes out of scope.
330 class ScopedFramebufferBinder {
331  public:
332   explicit ScopedFramebufferBinder(GLES2DecoderImpl* decoder, GLuint id);
333   ~ScopedFramebufferBinder();
334 
335  private:
336   GLES2DecoderImpl* decoder_;
337   DISALLOW_COPY_AND_ASSIGN(ScopedFramebufferBinder);
338 };
339 
340 // Temporarily changes a decoder's bound frame buffer to a resolved version of
341 // the multisampled offscreen render buffer if that buffer is multisampled, and,
342 // if it is bound or enforce_internal_framebuffer is true. If internal is
343 // true, the resolved framebuffer is not visible to the parent.
344 class ScopedResolvedFramebufferBinder {
345  public:
346   explicit ScopedResolvedFramebufferBinder(GLES2DecoderImpl* decoder,
347                                            bool enforce_internal_framebuffer,
348                                            bool internal);
349   ~ScopedResolvedFramebufferBinder();
350 
351  private:
352   GLES2DecoderImpl* decoder_;
353   bool resolve_and_bind_;
354   DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFramebufferBinder);
355 };
356 
357 // Temporarily create and bind a single sample copy of the currently bound
358 // framebuffer using CopyTexImage2D. This is useful as a workaround for drivers
359 // that have broken implementations of ReadPixels on multisampled framebuffers.
360 // See http://crbug.com/890002
361 class ScopedFramebufferCopyBinder {
362  public:
363   explicit ScopedFramebufferCopyBinder(GLES2DecoderImpl* decoder,
364                                        GLint x = 0,
365                                        GLint y = 0,
366                                        GLint width = 0,
367                                        GLint height = 0);
368 
369   ~ScopedFramebufferCopyBinder();
370 
371  private:
372   GLES2DecoderImpl* decoder_;
373   std::unique_ptr<ScopedFramebufferBinder> framebuffer_binder_;
374   GLuint temp_texture_;
375   GLuint temp_framebuffer_;
376   DISALLOW_COPY_AND_ASSIGN(ScopedFramebufferCopyBinder);
377 };
378 
379 // Temporarily changes a decoder's PIXEL_UNPACK_BUFFER to 0 and set pixel unpack
380 // params to default, and restore them when this object goes out of scope.
381 class ScopedPixelUnpackState {
382  public:
383   explicit ScopedPixelUnpackState(ContextState* state);
384   ~ScopedPixelUnpackState();
385 
386  private:
387   ContextState* state_;
388   DISALLOW_COPY_AND_ASSIGN(ScopedPixelUnpackState);
389 };
390 
391 // Encapsulates an OpenGL texture.
392 class BackTexture {
393  public:
394   explicit BackTexture(GLES2DecoderImpl* decoder);
395   ~BackTexture();
396 
397   // Create a new render texture.
398   void Create();
399 
400   // Set the initial size and format of a render texture or resize it.
401   bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
402 
403   // Copy the contents of the currently bound frame buffer.
404   void Copy();
405 
406   // Destroy the render texture. This must be explicitly called before
407   // destroying this object.
408   void Destroy();
409 
410   // Invalidate the texture. This can be used when a context is lost and it is
411   // not possible to make it current in order to free the resource.
412   void Invalidate();
413 
414   // The bind point for the texture.
415   GLenum Target();
416 
texture_ref()417   scoped_refptr<TextureRef> texture_ref() { return texture_ref_; }
418 
id() const419   GLuint id() const {
420     return texture_ref_ ? texture_ref_->service_id() : 0;
421   }
422 
size() const423   gfx::Size size() const {
424     return size_;
425   }
426 
427   gl::GLApi* api() const;
428 
429  private:
430   // The texture must be bound to Target() before calling this method.
431   // Returns whether the operation was successful.
432   bool AllocateNativeGpuMemoryBuffer(const gfx::Size& size,
433                                      GLenum format,
434                                      bool zero);
435 
436   // The texture must be bound to Target() before calling this method.
437   void DestroyNativeGpuMemoryBuffer(bool have_context);
438 
439   MemoryTypeTracker memory_tracker_;
440   size_t bytes_allocated_;
441   gfx::Size size_;
442   GLES2DecoderImpl* decoder_;
443 
444   scoped_refptr<TextureRef> texture_ref_;
445 
446   // The image that backs the texture, if its backed by a native
447   // GpuMemoryBuffer.
448   scoped_refptr<gl::GLImage> image_;
449 
450   DISALLOW_COPY_AND_ASSIGN(BackTexture);
451 };
452 
453 // Encapsulates an OpenGL render buffer of any format.
454 class BackRenderbuffer {
455  public:
456   explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
457   ~BackRenderbuffer();
458 
459   // Create a new render buffer.
460   void Create();
461 
462   // Set the initial size and format of a render buffer or resize it.
463   bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
464 
465   // Destroy the render buffer. This must be explicitly called before destroying
466   // this object.
467   void Destroy();
468 
469   // Invalidate the render buffer. This can be used when a context is lost and
470   // it is not possible to make it current in order to free the resource.
471   void Invalidate();
472 
id() const473   GLuint id() const {
474     return id_;
475   }
476 
477   gl::GLApi* api() const;
478 
479  private:
480   GLES2DecoderImpl* decoder_;
481   MemoryTypeTracker memory_tracker_;
482   size_t bytes_allocated_;
483   GLuint id_;
484   DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
485 };
486 
487 // Encapsulates an OpenGL frame buffer.
488 class BackFramebuffer {
489  public:
490   explicit BackFramebuffer(GLES2DecoderImpl* decoder);
491   ~BackFramebuffer();
492 
493   // Create a new frame buffer.
494   void Create();
495 
496   // Attach a color render buffer to a frame buffer.
497   void AttachRenderTexture(BackTexture* texture);
498 
499   // Attach a render buffer to a frame buffer. Note that this unbinds any
500   // currently bound frame buffer.
501   void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
502 
503   // Destroy the frame buffer. This must be explicitly called before destroying
504   // this object.
505   void Destroy();
506 
507   // Invalidate the frame buffer. This can be used when a context is lost and it
508   // is not possible to make it current in order to free the resource.
509   void Invalidate();
510 
511   // See glCheckFramebufferStatusEXT.
512   GLenum CheckStatus();
513 
id() const514   GLuint id() const {
515     return id_;
516   }
517 
518   gl::GLApi* api() const;
519 
520  private:
521   GLES2DecoderImpl* decoder_;
522   GLuint id_;
523   DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
524 };
525 
526 struct FenceCallback {
FenceCallbackgpu::gles2::FenceCallback527   FenceCallback() : fence(gl::GLFence::Create()) { DCHECK(fence); }
528   FenceCallback(FenceCallback&&) = default;
529   FenceCallback& operator=(FenceCallback&&) = default;
530   std::vector<base::OnceClosure> callbacks;
531   std::unique_ptr<gl::GLFence> fence;
532 };
533 
534 // For ensuring that client-side glRenderbufferStorageMultisampleEXT
535 // calls go down the correct code path.
536 enum ForcedMultisampleMode {
537   kForceExtMultisampledRenderToTexture,
538   kDoNotForce
539 };
540 
541 // }  // anonymous namespace.
542 
543 // static
544 const unsigned int GLES2Decoder::kDefaultStencilMask =
545     static_cast<unsigned int>(-1);
546 
GetServiceTextureId(uint32_t client_texture_id,uint32_t * service_texture_id)547 bool GLES2Decoder::GetServiceTextureId(uint32_t client_texture_id,
548                                        uint32_t* service_texture_id) {
549   return false;
550 }
551 
GetAndClearBackbufferClearBitsForTest()552 uint32_t GLES2Decoder::GetAndClearBackbufferClearBitsForTest() {
553   return 0;
554 }
555 
GLES2Decoder(DecoderClient * client,CommandBufferServiceBase * command_buffer_service,Outputter * outputter)556 GLES2Decoder::GLES2Decoder(DecoderClient* client,
557                            CommandBufferServiceBase* command_buffer_service,
558                            Outputter* outputter)
559     : CommonDecoder(client, command_buffer_service), outputter_(outputter) {
560   DCHECK(outputter_);
561 }
562 
563 GLES2Decoder::~GLES2Decoder() = default;
564 
initialized() const565 bool GLES2Decoder::initialized() const {
566   return initialized_;
567 }
568 
GetTextureBase(uint32_t client_id)569 TextureBase* GLES2Decoder::GetTextureBase(uint32_t client_id) {
570   return nullptr;
571 }
572 
SetLevelInfo(uint32_t client_id,int level,unsigned internal_format,unsigned width,unsigned height,unsigned depth,unsigned format,unsigned type,const gfx::Rect & cleared_rect)573 void GLES2Decoder::SetLevelInfo(uint32_t client_id,
574                                 int level,
575                                 unsigned internal_format,
576                                 unsigned width,
577                                 unsigned height,
578                                 unsigned depth,
579                                 unsigned format,
580                                 unsigned type,
581                                 const gfx::Rect& cleared_rect) {}
582 
BeginDecoding()583 void GLES2Decoder::BeginDecoding() {}
584 
EndDecoding()585 void GLES2Decoder::EndDecoding() {}
586 
GetLogPrefix()587 base::StringPiece GLES2Decoder::GetLogPrefix() {
588   return GetLogger()->GetLogPrefix();
589 }
590 
SetLogCommands(bool log_commands)591 void GLES2Decoder::SetLogCommands(bool log_commands) {
592   log_commands_ = log_commands;
593 }
594 
outputter() const595 Outputter* GLES2Decoder::outputter() const {
596   return outputter_;
597 }
598 
GetRasterDecoderId() const599 int GLES2Decoder::GetRasterDecoderId() const {
600   NOTREACHED();
601   return -1;
602 }
603 
604 // This class implements GLES2Decoder so we don't have to expose all the GLES2
605 // cmd stuff to outside this class.
606 class GLES2DecoderImpl : public GLES2Decoder,
607                          public ErrorStateClient,
608                          public ui::GpuSwitchingObserver {
609  public:
610   GLES2DecoderImpl(DecoderClient* client,
611                    CommandBufferServiceBase* command_buffer_service,
612                    Outputter* outputter,
613                    ContextGroup* group);
614   ~GLES2DecoderImpl() override;
615 
616   error::Error DoCommands(unsigned int num_commands,
617                           const volatile void* buffer,
618                           int num_entries,
619                           int* entries_processed) override;
620 
621   template <bool DebugImpl>
622   error::Error DoCommandsImpl(unsigned int num_commands,
623                               const volatile void* buffer,
624                               int num_entries,
625                               int* entries_processed);
626 
627   // Overridden from GLES2Decoder.
628   base::WeakPtr<DecoderContext> AsWeakPtr() override;
629   gpu::ContextResult Initialize(
630       const scoped_refptr<gl::GLSurface>& surface,
631       const scoped_refptr<gl::GLContext>& context,
632       bool offscreen,
633       const DisallowedFeatures& disallowed_features,
634       const ContextCreationAttribs& attrib_helper) override;
635   void Destroy(bool have_context) override;
636   void SetSurface(const scoped_refptr<gl::GLSurface>& surface) override;
637   void ReleaseSurface() override;
638   void TakeFrontBuffer(const Mailbox& mailbox) override;
639   void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
640   bool ResizeOffscreenFramebuffer(const gfx::Size& size) override;
641   bool MakeCurrent() override;
api() const642   gl::GLApi* api() const { return state_.api(); }
GetGLES2Util()643   GLES2Util* GetGLES2Util() override { return &util_; }
GetGLContext()644   gl::GLContext* GetGLContext() override { return context_.get(); }
GetGLSurface()645   gl::GLSurface* GetGLSurface() override { return surface_.get(); }
GetContextGroup()646   ContextGroup* GetContextGroup() override { return group_.get(); }
GetFeatureInfo() const647   const FeatureInfo* GetFeatureInfo() const override {
648     return feature_info_.get();
649   }
650   Capabilities GetCapabilities() override;
651   void RestoreState(const ContextState* prev_state) override;
652 
RestoreActiveTexture() const653   void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
RestoreAllTextureUnitAndSamplerBindings(const ContextState * prev_state) const654   void RestoreAllTextureUnitAndSamplerBindings(
655       const ContextState* prev_state) const override {
656     state_.RestoreAllTextureUnitAndSamplerBindings(prev_state);
657   }
RestoreActiveTextureUnitBinding(unsigned int target) const658   void RestoreActiveTextureUnitBinding(unsigned int target) const override {
659     state_.RestoreActiveTextureUnitBinding(target);
660   }
RestoreBufferBindings() const661   void RestoreBufferBindings() const override {
662     state_.RestoreBufferBindings();
663   }
RestoreGlobalState() const664   void RestoreGlobalState() const override {
665     state_.RestoreGlobalState(nullptr);
666   }
RestoreProgramBindings() const667   void RestoreProgramBindings() const override {
668     state_.RestoreProgramSettings(nullptr, false);
669   }
RestoreTextureUnitBindings(unsigned unit) const670   void RestoreTextureUnitBindings(unsigned unit) const override {
671     state_.RestoreTextureUnitBindings(unit, nullptr);
672   }
RestoreVertexAttribArray(unsigned index)673   void RestoreVertexAttribArray(unsigned index) override {
674     RestoreStateForAttrib(index, true);
675   }
676   void RestoreBufferBinding(unsigned int target) override;
677   void RestoreFramebufferBindings() const override;
678   void RestoreRenderbufferBindings() override;
679   void RestoreTextureState(unsigned service_id) override;
680 
681   void ClearDeviceWindowRectangles() const;
682   void RestoreDeviceWindowRectangles() const override;
683 
684   void ClearAllAttributes() const override;
685   void RestoreAllAttributes() const override;
686 
GetQueryManager()687   QueryManager* GetQueryManager() override { return query_manager_.get(); }
688   void SetQueryCallback(unsigned int query_client_id,
689                         base::OnceClosure callback) override;
690 
GetGpuFenceManager()691   GpuFenceManager* GetGpuFenceManager() override {
692     return gpu_fence_manager_.get();
693   }
GetFramebufferManager()694   FramebufferManager* GetFramebufferManager() override {
695     return framebuffer_manager_.get();
696   }
GetTransformFeedbackManager()697   TransformFeedbackManager* GetTransformFeedbackManager() override {
698     return transform_feedback_manager_.get();
699   }
GetVertexArrayManager()700   VertexArrayManager* GetVertexArrayManager() override {
701     return vertex_array_manager_.get();
702   }
GetImageManagerForTest()703   ImageManager* GetImageManagerForTest() override {
704     return group_->image_manager();
705   }
706 
707   bool HasPendingQueries() const override;
708   void ProcessPendingQueries(bool did_finish) override;
709 
710   bool HasMoreIdleWork() const override;
711   void PerformIdleWork() override;
712 
713   bool HasPollingWork() const override;
714   void PerformPollingWork() override;
715 
716   void WaitForReadPixels(base::OnceClosure callback) override;
717 
718   Logger* GetLogger() override;
719 
720   void BeginDecoding() override;
721   void EndDecoding() override;
722 
723   ErrorState* GetErrorState() override;
GetContextState()724   const ContextState* GetContextState() override { return &state_; }
725   std::unique_ptr<AbstractTexture> CreateAbstractTexture(GLenum target,
726                                                          GLenum internal_format,
727                                                          GLsizei width,
728                                                          GLsizei height,
729                                                          GLsizei depth,
730                                                          GLint border,
731                                                          GLenum format,
732                                                          GLenum type) override;
733 
734   scoped_refptr<ShaderTranslatorInterface> GetTranslator(GLenum type) override;
735   scoped_refptr<ShaderTranslatorInterface> GetOrCreateTranslator(GLenum type);
736 
737   void SetIgnoreCachedStateForTest(bool ignore) override;
738   void SetForceShaderNameHashingForTest(bool force) override;
739   uint32_t GetAndClearBackbufferClearBitsForTest() override;
740   void ProcessFinishedAsyncTransfers();
741 
742   bool GetServiceTextureId(uint32_t client_texture_id,
743                            uint32_t* service_texture_id) override;
744   TextureBase* GetTextureBase(uint32_t client_id) override;
745   void SetLevelInfo(uint32_t client_id,
746                     int level,
747                     unsigned internal_format,
748                     unsigned width,
749                     unsigned height,
750                     unsigned depth,
751                     unsigned format,
752                     unsigned type,
753                     const gfx::Rect& cleared_rect) override;
754 
755   // Implements GpuSwitchingObserver.
756   void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
757 
758   // Restores the current state to the user's settings.
759   void RestoreCurrentFramebufferBindings();
760 
761   // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
762   void ApplyDirtyState();
763 
764   // These check the state of the currently bound framebuffer or the
765   // backbuffer if no framebuffer is bound.
766   // Check with all attached and enabled color attachments.
767   bool BoundFramebufferAllowsChangesToAlphaChannel();
768   bool BoundFramebufferHasDepthAttachment();
769   bool BoundFramebufferHasStencilAttachment();
770 
771   // Overriden from ErrorStateClient.
772   void OnContextLostError() override;
773   void OnOutOfMemoryError() override;
774 
775   // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
776   void EnsureRenderbufferBound();
777 
778   // Helpers to facilitate calling into compatible extensions.
779   void RenderbufferStorageMultisampleWithWorkaround(GLenum target,
780                                                     GLsizei samples,
781                                                     GLenum internal_format,
782                                                     GLsizei width,
783                                                     GLsizei height,
784                                                     ForcedMultisampleMode mode);
785   void RenderbufferStorageMultisampleHelper(GLenum target,
786                                             GLsizei samples,
787                                             GLenum internal_format,
788                                             GLsizei width,
789                                             GLsizei height,
790                                             ForcedMultisampleMode mode);
791   void RenderbufferStorageMultisampleHelperAMD(GLenum target,
792                                                GLsizei samples,
793                                                GLsizei storageSamples,
794                                                GLenum internal_format,
795                                                GLsizei width,
796                                                GLsizei height,
797                                                ForcedMultisampleMode mode);
798   bool RegenerateRenderbufferIfNeeded(Renderbuffer* renderbuffer);
799 
SetCopyTextureResourceManagerForTest(CopyTextureCHROMIUMResourceManager * copy_texture_resource_manager)800   void SetCopyTextureResourceManagerForTest(
801       CopyTextureCHROMIUMResourceManager* copy_texture_resource_manager)
802       override {
803     copy_texture_chromium_.reset(copy_texture_resource_manager);
804   }
805 
SetCopyTexImageBlitterForTest(CopyTexImageResourceManager * copy_tex_image_blit)806   void SetCopyTexImageBlitterForTest(
807       CopyTexImageResourceManager* copy_tex_image_blit) override {
808     copy_tex_image_blit_.reset(copy_tex_image_blit);
809   }
810 
811   // ServiceFontManager::Client implementation.
812   scoped_refptr<gpu::Buffer> GetShmBuffer(uint32_t shm_id);
813 
814  private:
815   friend class ScopedFramebufferBinder;
816   friend class ScopedResolvedFramebufferBinder;
817   friend class ScopedFramebufferCopyBinder;
818   friend class BackFramebuffer;
819   friend class BackRenderbuffer;
820   friend class BackTexture;
821 
822   enum FramebufferOperation {
823     kFramebufferDiscard,
824     kFramebufferInvalidate,
825     kFramebufferInvalidateSub
826   };
827 
828   enum class BindIndexedBufferFunctionType {
829     kBindBufferBase,
830     kBindBufferRange
831   };
832 
833   // Helper class to ensure that GLES2DecoderImpl::Destroy() is always called
834   // unless we specifically call OnSuccess().
835   class DestroyOnFailure {
836    public:
DestroyOnFailure(GLES2DecoderImpl * decoder)837     DestroyOnFailure(GLES2DecoderImpl* decoder) : decoder_(decoder) {}
~DestroyOnFailure()838     ~DestroyOnFailure() {
839       if (!success_)
840         decoder_->Destroy(has_context_);
841     }
842 
OnSuccess()843     void OnSuccess() { success_ = true; }
LoseContext()844     void LoseContext() { has_context_ = false; }
845 
846    private:
847     GLES2DecoderImpl* decoder_ = nullptr;
848     bool success_ = false;
849     bool has_context_ = true;
850   };
851 
852   const char* GetCommandName(unsigned int command_id) const;
853 
854   // Initialize or re-initialize the shader translator.
855   bool InitializeShaderTranslator();
856   void DestroyShaderTranslator();
857 
858   GLint ComputeMaxSamples();
859   void UpdateCapabilities();
860 
861   // Helpers for the glGen and glDelete functions.
862   bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
863   void DeleteTexturesHelper(GLsizei n, const volatile GLuint* client_ids);
864   bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
865   void DeleteBuffersHelper(GLsizei n, const volatile GLuint* client_ids);
866   bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
867   void DeleteFramebuffersHelper(GLsizei n, const volatile GLuint* client_ids);
868   bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
869   void DeleteRenderbuffersHelper(GLsizei n, const volatile GLuint* client_ids);
870   bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
871   void DeleteQueriesEXTHelper(GLsizei n, const volatile GLuint* client_ids);
872   bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
873   void DeleteVertexArraysOESHelper(GLsizei n,
874                                    const volatile GLuint* client_ids);
875   bool GenSamplersHelper(GLsizei n, const GLuint* client_ids);
876   void DeleteSamplersHelper(GLsizei n, const volatile GLuint* client_ids);
877   bool GenTransformFeedbacksHelper(GLsizei n, const GLuint* client_ids);
878   void DeleteTransformFeedbacksHelper(GLsizei n,
879                                       const volatile GLuint* client_ids);
880   void DeleteSyncHelper(GLuint sync);
881 
882   bool UnmapBufferHelper(Buffer* buffer, GLenum target);
883 
884   // Workarounds
885   void OnFboChanged() const;
886   void OnUseFramebuffer() const;
887   void UpdateFramebufferSRGB(Framebuffer* framebuffer);
888 
889   // TODO(gman): Cache these pointers?
buffer_manager()890   BufferManager* buffer_manager() {
891     return group_->buffer_manager();
892   }
893 
renderbuffer_manager()894   RenderbufferManager* renderbuffer_manager() {
895     return group_->renderbuffer_manager();
896   }
897 
framebuffer_manager()898   FramebufferManager* framebuffer_manager() {
899     return framebuffer_manager_.get();
900   }
901 
program_manager()902   ProgramManager* program_manager() {
903     return group_->program_manager();
904   }
905 
sampler_manager()906   SamplerManager* sampler_manager() {
907     return group_->sampler_manager();
908   }
909 
shader_manager()910   ShaderManager* shader_manager() {
911     return group_->shader_manager();
912   }
913 
shader_translator_cache()914   ShaderTranslatorCache* shader_translator_cache() {
915     return group_->shader_translator_cache();
916   }
917 
texture_manager() const918   const TextureManager* texture_manager() const {
919     return group_->texture_manager();
920   }
921 
texture_manager()922   TextureManager* texture_manager() {
923     return group_->texture_manager();
924   }
925 
mailbox_manager()926   MailboxManager* mailbox_manager() {
927     return group_->mailbox_manager();
928   }
929 
image_manager()930   ImageManager* image_manager() { return group_->image_manager(); }
931 
vertex_array_manager()932   VertexArrayManager* vertex_array_manager() {
933     return vertex_array_manager_.get();
934   }
935 
memory_tracker()936   MemoryTracker* memory_tracker() {
937     return group_->memory_tracker();
938   }
939 
gl_version_info()940   const gl::GLVersionInfo& gl_version_info() {
941     return feature_info_->gl_version_info();
942   }
943 
IsOffscreenBufferMultisampled() const944   bool IsOffscreenBufferMultisampled() const {
945     return offscreen_target_samples_ > 0;
946   }
947 
948   // Creates a Texture for the given texture.
CreateTexture(GLuint client_id,GLuint service_id)949   TextureRef* CreateTexture(
950       GLuint client_id, GLuint service_id) {
951     return texture_manager()->CreateTexture(client_id, service_id);
952   }
953 
954   // Gets the texture info for the given texture. Returns nullptr if none
955   // exists.
GetTexture(GLuint client_id) const956   TextureRef* GetTexture(GLuint client_id) const {
957     return texture_manager()->GetTexture(client_id);
958   }
959 
960   // Deletes the texture info for the given texture.
RemoveTexture(GLuint client_id)961   void RemoveTexture(GLuint client_id) {
962     texture_manager()->RemoveTexture(client_id);
963   }
964 
965   // Creates a Sampler for the given sampler.
CreateSampler(GLuint client_id,GLuint service_id)966   Sampler* CreateSampler(
967       GLuint client_id, GLuint service_id) {
968     return sampler_manager()->CreateSampler(client_id, service_id);
969   }
970 
971   // Gets the sampler info for the given sampler. Returns nullptr if none
972   // exists.
GetSampler(GLuint client_id)973   Sampler* GetSampler(GLuint client_id) {
974     return sampler_manager()->GetSampler(client_id);
975   }
976 
977   // Deletes the sampler info for the given sampler.
RemoveSampler(GLuint client_id)978   void RemoveSampler(GLuint client_id) {
979     sampler_manager()->RemoveSampler(client_id);
980   }
981 
982   // Creates a TransformFeedback for the given transformfeedback.
CreateTransformFeedback(GLuint client_id,GLuint service_id)983   TransformFeedback* CreateTransformFeedback(
984       GLuint client_id, GLuint service_id) {
985     return transform_feedback_manager_->CreateTransformFeedback(
986         client_id, service_id);
987   }
988 
989   // Gets the TransformFeedback info for the given transformfeedback.
990   // Returns nullptr if none exists.
GetTransformFeedback(GLuint client_id)991   TransformFeedback* GetTransformFeedback(GLuint client_id) {
992     return transform_feedback_manager_->GetTransformFeedback(client_id);
993   }
994 
995   // Deletes the TransformFeedback info for the given transformfeedback.
RemoveTransformFeedback(GLuint client_id)996   void RemoveTransformFeedback(GLuint client_id) {
997     transform_feedback_manager_->RemoveTransformFeedback(client_id);
998   }
999 
1000   // Get the size (in pixels) of the currently bound frame buffer (either FBO
1001   // or regular back buffer).
1002   gfx::Size GetBoundReadFramebufferSize();
1003   gfx::Size GetBoundDrawFramebufferSize();
1004 
1005   // Get the service side ID for the bound read framebuffer.
1006   // If it's back buffer, 0 is returned.
1007   GLuint GetBoundReadFramebufferServiceId();
1008 
1009   // Get the service side ID for the bound draw framebuffer.
1010   // If it's back buffer, 0 is returned.
1011   GLuint GetBoundDrawFramebufferServiceId() const;
1012 
1013   // Get the format/type of the currently bound frame buffer (either FBO or
1014   // regular back buffer).
1015   // If the color image is a renderbuffer, returns 0 for type.
1016   GLenum GetBoundReadFramebufferTextureType();
1017   GLenum GetBoundReadFramebufferInternalFormat();
1018 
1019   // Get the i-th draw buffer's internal format/type from the bound framebuffer.
1020   // If no framebuffer is bound, or no image is attached, or the DrawBuffers
1021   // setting for that image is GL_NONE, return 0.
1022   GLenum GetBoundColorDrawBufferType(GLint drawbuffer_i);
1023   GLenum GetBoundColorDrawBufferInternalFormat(GLint drawbuffer_i);
1024 
1025   GLsizei GetBoundFramebufferSamples(GLenum target);
1026 
1027   // Return 0 if no depth attachment.
1028   GLenum GetBoundFramebufferDepthFormat(GLenum target);
1029   // Return 0 if no stencil attachment.
1030   GLenum GetBoundFramebufferStencilFormat(GLenum target);
1031 
GetBoundFramebufferDrawOffset() const1032   gfx::Vector2d GetBoundFramebufferDrawOffset() const {
1033     if (GetBoundDrawFramebuffer() || offscreen_target_frame_buffer_.get())
1034       return gfx::Vector2d();
1035     return surface_->GetDrawOffset();
1036   }
1037 
1038   void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i);
1039 
1040   // Wrapper for CompressedTexImage{2|3}D commands.
1041   error::Error DoCompressedTexImage(
1042       GLenum target,
1043       GLint level,
1044       GLenum internal_format,
1045       GLsizei width,
1046       GLsizei height,
1047       GLsizei depth,
1048       GLint border,
1049       GLsizei image_size,
1050       const void* data,
1051       ContextState::Dimension dimension);
1052 
1053   // Wrapper for CompressedTexSubImage{2|3}D.
1054   error::Error DoCompressedTexSubImage(
1055       GLenum target,
1056       GLint level,
1057       GLint xoffset,
1058       GLint yoffset,
1059       GLint zoffset,
1060       GLsizei width,
1061       GLsizei height,
1062       GLsizei depth,
1063       GLenum format,
1064       GLsizei imageSize,
1065       const void* data,
1066       ContextState::Dimension dimension);
1067 
1068   // Validate if |format| is valid for CopyTex{Sub}Image functions.
1069   // If not, generate a GL error and return false.
1070   bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format,
1071                              GLenum read_format, GLenum read_type);
1072 
1073   // Wrapper for CopyTexImage2D.
1074   void DoCopyTexImage2D(
1075       GLenum target,
1076       GLint level,
1077       GLenum internal_format,
1078       GLint x,
1079       GLint y,
1080       GLsizei width,
1081       GLsizei height,
1082       GLint border);
1083 
1084   // Wrapper for SwapBuffers.
1085   void DoSwapBuffers(uint64_t swap_id, GLbitfield flags);
1086 
1087   // Wrapper for SwapBuffersWithBoundsCHROMIUM.
1088   void DoSwapBuffersWithBoundsCHROMIUM(uint64_t swap_id,
1089                                        GLsizei count,
1090                                        const volatile GLint* rects,
1091                                        GLbitfield flags);
1092 
1093   // Callback for async SwapBuffers.
1094   void FinishAsyncSwapBuffers(uint64_t swap_id,
1095                               gfx::SwapResult result,
1096                               std::unique_ptr<gfx::GpuFence>);
1097   void FinishSwapBuffers(gfx::SwapResult result);
1098 
1099   void DoCommitOverlayPlanes(uint64_t swap_id, GLbitfield flags);
1100 
1101   // Wrapper for CopyTexSubImage2D.
1102   void DoCopyTexSubImage2D(
1103       GLenum target,
1104       GLint level,
1105       GLint xoffset,
1106       GLint yoffset,
1107       GLint x,
1108       GLint y,
1109       GLsizei width,
1110       GLsizei height);
1111 
1112   // Wrapper for CopyTexSubImage3D.
1113   void DoCopyTexSubImage3D(
1114       GLenum target,
1115       GLint level,
1116       GLint xoffset,
1117       GLint yoffset,
1118       GLint zoffset,
1119       GLint x,
1120       GLint y,
1121       GLsizei width,
1122       GLsizei height);
1123 
1124   // Wrapper for glCopyBufferSubData.
1125   void DoCopyBufferSubData(GLenum readtarget,
1126                            GLenum writetarget,
1127                            GLintptr readoffset,
1128                            GLintptr writeoffset,
1129                            GLsizeiptr size);
1130 
1131   void DoCopyTextureCHROMIUM(GLuint source_id,
1132                              GLint source_level,
1133                              GLenum dest_target,
1134                              GLuint dest_id,
1135                              GLint dest_level,
1136                              GLenum internal_format,
1137                              GLenum dest_type,
1138                              GLboolean unpack_flip_y,
1139                              GLboolean unpack_premultiply_alpha,
1140                              GLboolean unpack_unmultiply_alpha);
1141 
1142   void DoCopySubTextureCHROMIUM(GLuint source_id,
1143                                 GLint source_level,
1144                                 GLenum dest_target,
1145                                 GLuint dest_id,
1146                                 GLint dest_level,
1147                                 GLint xoffset,
1148                                 GLint yoffset,
1149                                 GLint x,
1150                                 GLint y,
1151                                 GLsizei width,
1152                                 GLsizei height,
1153                                 GLboolean unpack_flip_y,
1154                                 GLboolean unpack_premultiply_alpha,
1155                                 GLboolean unpack_unmultiply_alpha);
1156 
1157   // Helper for DoTexStorage2DEXT and DoTexStorage3D.
1158   void TexStorageImpl(GLenum target,
1159                       GLsizei levels,
1160                       GLenum internal_format,
1161                       GLsizei width,
1162                       GLsizei height,
1163                       GLsizei depth,
1164                       ContextState::Dimension dimension,
1165                       const char* function_name);
1166 
1167   // Wrapper for TexStorage2DEXT.
1168   void DoTexStorage2DEXT(GLenum target,
1169                          GLsizei levels,
1170                          GLenum internal_format,
1171                          GLsizei width,
1172                          GLsizei height);
1173 
1174   // Wrapper for TexStorage3D.
1175   void DoTexStorage3D(GLenum target,
1176                       GLsizei levels,
1177                       GLenum internal_format,
1178                       GLsizei width,
1179                       GLsizei height,
1180                       GLsizei depth);
1181 
1182   void DoTexStorage2DImageCHROMIUM(GLenum target,
1183                                    GLenum internal_format,
1184                                    GLenum buffer_usage,
1185                                    GLsizei width,
1186                                    GLsizei height);
1187 
1188   void DoProduceTextureDirectCHROMIUM(GLuint texture,
1189                                       const volatile GLbyte* key);
1190 
1191   void DoCreateAndConsumeTextureINTERNAL(GLuint client_id,
1192                                          const volatile GLbyte* key);
1193   void DoCreateAndTexStorage2DSharedImageINTERNAL(
1194       GLuint client_id,
1195       GLenum internal_format,
1196       const volatile GLbyte* mailbox);
1197   void DoBeginSharedImageAccessDirectCHROMIUM(GLuint client_id, GLenum mode);
1198   void DoEndSharedImageAccessDirectCHROMIUM(GLuint client_id);
1199 
1200   void DoBeginBatchReadAccessSharedImageCHROMIUM();
1201   void DoEndBatchReadAccessSharedImageCHROMIUM();
1202 
1203   void BindImage(uint32_t client_texture_id,
1204                  uint32_t texture_target,
1205                  gl::GLImage* image,
1206                  bool can_bind_to_sampler) override;
1207   void DoBindTexImage2DCHROMIUM(
1208       GLenum target,
1209       GLint image_id);
1210   void DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target,
1211                                                   GLenum internalformat,
1212                                                   GLint image_id);
1213   // Common implementation of DoBindTexImage2DCHROMIUM entry points.
1214   void BindTexImage2DCHROMIUMImpl(const char* function_name,
1215                                   GLenum target,
1216                                   GLenum internalformat,
1217                                   GLint image_id);
1218   void DoReleaseTexImage2DCHROMIUM(
1219       GLenum target,
1220       GLint image_id);
1221 
1222   void DoTraceEndCHROMIUM(void);
1223 
1224   void DoDrawBuffersEXT(GLsizei count, const volatile GLenum* bufs);
1225 
1226   void DoLoseContextCHROMIUM(GLenum current, GLenum other);
1227 
1228   void DoFlushDriverCachesCHROMIUM(void);
1229 
1230   void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count,
1231                                            const volatile GLuint* textures);
1232 
1233   void DoFlushMappedBufferRange(
1234       GLenum target, GLintptr offset, GLsizeiptr size);
1235 
1236   void DoScheduleDCLayerCHROMIUM(GLuint texture_0,
1237                                  GLuint texture_1,
1238                                  GLint z_order,
1239                                  GLint content_x,
1240                                  GLint content_y,
1241                                  GLint content_width,
1242                                  GLint content_height,
1243                                  GLint quad_x,
1244                                  GLint quad_y,
1245                                  GLint quad_width,
1246                                  GLint quad_height,
1247                                  GLfloat transform_c1r1,
1248                                  GLfloat transform_c2r1,
1249                                  GLfloat transform_c1r2,
1250                                  GLfloat transform_c2r2,
1251                                  GLfloat transform_tx,
1252                                  GLfloat transform_ty,
1253                                  GLboolean is_clipped,
1254                                  GLint clip_x,
1255                                  GLint clip_y,
1256                                  GLint clip_width,
1257                                  GLint clip_height,
1258                                  GLuint protected_video_type);
1259 
1260   // Creates a Program for the given program.
CreateProgram(GLuint client_id,GLuint service_id)1261   Program* CreateProgram(GLuint client_id, GLuint service_id) {
1262     return program_manager()->CreateProgram(client_id, service_id);
1263   }
1264 
1265   // Gets the program info for the given program. Returns nullptr if none
1266   // exists.
GetProgram(GLuint client_id)1267   Program* GetProgram(GLuint client_id) {
1268     return program_manager()->GetProgram(client_id);
1269   }
1270 
1271 #if defined(NDEBUG)
LogClientServiceMapping(const char *,GLuint,GLuint)1272   void LogClientServiceMapping(
1273       const char* /* function_name */,
1274       GLuint /* client_id */,
1275       GLuint /* service_id */) {
1276   }
1277   template<typename T>
LogClientServiceForInfo(T *,GLuint,const char *)1278   void LogClientServiceForInfo(
1279       T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1280   }
1281 #else
LogClientServiceMapping(const char * function_name,GLuint client_id,GLuint service_id)1282   void LogClientServiceMapping(
1283       const char* function_name, GLuint client_id, GLuint service_id) {
1284     if (service_logging_) {
1285       VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1286               << ": client_id = " << client_id
1287               << ", service_id = " << service_id;
1288     }
1289   }
1290   template<typename T>
LogClientServiceForInfo(T * info,GLuint client_id,const char * function_name)1291   void LogClientServiceForInfo(
1292       T* info, GLuint client_id, const char* function_name) {
1293     if (info) {
1294       LogClientServiceMapping(function_name, client_id, info->service_id());
1295     }
1296   }
1297 #endif
1298 
1299   // Gets the program info for the given program. If it's not a program
1300   // generates a GL error. Returns nullptr if not program.
GetProgramInfoNotShader(GLuint client_id,const char * function_name)1301   Program* GetProgramInfoNotShader(
1302       GLuint client_id, const char* function_name) {
1303     Program* program = GetProgram(client_id);
1304     if (!program) {
1305       if (GetShader(client_id)) {
1306         LOCAL_SET_GL_ERROR(
1307             GL_INVALID_OPERATION, function_name, "shader passed for program");
1308       } else {
1309         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
1310       }
1311     }
1312     LogClientServiceForInfo(program, client_id, function_name);
1313     return program;
1314   }
1315 
1316 
1317   // Creates a Shader for the given shader.
CreateShader(GLuint client_id,GLuint service_id,GLenum shader_type)1318   Shader* CreateShader(
1319       GLuint client_id,
1320       GLuint service_id,
1321       GLenum shader_type) {
1322     return shader_manager()->CreateShader(
1323         client_id, service_id, shader_type);
1324   }
1325 
1326   // Gets the shader info for the given shader. Returns nullptr if none exists.
GetShader(GLuint client_id)1327   Shader* GetShader(GLuint client_id) {
1328     return shader_manager()->GetShader(client_id);
1329   }
1330 
1331   // Gets the shader info for the given shader. If it's not a shader generates a
1332   // GL error. Returns nullptr if not shader.
GetShaderInfoNotProgram(GLuint client_id,const char * function_name)1333   Shader* GetShaderInfoNotProgram(
1334       GLuint client_id, const char* function_name) {
1335     Shader* shader = GetShader(client_id);
1336     if (!shader) {
1337       if (GetProgram(client_id)) {
1338         LOCAL_SET_GL_ERROR(
1339             GL_INVALID_OPERATION, function_name, "program passed for shader");
1340       } else {
1341         LOCAL_SET_GL_ERROR(
1342             GL_INVALID_VALUE, function_name, "unknown shader");
1343       }
1344     }
1345     LogClientServiceForInfo(shader, client_id, function_name);
1346     return shader;
1347   }
1348 
1349   // Creates a buffer info for the given buffer.
CreateBuffer(GLuint client_id,GLuint service_id)1350   void CreateBuffer(GLuint client_id, GLuint service_id) {
1351     return buffer_manager()->CreateBuffer(client_id, service_id);
1352   }
1353 
1354   // Gets the buffer info for the given buffer.
GetBuffer(GLuint client_id)1355   Buffer* GetBuffer(GLuint client_id) {
1356     Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1357     return buffer;
1358   }
1359 
1360   // Creates a framebuffer info for the given framebuffer.
CreateFramebuffer(GLuint client_id,GLuint service_id)1361   void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1362     return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
1363   }
1364 
1365   // Gets the framebuffer info for the given framebuffer.
GetFramebuffer(GLuint client_id)1366   Framebuffer* GetFramebuffer(GLuint client_id) {
1367     return framebuffer_manager()->GetFramebuffer(client_id);
1368   }
1369 
1370   // Removes the framebuffer info for the given framebuffer.
RemoveFramebuffer(GLuint client_id)1371   void RemoveFramebuffer(GLuint client_id) {
1372     framebuffer_manager()->RemoveFramebuffer(client_id);
1373   }
1374 
1375   // Creates a renderbuffer info for the given renderbuffer.
CreateRenderbuffer(GLuint client_id,GLuint service_id)1376   void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1377     return renderbuffer_manager()->CreateRenderbuffer(
1378         client_id, service_id);
1379   }
1380 
1381   // Gets the renderbuffer info for the given renderbuffer.
GetRenderbuffer(GLuint client_id)1382   Renderbuffer* GetRenderbuffer(GLuint client_id) {
1383     return renderbuffer_manager()->GetRenderbuffer(client_id);
1384   }
1385 
1386   // Removes the renderbuffer info for the given renderbuffer.
RemoveRenderbuffer(GLuint client_id)1387   void RemoveRenderbuffer(GLuint client_id) {
1388     renderbuffer_manager()->RemoveRenderbuffer(client_id);
1389   }
1390 
1391   // Gets the vertex attrib manager for the given vertex array.
GetVertexAttribManager(GLuint client_id)1392   VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1393     VertexAttribManager* info =
1394         vertex_array_manager()->GetVertexAttribManager(client_id);
1395     return info;
1396   }
1397 
1398   // Removes the vertex attrib manager for the given vertex array.
RemoveVertexAttribManager(GLuint client_id)1399   void RemoveVertexAttribManager(GLuint client_id) {
1400     vertex_array_manager()->RemoveVertexAttribManager(client_id);
1401   }
1402 
1403   // Creates a vertex attrib manager for the given vertex array.
CreateVertexAttribManager(GLuint client_id,GLuint service_id,bool client_visible)1404   scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1405       GLuint client_id,
1406       GLuint service_id,
1407       bool client_visible) {
1408     return vertex_array_manager()->CreateVertexAttribManager(
1409         client_id, service_id, group_->max_vertex_attribs(), client_visible,
1410         feature_info_->IsWebGL2OrES3Context());
1411   }
1412 
1413   void DoBindAttribLocation(GLuint client_id,
1414                             GLuint index,
1415                             const std::string& name);
1416 
1417   error::Error DoBindFragDataLocation(GLuint program_id,
1418                                       GLuint colorName,
1419                                       const std::string& name);
1420 
1421   error::Error DoBindFragDataLocationIndexed(GLuint program_id,
1422                                              GLuint colorName,
1423                                              GLuint index,
1424                                              const std::string& name);
1425 
1426   void DoBindUniformLocationCHROMIUM(GLuint client_id,
1427                                      GLint location,
1428                                      const std::string& name);
1429 
1430   error::Error GetAttribLocationHelper(GLuint client_id,
1431                                        uint32_t location_shm_id,
1432                                        uint32_t location_shm_offset,
1433                                        const std::string& name_str);
1434 
1435   error::Error GetUniformLocationHelper(GLuint client_id,
1436                                         uint32_t location_shm_id,
1437                                         uint32_t location_shm_offset,
1438                                         const std::string& name_str);
1439 
1440   error::Error GetFragDataLocationHelper(GLuint client_id,
1441                                          uint32_t location_shm_id,
1442                                          uint32_t location_shm_offset,
1443                                          const std::string& name_str);
1444 
1445   error::Error GetFragDataIndexHelper(GLuint program_id,
1446                                       uint32_t index_shm_id,
1447                                       uint32_t index_shm_offset,
1448                                       const std::string& name_str);
1449 
1450   // Wrapper for glShaderSource.
1451   void DoShaderSource(
1452       GLuint client_id, GLsizei count, const char** data, const GLint* length);
1453 
1454   // Wrapper for glTransformFeedbackVaryings.
1455   void DoTransformFeedbackVaryings(
1456       GLuint client_program_id, GLsizei count, const char* const* varyings,
1457       GLenum buffer_mode);
1458 
1459   // Clear any textures used by the current program.
1460   bool ClearUnclearedTextures();
1461 
1462   // Clears any uncleared attachments attached to the given frame buffer.
1463   // Returns false if there was a generated GL error.
1464   void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
1465 
1466   // overridden from GLES2Decoder
1467   bool ClearLevel(Texture* texture,
1468                   unsigned target,
1469                   int level,
1470                   unsigned format,
1471                   unsigned type,
1472                   int xoffset,
1473                   int yoffset,
1474                   int width,
1475                   int height) override;
1476 
1477   // Helper function for ClearLevel that attempts to clear using a glClear call
1478   // to a temporary FBO, rather than using glTexSubImage2D.
1479   bool ClearLevelUsingGL(Texture* texture,
1480                          uint32_t channels,
1481                          unsigned target,
1482                          int level,
1483                          int xoffset,
1484                          int yoffset,
1485                          int width,
1486                          int height);
1487 
1488   // overridden from GLES2Decoder
1489   bool ClearCompressedTextureLevel(Texture* texture,
1490                                    unsigned target,
1491                                    int level,
1492                                    unsigned format,
1493                                    int width,
1494                                    int height) override;
1495   bool ClearCompressedTextureLevel3D(Texture* texture,
1496                                      unsigned target,
1497                                      int level,
1498                                      unsigned format,
1499                                      int width,
1500                                      int height,
1501                                      int depth) override;
1502   bool IsCompressedTextureFormat(unsigned format) override;
1503 
1504   // overridden from GLES2Decoder
1505   bool ClearLevel3D(Texture* texture,
1506                     unsigned target,
1507                     int level,
1508                     unsigned format,
1509                     unsigned type,
1510                     int width,
1511                     int height,
1512                     int depth) override;
1513 
1514   // Restore all GL state that affects clearing.
1515   void RestoreClearState();
1516 
1517   // Remembers the state of some capabilities.
1518   // Returns: true if glEnable/glDisable should actually be called.
1519   bool SetCapabilityState(GLenum cap, bool enabled);
1520 
1521   // Check that the currently bound read framebuffer's color image
1522   // isn't the target texture of the glCopyTex{Sub}Image{2D|3D}.
1523   bool FormsTextureCopyingFeedbackLoop(
1524       TextureRef* texture,
1525       GLint level,
1526       GLint layer);
1527 
1528   // Check if a framebuffer meets our requirements.
1529   // Generates |gl_error| if the framebuffer is incomplete.
1530   bool CheckFramebufferValid(
1531       Framebuffer* framebuffer,
1532       GLenum target,
1533       GLenum gl_error,
1534       const char* func_name);
1535 
1536   bool CheckBoundDrawFramebufferValid(const char* func_name,
1537                                       bool check_float_blending = false);
1538   // Generates |gl_error| if the bound read fbo is incomplete.
1539   bool CheckBoundReadFramebufferValid(const char* func_name, GLenum gl_error);
1540   // This is only used by DoBlitFramebufferCHROMIUM which operates read/draw
1541   // framebuffer at the same time.
1542   bool CheckBoundFramebufferValid(const char* func_name);
1543 
1544   // Checks if the current program exists and is valid. If not generates the
1545   // appropriate GL error.  Returns true if the current program is in a usable
1546   // state.
1547   bool CheckCurrentProgram(const char* function_name);
1548 
1549   // Checks if the current program exists and is valid and that location is not
1550   // -1. If the current program is not valid generates the appropriate GL
1551   // error. Returns true if the current program is in a usable state and
1552   // location is not -1.
1553   bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1554 
1555   // Helper for CheckDrawingFeedbackLoops. Returns true if the attachment is
1556   // the same one where it samples from during drawing.
1557   bool CheckDrawingFeedbackLoopsHelper(
1558       const Framebuffer::Attachment* attachment,
1559       TextureRef* texture_ref,
1560       const char* function_name);
1561 
1562   bool SupportsDrawBuffers() const;
1563 
1564   // Checks if a draw buffer's format and its corresponding fragment shader
1565   // output's type are compatible, i.e., a signed integer typed variable is
1566   // incompatible with a float or unsigned integer buffer.
1567   // If incompaticle, generates an INVALID_OPERATION to avoid undefined buffer
1568   // contents and return false.
1569   // Otherwise, filter out the draw buffers that are not written to but are not
1570   // NONE through DrawBuffers, to be on the safe side. Return true.
1571   bool ValidateAndAdjustDrawBuffers(const char* function_name);
1572 
1573   // Filter out the draw buffers that have no images attached but are not NONE
1574   // through DrawBuffers, to be on the safe side.
1575   void AdjustDrawBuffers();
1576 
1577   // Checks if all active uniform blocks in the current program are backed by
1578   // a buffer of sufficient size.
1579   // If not, generates an INVALID_OPERATION to avoid undefined behavior in
1580   // shader execution and return false.
1581   bool ValidateUniformBlockBackings(const char* function_name);
1582 
1583   // Checks if |api_type| is valid for the given uniform
1584   // If the api type is not valid generates the appropriate GL
1585   // error. Returns true if |api_type| is valid for the uniform
1586   bool CheckUniformForApiType(const Program::UniformInfo* info,
1587                               const char* function_name,
1588                               UniformApiType api_type);
1589 
1590   // Gets the type of a uniform for a location in the current program. Sets GL
1591   // errors if the current program is not valid. Returns true if the current
1592   // program is valid and the location exists. Adjusts count so it
1593   // does not overflow the uniform.
1594   bool PrepForSetUniformByLocation(GLint fake_location,
1595                                    const char* function_name,
1596                                    UniformApiType api_type,
1597                                    GLint* real_location,
1598                                    GLenum* type,
1599                                    GLsizei* count);
1600 
1601   // Gets the service id for any simulated backbuffer fbo.
1602   GLuint GetBackbufferServiceId() const;
1603 
1604   // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv.  Returns
1605   // false if pname is unhandled.
1606   bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1607 
1608   // Helper for glGetVertexAttrib
1609   void GetVertexAttribHelper(
1610     const VertexAttrib* attrib, GLenum pname, GLint* param);
1611 
1612   // Wrapper for glActiveTexture
1613   void DoActiveTexture(GLenum texture_unit);
1614 
1615   // Wrapper for glAttachShader
1616   void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1617 
1618   // Wrapper for glBindBuffer since we need to track the current targets.
1619   void DoBindBuffer(GLenum target, GLuint buffer);
1620 
1621   // Wrapper for glBindBufferBase since we need to track the current targets.
1622   void DoBindBufferBase(GLenum target, GLuint index, GLuint buffer);
1623 
1624   // Wrapper for glBindBufferRange since we need to track the current targets.
1625   void DoBindBufferRange(GLenum target, GLuint index, GLuint buffer,
1626       GLintptr offset, GLsizeiptr size);
1627 
1628   // Helper for DoBindBufferBase and DoBindBufferRange.
1629   void BindIndexedBufferImpl(GLenum target, GLuint index, GLuint buffer,
1630                              GLintptr offset, GLsizeiptr size,
1631                              BindIndexedBufferFunctionType function_type,
1632                              const char* function_name);
1633 
1634   // Wrapper for glBindFramebuffer since we need to track the current targets.
1635   void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1636 
1637   // Wrapper for glBindRenderbuffer since we need to track the current targets.
1638   void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1639 
1640   // Wrapper for glBindTexture since we need to track the current targets.
1641   void DoBindTexture(GLenum target, GLuint texture);
1642 
1643   // Wrapper for glBindSampler since we need to track the current targets.
1644   void DoBindSampler(GLuint unit, GLuint sampler);
1645 
1646   // Wrapper for glBindTransformFeedback since we need to emulate ES3 behaviors
1647   // for BindBufferRange on Desktop GL lower than 4.2.
1648   void DoBindTransformFeedback(GLenum target, GLuint transform_feedback);
1649 
1650   // Wrapper for glBeginTransformFeedback.
1651   void DoBeginTransformFeedback(GLenum primitive_mode);
1652 
1653   // Wrapper for glEndTransformFeedback.
1654   void DoEndTransformFeedback();
1655 
1656   // Wrapper for glPauseTransformFeedback.
1657   void DoPauseTransformFeedback();
1658 
1659   // Wrapper for glResumeTransformFeedback.
1660   void DoResumeTransformFeedback();
1661 
1662   // Wrapper for glBindVertexArrayOES
1663   void DoBindVertexArrayOES(GLuint array);
1664   void EmulateVertexArrayState();
1665 
1666   // Wrapper for glBlitFramebufferCHROMIUM.
1667   void DoBlitFramebufferCHROMIUM(
1668       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1669       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1670       GLbitfield mask, GLenum filter);
1671 
1672   // Wrapper for glBufferSubData.
1673   void DoBufferSubData(
1674     GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1675 
1676   // Wrapper for glCheckFramebufferStatus
1677   GLenum DoCheckFramebufferStatus(GLenum target);
1678 
1679   // Wrapper for glClear*()
1680   error::Error DoClear(GLbitfield mask);
1681   void DoClearBufferiv(GLenum buffer,
1682                        GLint drawbuffer,
1683                        const volatile GLint* value);
1684   void DoClearBufferuiv(GLenum buffer,
1685                         GLint drawbuffer,
1686                         const volatile GLuint* value);
1687   void DoClearBufferfv(GLenum buffer,
1688                        GLint drawbuffer,
1689                        const volatile GLfloat* value);
1690   void DoClearBufferfi(
1691       GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
1692 
1693   // Wrappers for various state.
1694   void DoDepthRangef(GLclampf znear, GLclampf zfar);
1695   void DoSampleCoverage(GLclampf value, GLboolean invert);
1696 
1697   // Wrapper for glCompileShader.
1698   void DoCompileShader(GLuint shader);
1699 
1700   // Wrapper for glDetachShader
1701   void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1702 
1703   // Wrapper for glDisable
1704   void DoDisable(GLenum cap);
1705 
1706   // Wrapper for glDisableVertexAttribArray.
1707   void DoDisableVertexAttribArray(GLuint index);
1708 
1709   // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1710   // attachments.
1711   void DoDiscardFramebufferEXT(GLenum target,
1712                                GLsizei count,
1713                                const volatile GLenum* attachments);
1714 
1715   void DoInvalidateFramebuffer(GLenum target,
1716                                GLsizei count,
1717                                const volatile GLenum* attachments);
1718   void DoInvalidateSubFramebuffer(GLenum target,
1719                                   GLsizei count,
1720                                   const volatile GLenum* attachments,
1721                                   GLint x,
1722                                   GLint y,
1723                                   GLsizei width,
1724                                   GLsizei height);
1725 
1726   // Helper for DoDiscardFramebufferEXT, DoInvalidate{Sub}Framebuffer.
1727   void InvalidateFramebufferImpl(GLenum target,
1728                                  GLsizei count,
1729                                  const volatile GLenum* attachments,
1730                                  GLint x,
1731                                  GLint y,
1732                                  GLsizei width,
1733                                  GLsizei height,
1734                                  const char* function_name,
1735                                  FramebufferOperation op);
1736 
1737   // Wrapper for glEnable
1738   void DoEnable(GLenum cap);
1739 
1740   // Wrapper for glEnableVertexAttribArray.
1741   void DoEnableVertexAttribArray(GLuint index);
1742 
1743   // Wrapper for glFinish.
1744   void DoFinish();
1745 
1746   // Wrapper for glFlush.
1747   void DoFlush();
1748 
1749   // Wrapper for glFramebufferParameteri.
1750   void DoFramebufferParameteri(GLenum target, GLenum pname, GLint param);
1751 
1752   // Wrapper for glFramebufferRenderbufffer.
1753   void DoFramebufferRenderbuffer(
1754       GLenum target, GLenum attachment, GLenum renderbuffertarget,
1755       GLuint renderbuffer);
1756 
1757   // Wrapper for glFramebufferTexture2D.
1758   void DoFramebufferTexture2D(
1759       GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1760       GLint level);
1761 
1762   // Wrapper for glFramebufferTexture2DMultisampleEXT.
1763   void DoFramebufferTexture2DMultisample(
1764       GLenum target, GLenum attachment, GLenum textarget,
1765       GLuint texture, GLint level, GLsizei samples);
1766 
1767   // Common implementation for both DoFramebufferTexture2D wrappers.
1768   void DoFramebufferTexture2DCommon(const char* name,
1769       GLenum target, GLenum attachment, GLenum textarget,
1770       GLuint texture, GLint level, GLsizei samples);
1771 
1772   // Wrapper for glFramebufferTextureLayer.
1773   void DoFramebufferTextureLayer(
1774       GLenum target, GLenum attachment, GLuint texture, GLint level,
1775       GLint layer);
1776 
1777   // Wrapper for glFramebufferTextureLayer.
1778   void DoFramebufferTextureMultiviewOVR(GLenum target,
1779                                         GLenum attachment,
1780                                         GLuint texture,
1781                                         GLint level,
1782                                         GLint base_view_index,
1783                                         GLsizei num_views);
1784 
1785   // Wrapper for glGenerateMipmap
1786   void DoGenerateMipmap(GLenum target);
1787 
1788   // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1789   // to account for different pname values defined in different extension
1790   // variants.
1791   GLenum AdjustGetPname(GLenum pname);
1792 
1793   // Wrapper for DoGetBooleanv.
1794   void DoGetBooleanv(GLenum pname, GLboolean* params, GLsizei params_size);
1795 
1796   // Wrapper for DoGetFloatv.
1797   void DoGetFloatv(GLenum pname, GLfloat* params, GLsizei params_size);
1798 
1799   // Wrapper for glGetFramebufferAttachmentParameteriv.
1800   void DoGetFramebufferAttachmentParameteriv(GLenum target,
1801                                              GLenum attachment,
1802                                              GLenum pname,
1803                                              GLint* params,
1804                                              GLsizei params_size);
1805 
1806   // Wrapper for glGetInteger64v.
1807   void DoGetInteger64v(GLenum pname, GLint64* params, GLsizei params_size);
1808 
1809   // Wrapper for glGetIntegerv.
1810   void DoGetIntegerv(GLenum pname, GLint* params, GLsizei params_size);
1811 
1812   // Helper for DoGetIntegeri_v and DoGetInteger64i_v.
1813   template <typename TYPE>
1814   void GetIndexedIntegerImpl(
1815       const char* function_name, GLenum target, GLuint index, TYPE* data);
1816 
1817   // Wrapper for glGetIntegeri_v.
1818   void DoGetIntegeri_v(GLenum target,
1819                        GLuint index,
1820                        GLint* params,
1821                        GLsizei params_size);
1822 
1823   // Wrapper for glGetInteger64i_v.
1824   void DoGetInteger64i_v(GLenum target,
1825                          GLuint index,
1826                          GLint64* params,
1827                          GLsizei params_size);
1828 
1829   // Gets the max value in a range in a buffer.
1830   GLuint DoGetMaxValueInBufferCHROMIUM(
1831       GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1832 
1833   // Wrapper for glGetBufferParameteri64v.
1834   void DoGetBufferParameteri64v(GLenum target,
1835                                 GLenum pname,
1836                                 GLint64* params,
1837                                 GLsizei params_size);
1838 
1839   // Wrapper for glGetBufferParameteriv.
1840   void DoGetBufferParameteriv(GLenum target,
1841                               GLenum pname,
1842                               GLint* params,
1843                               GLsizei params_size);
1844 
1845   // Wrapper for glGetProgramiv.
1846   void DoGetProgramiv(GLuint program_id,
1847                       GLenum pname,
1848                       GLint* params,
1849                       GLsizei params_size);
1850 
1851   // Wrapper for glRenderbufferParameteriv.
1852   void DoGetRenderbufferParameteriv(GLenum target,
1853                                     GLenum pname,
1854                                     GLint* params,
1855                                     GLsizei params_size);
1856 
1857   // Wrappers for glGetSamplerParameter.
1858   void DoGetSamplerParameterfv(GLuint client_id,
1859                                GLenum pname,
1860                                GLfloat* params,
1861                                GLsizei params_size);
1862   void DoGetSamplerParameteriv(GLuint client_id,
1863                                GLenum pname,
1864                                GLint* params,
1865                                GLsizei params_size);
1866 
1867   // Wrapper for glGetShaderiv
1868   void DoGetShaderiv(GLuint shader,
1869                      GLenum pname,
1870                      GLint* params,
1871                      GLsizei params_size);
1872 
1873   // Wrapper for glGetSynciv.
1874   void DoGetSynciv(GLuint sync_id,
1875                    GLenum pname,
1876                    GLsizei num_values,
1877                    GLsizei* length,
1878                    GLint* values);
1879 
1880   // Helper for DoGetTexParameter{f|i}v.
1881   void GetTexParameterImpl(
1882       GLenum target, GLenum pname, GLfloat* fparams, GLint* iparams,
1883       const char* function_name);
1884 
1885   // Wrappers for glGetTexParameter.
1886   void DoGetTexParameterfv(GLenum target,
1887                            GLenum pname,
1888                            GLfloat* params,
1889                            GLsizei params_size);
1890   void DoGetTexParameteriv(GLenum target,
1891                            GLenum pname,
1892                            GLint* params,
1893                            GLsizei params_size);
1894 
1895   // Wrappers for glGetVertexAttrib.
1896   template <typename T>
1897   void DoGetVertexAttribImpl(GLuint index, GLenum pname, T* params);
1898   void DoGetVertexAttribfv(GLuint index,
1899                            GLenum pname,
1900                            GLfloat* params,
1901                            GLsizei params_size);
1902   void DoGetVertexAttribiv(GLuint index,
1903                            GLenum pname,
1904                            GLint* params,
1905                            GLsizei params_size);
1906   void DoGetVertexAttribIiv(GLuint index,
1907                             GLenum pname,
1908                             GLint* params,
1909                             GLsizei params_size);
1910   void DoGetVertexAttribIuiv(GLuint index,
1911                              GLenum pname,
1912                              GLuint* params,
1913                              GLsizei params_size);
1914 
1915   // Wrappers for glIsXXX functions.
1916   bool DoIsEnabled(GLenum cap);
1917   bool DoIsBuffer(GLuint client_id);
1918   bool DoIsFramebuffer(GLuint client_id);
1919   bool DoIsProgram(GLuint client_id);
1920   bool DoIsRenderbuffer(GLuint client_id);
1921   bool DoIsShader(GLuint client_id);
1922   bool DoIsTexture(GLuint client_id);
1923   bool DoIsSampler(GLuint client_id);
1924   bool DoIsTransformFeedback(GLuint client_id);
1925   bool DoIsVertexArrayOES(GLuint client_id);
1926   bool DoIsSync(GLuint client_id);
1927 
1928   void DoLineWidth(GLfloat width);
1929 
1930   // Wrapper for glLinkProgram
1931   void DoLinkProgram(GLuint program);
1932 
1933   void DoMultiDrawBeginCHROMIUM(GLsizei drawcount);
1934   void DoMultiDrawEndCHROMIUM();
1935 
1936   // Wrapper for glOverlayPromotionHintCHROMIUIM
1937   void DoOverlayPromotionHintCHROMIUM(GLuint client_id,
1938                                       GLboolean promotion_hint,
1939                                       GLint display_x,
1940                                       GLint display_y,
1941                                       GLint display_width,
1942                                       GLint display_height);
1943 
1944   // Wrapper for glSetDrawRectangleCHROMIUM
1945   void DoSetDrawRectangleCHROMIUM(GLint x, GLint y, GLint width, GLint height);
1946 
1947   void DoSetEnableDCLayersCHROMIUM(GLboolean enable);
1948 
1949   // Wrapper for glReadBuffer
1950   void DoReadBuffer(GLenum src);
1951 
1952   // Wrapper for glRenderbufferStorage.
1953   void DoRenderbufferStorage(
1954       GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
1955 
1956   // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1957   void DoRenderbufferStorageMultisampleCHROMIUM(
1958       GLenum target, GLsizei samples, GLenum internalformat,
1959       GLsizei width, GLsizei height);
1960 
1961   // Handler for glRenderbufferStorageMultisampleAdvancedAMD.
1962   void DoRenderbufferStorageMultisampleAdvancedAMD(GLenum target,
1963                                                    GLsizei samples,
1964                                                    GLsizei storageSamples,
1965                                                    GLenum internalformat,
1966                                                    GLsizei width,
1967                                                    GLsizei height);
1968 
1969   // Handler for glRenderbufferStorageMultisampleEXT
1970   // (multisampled_render_to_texture).
1971   void DoRenderbufferStorageMultisampleEXT(
1972       GLenum target, GLsizei samples, GLenum internalformat,
1973       GLsizei width, GLsizei height);
1974 
1975   // Wrapper for glFenceSync.
1976   GLsync DoFenceSync(GLenum condition, GLbitfield flags);
1977 
1978   GLsizei InternalFormatSampleCountsHelper(
1979       GLenum target,
1980       GLenum format,
1981       std::vector<GLint>* out_sample_counts);
1982 
1983   // Common validation for multisample extensions.
1984   bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1985                                               GLenum internalformat,
1986                                               GLsizei width,
1987                                               GLsizei height);
1988 
1989   // validation for multisample AMD extension.
1990   bool ValidateRenderbufferStorageMultisampleAMD(GLsizei samples,
1991                                                  GLsizei storageSamples,
1992                                                  GLenum internalformat,
1993                                                  GLsizei width,
1994                                                  GLsizei height);
1995   // Verifies that the currently bound multisample renderbuffer is valid
1996   // Very slow! Only done on platforms with driver bugs that return invalid
1997   // buffers under memory pressure
1998   bool VerifyMultisampleRenderbufferIntegrity(
1999       GLuint renderbuffer, GLenum format);
2000 
2001   // Wrapper for glReleaseShaderCompiler.
2002   void DoReleaseShaderCompiler();
2003 
2004   // Wrappers for glSamplerParameter functions.
2005   void DoSamplerParameterf(GLuint client_id, GLenum pname, GLfloat param);
2006   void DoSamplerParameteri(GLuint client_id, GLenum pname, GLint param);
2007   void DoSamplerParameterfv(GLuint client_id,
2008                             GLenum pname,
2009                             const volatile GLfloat* params);
2010   void DoSamplerParameteriv(GLuint client_id,
2011                             GLenum pname,
2012                             const volatile GLint* params);
2013 
2014   // Wrappers for glTexParameter functions.
2015   void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
2016   void DoTexParameteri(GLenum target, GLenum pname, GLint param);
2017   void DoTexParameterfv(GLenum target,
2018                         GLenum pname,
2019                         const volatile GLfloat* params);
2020   void DoTexParameteriv(GLenum target,
2021                         GLenum pname,
2022                         const volatile GLint* params);
2023 
2024   // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
2025   // spec only these 2 functions can be used to set sampler uniforms.
2026   void DoUniform1i(GLint fake_location, GLint v0);
2027   void DoUniform1iv(GLint fake_location,
2028                     GLsizei count,
2029                     const volatile GLint* value);
2030   void DoUniform2iv(GLint fake_location,
2031                     GLsizei count,
2032                     const volatile GLint* value);
2033   void DoUniform3iv(GLint fake_location,
2034                     GLsizei count,
2035                     const volatile GLint* value);
2036   void DoUniform4iv(GLint fake_location,
2037                     GLsizei count,
2038                     const volatile GLint* value);
2039 
2040   void DoUniform1ui(GLint fake_location, GLuint v0);
2041   void DoUniform1uiv(GLint fake_location,
2042                      GLsizei count,
2043                      const volatile GLuint* value);
2044   void DoUniform2uiv(GLint fake_location,
2045                      GLsizei count,
2046                      const volatile GLuint* value);
2047   void DoUniform3uiv(GLint fake_location,
2048                      GLsizei count,
2049                      const volatile GLuint* value);
2050   void DoUniform4uiv(GLint fake_location,
2051                      GLsizei count,
2052                      const volatile GLuint* value);
2053 
2054   // Wrappers for glUniformfv because some drivers don't correctly accept
2055   // bool uniforms.
2056   void DoUniform1fv(GLint fake_location,
2057                     GLsizei count,
2058                     const volatile GLfloat* value);
2059   void DoUniform2fv(GLint fake_location,
2060                     GLsizei count,
2061                     const volatile GLfloat* value);
2062   void DoUniform3fv(GLint fake_location,
2063                     GLsizei count,
2064                     const volatile GLfloat* value);
2065   void DoUniform4fv(GLint fake_location,
2066                     GLsizei count,
2067                     const volatile GLfloat* value);
2068 
2069   void DoUniformMatrix2fv(GLint fake_location,
2070                           GLsizei count,
2071                           GLboolean transpose,
2072                           const volatile GLfloat* value);
2073   void DoUniformMatrix3fv(GLint fake_location,
2074                           GLsizei count,
2075                           GLboolean transpose,
2076                           const volatile GLfloat* value);
2077   void DoUniformMatrix4fv(GLint fake_location,
2078                           GLsizei count,
2079                           GLboolean transpose,
2080                           const volatile GLfloat* value);
2081   void DoUniformMatrix4fvStreamTextureMatrixCHROMIUM(
2082       GLint fake_location,
2083       GLboolean transpose,
2084       const volatile GLfloat* default_value);
2085   void DoUniformMatrix2x3fv(GLint fake_location,
2086                             GLsizei count,
2087                             GLboolean transpose,
2088                             const volatile GLfloat* value);
2089   void DoUniformMatrix2x4fv(GLint fake_location,
2090                             GLsizei count,
2091                             GLboolean transpose,
2092                             const volatile GLfloat* value);
2093   void DoUniformMatrix3x2fv(GLint fake_location,
2094                             GLsizei count,
2095                             GLboolean transpose,
2096                             const volatile GLfloat* value);
2097   void DoUniformMatrix3x4fv(GLint fake_location,
2098                             GLsizei count,
2099                             GLboolean transpose,
2100                             const volatile GLfloat* value);
2101   void DoUniformMatrix4x2fv(GLint fake_location,
2102                             GLsizei count,
2103                             GLboolean transpose,
2104                             const volatile GLfloat* value);
2105   void DoUniformMatrix4x3fv(GLint fake_location,
2106                             GLsizei count,
2107                             GLboolean transpose,
2108                             const volatile GLfloat* value);
2109 
2110   template <typename T>
2111   bool SetVertexAttribValue(
2112     const char* function_name, GLuint index, const T* value);
2113 
2114   // Wrappers for glVertexAttrib??
2115   void DoVertexAttrib1f(GLuint index, GLfloat v0);
2116   void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
2117   void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
2118   void DoVertexAttrib4f(
2119       GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
2120   void DoVertexAttrib1fv(GLuint index, const volatile GLfloat* v);
2121   void DoVertexAttrib2fv(GLuint index, const volatile GLfloat* v);
2122   void DoVertexAttrib3fv(GLuint index, const volatile GLfloat* v);
2123   void DoVertexAttrib4fv(GLuint index, const volatile GLfloat* v);
2124   void DoVertexAttribI4i(GLuint index, GLint v0, GLint v1, GLint v2, GLint v3);
2125   void DoVertexAttribI4iv(GLuint index, const volatile GLint* v);
2126   void DoVertexAttribI4ui(
2127       GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
2128   void DoVertexAttribI4uiv(GLuint index, const volatile GLuint* v);
2129 
2130   // Wrapper for glViewport
2131   void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
2132 
2133   // Wrapper for glScissor
2134   void DoScissor(GLint x, GLint y, GLsizei width, GLsizei height);
2135 
2136   // Wrapper for glUseProgram
2137   void DoUseProgram(GLuint program);
2138 
2139   // Wrapper for glValidateProgram.
2140   void DoValidateProgram(GLuint program_client_id);
2141 
2142   void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
2143   void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
2144   void DoPopGroupMarkerEXT(void);
2145 
2146   // Wrapper for ContextVisibilityHintCHROMIUM.
2147   void DoContextVisibilityHintCHROMIUM(GLboolean visibility);
2148 
2149   // Gets the number of values that will be returned by glGetXXX. Returns
2150   // false if pname is unknown.
2151   bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
2152 
2153   // Checks if every attribute's type set by vertexAttrib API match
2154   // the type of corresponding attribute in vertex shader.
2155   bool AttribsTypeMatch();
2156 
2157   // Verifies that front/back stencil settings match, per WebGL specification:
2158   // https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.11
2159   bool ValidateStencilStateForDraw(const char* function_name);
2160 
2161   // Checks if the current program and vertex attributes are valid for drawing.
2162   bool IsDrawValid(const char* function_name,
2163                    GLuint max_vertex_accessed,
2164                    bool instanced,
2165                    GLsizei primcount,
2166                    GLint basevertex,
2167                    GLuint baseinstance);
2168 
2169   // Returns true if successful, simulated will be true if attrib0 was
2170   // simulated.
2171   bool SimulateAttrib0(
2172       const char* function_name, GLuint max_vertex_accessed, bool* simulated);
2173   void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
2174 
2175   // Copies the image to the texture currently bound to |textarget|. The image
2176   // state of |texture| is updated to reflect the new state.
2177   void DoCopyTexImage(Texture* texture, GLenum textarget, gl::GLImage* image);
2178 
2179   // If the texture has an image but that image is not bound or copied to the
2180   // texture, this will first attempt to bind it, and if that fails
2181   // DoCopyTexImage on it. texture_unit is the texture unit it should be bound
2182   // to, or 0 if it doesn't matter - setting it to 0 will cause the previous
2183   // binding to be restored after the operation. This returns true if a copy
2184   // or bind happened and the caller needs to restore the previous texture
2185   // binding.
2186   bool DoBindOrCopyTexImageIfNeeded(Texture* texture,
2187                                     GLenum textarget,
2188                                     GLuint texture_unit);
2189 
2190   void DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
2191                                             GLuint dest_id,
2192                                             GLint x,
2193                                             GLint y,
2194                                             GLsizei width,
2195                                             GLsizei height);
2196 
2197   void DoWindowRectanglesEXT(GLenum mode, GLsizei n, const volatile GLint* box);
2198 
2199   void DoSetReadbackBufferShadowAllocationINTERNAL(GLuint buffer_id,
2200                                                    GLuint shm_id,
2201                                                    GLuint shm_offset,
2202                                                    GLuint size);
2203 
2204   // Returns false if a GL error occurred. textures_set is always modified
2205   // appropriately to indicate whether textures were set, even on failure.
2206   bool PrepareTexturesForRender(bool* textures_set, const char* function_name);
2207   void RestoreStateForTextures();
2208 
2209   // Returns true if GL_FIXED attribs were simulated.
2210   bool SimulateFixedAttribs(const char* function_name,
2211                             GLuint max_vertex_accessed,
2212                             bool* simulated,
2213                             GLsizei primcount);
2214   void RestoreStateForSimulatedFixedAttribs();
2215 
2216   // Having extra base vertex and base instance parameters and run-time if else
2217   // for heavily called DoMultiDrawArrays/DoMultiDrawElements caused
2218   // performance regression, thus use non-type template draw functions
2219   enum class DrawArraysOption { Default = 0, UseBaseInstance };
2220   enum class DrawElementsOption { Default = 0, UseBaseVertexBaseInstance };
2221 
2222   template <DrawArraysOption option>
2223   bool CheckMultiDrawArraysVertices(const char* function_name,
2224                                     bool instanced,
2225                                     const GLint* firsts,
2226                                     const GLsizei* counts,
2227                                     const GLsizei* primcounts,
2228                                     const GLuint* baseinstances,
2229                                     GLsizei drawcount,
2230                                     GLuint* total_max_vertex_accessed,
2231                                     GLsizei* total_max_primcount);
2232   template <DrawElementsOption option>
2233   bool CheckMultiDrawElementsVertices(const char* function_name,
2234                                       bool instanced,
2235                                       const GLsizei* counts,
2236                                       GLenum type,
2237                                       const int32_t* offsets,
2238                                       const GLsizei* primcounts,
2239                                       const GLint* basevertices,
2240                                       const GLuint* baseinstances,
2241                                       GLsizei drawcount,
2242                                       Buffer* element_array_buffer,
2243                                       GLuint* total_max_vertex_accessed,
2244                                       GLsizei* total_max_primcount);
2245   bool CheckTransformFeedback(const char* function_name,
2246                               bool instanced,
2247                               GLenum mode,
2248                               const GLsizei* counts,
2249                               const GLsizei* primcounts,
2250                               GLsizei drawcount,
2251                               GLsizei* transform_feedback_vertices);
2252 
2253   // Handle MultiDrawArrays and MultiDrawElements for both instanced and
2254   // non-instanced cases (primcount is always 1 for non-instanced).
2255   // (basevertex and baseinstance are always 0 for non-basevertex-baseinstance
2256   // draws)
2257   template <DrawArraysOption option>
2258   error::Error DoMultiDrawArrays(const char* function_name,
2259                                  bool instanced,
2260                                  GLenum mode,
2261                                  const GLint* firsts,
2262                                  const GLsizei* counts,
2263                                  const GLsizei* primcounts,
2264                                  const GLuint* baseinstances,
2265                                  GLsizei drawcount);
2266   template <DrawElementsOption option>
2267   error::Error DoMultiDrawElements(const char* function_name,
2268                                    bool instanced,
2269                                    GLenum mode,
2270                                    const GLsizei* counts,
2271                                    GLenum type,
2272                                    const int32_t* offsets,
2273                                    const GLsizei* primcounts,
2274                                    const GLint* basevertices,
2275                                    const GLuint* baseinstances,
2276                                    GLsizei drawcount);
2277 
GetBindTargetForSamplerType(GLenum type)2278   GLenum GetBindTargetForSamplerType(GLenum type) {
2279     switch (type) {
2280       case GL_SAMPLER_2D:
2281       case GL_SAMPLER_2D_SHADOW:
2282       case GL_INT_SAMPLER_2D:
2283       case GL_UNSIGNED_INT_SAMPLER_2D:
2284         return GL_TEXTURE_2D;
2285       case GL_SAMPLER_CUBE:
2286       case GL_SAMPLER_CUBE_SHADOW:
2287       case GL_INT_SAMPLER_CUBE:
2288       case GL_UNSIGNED_INT_SAMPLER_CUBE:
2289         return GL_TEXTURE_CUBE_MAP;
2290       case GL_SAMPLER_EXTERNAL_OES:
2291         return GL_TEXTURE_EXTERNAL_OES;
2292       case GL_SAMPLER_2D_RECT_ARB:
2293         return GL_TEXTURE_RECTANGLE_ARB;
2294       case GL_SAMPLER_3D:
2295       case GL_INT_SAMPLER_3D:
2296       case GL_UNSIGNED_INT_SAMPLER_3D:
2297         return GL_TEXTURE_3D;
2298       case GL_SAMPLER_2D_ARRAY:
2299       case GL_SAMPLER_2D_ARRAY_SHADOW:
2300       case GL_INT_SAMPLER_2D_ARRAY:
2301       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
2302         return GL_TEXTURE_2D_ARRAY;
2303       default:
2304         NOTREACHED();
2305         return 0;
2306     }
2307   }
2308 
2309   // Gets the framebuffer info for a particular target.
GetFramebufferInfoForTarget(GLenum target) const2310   Framebuffer* GetFramebufferInfoForTarget(GLenum target) const {
2311     Framebuffer* framebuffer = nullptr;
2312     switch (target) {
2313       case GL_FRAMEBUFFER:
2314       case GL_DRAW_FRAMEBUFFER_EXT:
2315         framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
2316         break;
2317       case GL_READ_FRAMEBUFFER_EXT:
2318         framebuffer = framebuffer_state_.bound_read_framebuffer.get();
2319         break;
2320       default:
2321         NOTREACHED();
2322         break;
2323     }
2324     return framebuffer;
2325   }
2326 
GetRenderbufferInfoForTarget(GLenum target)2327   Renderbuffer* GetRenderbufferInfoForTarget(
2328       GLenum target) {
2329     Renderbuffer* renderbuffer = nullptr;
2330     switch (target) {
2331       case GL_RENDERBUFFER:
2332         renderbuffer = state_.bound_renderbuffer.get();
2333         break;
2334       default:
2335         NOTREACHED();
2336         break;
2337     }
2338     return renderbuffer;
2339   }
2340 
2341   // Validates the program and location for a glGetUniform call and returns
2342   // a SizeResult setup to receive the result. Returns true if glGetUniform
2343   // should be called.
2344   template <class T>
2345   bool GetUniformSetup(GLuint program,
2346                        GLint fake_location,
2347                        uint32_t shm_id,
2348                        uint32_t shm_offset,
2349                        error::Error* error,
2350                        GLint* real_location,
2351                        GLuint* service_id,
2352                        SizedResult<T>** result,
2353                        GLenum* result_type,
2354                        GLsizei* result_size);
2355 
2356   bool WasContextLost() const override;
2357   bool WasContextLostByRobustnessExtension() const override;
2358   void MarkContextLost(error::ContextLostReason reason) override;
2359   bool CheckResetStatus() override;
2360 
2361   bool ValidateCompressedTexDimensions(
2362       const char* function_name, GLenum target, GLint level,
2363       GLsizei width, GLsizei height, GLsizei depth, GLenum format);
2364   bool ValidateCompressedTexFuncData(const char* function_name,
2365                                      GLsizei width,
2366                                      GLsizei height,
2367                                      GLsizei depth,
2368                                      GLenum format,
2369                                      GLsizei size,
2370                                      const GLvoid* data);
2371   bool ValidateCompressedTexSubDimensions(
2372     const char* function_name,
2373     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
2374     GLsizei width, GLsizei height, GLsizei depth, GLenum format,
2375     Texture* texture);
2376   bool ValidateCopyTextureCHROMIUMTextures(const char* function_name,
2377                                            GLenum dest_target,
2378                                            TextureRef* source_texture_ref,
2379                                            TextureRef* dest_texture_ref);
2380   bool CanUseCopyTextureCHROMIUMInternalFormat(GLenum dest_internal_format);
2381   void CopySubTextureHelper(const char* function_name,
2382                             GLuint source_id,
2383                             GLint source_level,
2384                             GLenum dest_target,
2385                             GLuint dest_id,
2386                             GLint dest_level,
2387                             GLint xoffset,
2388                             GLint yoffset,
2389                             GLint x,
2390                             GLint y,
2391                             GLsizei width,
2392                             GLsizei height,
2393                             GLboolean unpack_flip_y,
2394                             GLboolean unpack_premultiply_alpha,
2395                             GLboolean unpack_unmultiply_alpha,
2396                             GLboolean dither);
2397 
2398   void RenderWarning(const char* filename, int line, const std::string& msg);
2399   void PerformanceWarning(
2400       const char* filename, int line, const std::string& msg);
2401 
features() const2402   const FeatureInfo::FeatureFlags& features() const {
2403     return feature_info_->feature_flags();
2404   }
2405 
workarounds() const2406   const GpuDriverBugWorkarounds& workarounds() const {
2407     return feature_info_->workarounds();
2408   }
2409 
ShouldDeferDraws()2410   bool ShouldDeferDraws() {
2411     return !offscreen_target_frame_buffer_.get() &&
2412            framebuffer_state_.bound_draw_framebuffer.get() == nullptr &&
2413            surface_->DeferDraws();
2414   }
2415 
ShouldDeferReads()2416   bool ShouldDeferReads() {
2417     return !offscreen_target_frame_buffer_.get() &&
2418            framebuffer_state_.bound_read_framebuffer.get() == nullptr &&
2419            surface_->DeferDraws();
2420   }
2421 
WillAccessBoundFramebufferForDraw()2422   error::Error WillAccessBoundFramebufferForDraw() {
2423     if (ShouldDeferDraws())
2424       return error::kDeferCommandUntilLater;
2425     if (!offscreen_target_frame_buffer_.get() &&
2426         !framebuffer_state_.bound_draw_framebuffer.get() &&
2427         !surface_->SetBackbufferAllocation(true))
2428       return error::kLostContext;
2429     return error::kNoError;
2430   }
2431 
WillAccessBoundFramebufferForRead()2432   error::Error WillAccessBoundFramebufferForRead() {
2433     if (ShouldDeferReads())
2434       return error::kDeferCommandUntilLater;
2435     if (!offscreen_target_frame_buffer_.get() &&
2436         !framebuffer_state_.bound_read_framebuffer.get() &&
2437         !surface_->SetBackbufferAllocation(true))
2438       return error::kLostContext;
2439     return error::kNoError;
2440   }
2441 
2442   // Whether the back buffer exposed to the client has an alpha channel. Note
2443   // that this is potentially different from whether the implementation of the
2444   // back buffer has an alpha channel.
ClientExposedBackBufferHasAlpha() const2445   bool ClientExposedBackBufferHasAlpha() const {
2446     if (back_buffer_draw_buffer_ == GL_NONE)
2447       return false;
2448     if (offscreen_target_frame_buffer_.get()) {
2449       return offscreen_buffer_should_have_alpha_;
2450     }
2451     return (back_buffer_color_format_ == GL_RGBA ||
2452             back_buffer_color_format_ == GL_RGBA8);
2453   }
2454 
2455   // If the back buffer has a non-emulated alpha channel, the clear color should
2456   // be 0. Otherwise, the clear color should be 1.
BackBufferAlphaClearColor() const2457   GLfloat BackBufferAlphaClearColor() const {
2458     return offscreen_buffer_should_have_alpha_ ? 0.f : 1.f;
2459   }
2460 
2461   // Set remaining commands to process to 0 to force DoCommands to return
2462   // and allow context preemption and GPU watchdog checks in CommandExecutor().
2463   void ExitCommandProcessingEarly() override;
2464 
2465   void ProcessPendingReadPixels(bool did_finish);
2466   void FinishReadPixels(GLsizei width,
2467                         GLsizei height,
2468                         GLsizei format,
2469                         GLsizei type,
2470                         uint32_t pixels_shm_id,
2471                         uint32_t pixels_shm_offset,
2472                         uint32_t result_shm_id,
2473                         uint32_t result_shm_offset,
2474                         GLint pack_alignment,
2475                         GLenum read_format,
2476                         GLuint buffer);
2477 
2478   // Checks to see if the inserted fence has completed.
2479   void ProcessDescheduleUntilFinished();
2480 
2481   // If |texture_manager_version_| doesn't match the current version, then this
2482   // will rebind all external textures to match their current service_id.
2483   void RestoreAllExternalTextureBindingsIfNeeded() override;
2484 
2485   const SamplerState& GetSamplerStateForTextureUnit(GLenum target, GLuint unit);
2486 
2487   // copyTexImage2D doesn't work on OSX under very specific conditions.
2488   // Returns whether those conditions have been met. If this method returns
2489   // true, |source_texture_service_id| and |source_texture_target| are also
2490   // populated, since they are needed to implement the workaround.
2491   bool NeedsCopyTextureImageWorkaround(GLenum internal_format,
2492                                        int32_t channels_exist,
2493                                        GLuint* source_texture_service_id,
2494                                        GLenum* source_texture_target);
2495 
2496   // Whether a texture backed by a Chromium Image needs to emulate GL_RGB format
2497   // using GL_RGBA and glColorMask.
2498   bool ChromiumImageNeedsRGBEmulation();
2499 
2500   // The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and
2501   // equivalent functions reset shared state.
2502   void ClearScheduleCALayerState();
2503 
2504   // Helper method to call glClear workaround.
2505   void ClearFramebufferForWorkaround(GLbitfield mask);
2506 
SupportsSeparateFramebufferBinds() const2507   bool SupportsSeparateFramebufferBinds() const {
2508     return (feature_info_->feature_flags().chromium_framebuffer_multisample ||
2509             feature_info_->IsWebGL2OrES3Context());
2510   }
2511 
GetDrawFramebufferTarget() const2512   GLenum GetDrawFramebufferTarget() const {
2513     return SupportsSeparateFramebufferBinds() ?
2514         GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER;
2515   }
2516 
GetReadFramebufferTarget() const2517   GLenum GetReadFramebufferTarget() const {
2518     return SupportsSeparateFramebufferBinds() ?
2519         GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER;
2520   }
2521 
GetBoundDrawFramebuffer() const2522   Framebuffer* GetBoundDrawFramebuffer() const {
2523     return framebuffer_state_.bound_draw_framebuffer.get();
2524   }
2525 
GetBoundReadFramebuffer() const2526   Framebuffer* GetBoundReadFramebuffer() const {
2527     GLenum target = GetReadFramebufferTarget();
2528     return GetFramebufferInfoForTarget(target);
2529   }
2530 
2531   bool InitializeCopyTexImageBlitter(const char* function_name);
2532   bool InitializeCopyTextureCHROMIUM(const char* function_name);
2533   bool InitializeSRGBConverter(const char* function_name);
2534 
2535   void UnbindTexture(TextureRef* texture_ref,
2536                      bool supports_separate_framebuffer_binds);
2537 
2538   void OnAbstractTextureDestroyed(ValidatingAbstractTextureImpl* texture,
2539                                   scoped_refptr<TextureRef> texture_ref);
2540 
2541   void ReadBackBuffersIntoShadowCopies(
2542       base::flat_set<scoped_refptr<Buffer>> buffers_to_shadow_copy);
2543 
2544   // Compiles the given shader and exits command processing early.
2545   void CompileShaderAndExitCommandProcessingEarly(Shader* shader);
2546 
2547   // Notify the watchdog thread of progress, preventing time-outs when a
2548   // command takes a long time. May be no-op when using in-process command
2549   // buffer.
2550   void ReportProgress();
2551 
2552   // Generate a member function prototype for each command in an automated and
2553   // typesafe way.
2554 #define GLES2_CMD_OP(name) \
2555   Error Handle##name(uint32_t immediate_data_size, const volatile void* data);
2556 
2557   GLES2_COMMAND_LIST(GLES2_CMD_OP)
2558 
2559   #undef GLES2_CMD_OP
2560 
2561   // The GL context this decoder renders to on behalf of the client.
2562   scoped_refptr<gl::GLSurface> surface_;
2563   scoped_refptr<gl::GLContext> context_;
2564 
2565   // The ContextGroup for this decoder uses to track resources.
2566   scoped_refptr<ContextGroup> group_;
2567 
2568   DebugMarkerManager debug_marker_manager_;
2569   Logger logger_;
2570 
2571   std::unique_ptr<ErrorState> error_state_;
2572 
2573   // All the state for this context.
2574   ContextState state_;
2575 
2576   std::unique_ptr<TransformFeedbackManager> transform_feedback_manager_;
2577 
2578   // Current width and height of the offscreen frame buffer.
2579   gfx::Size offscreen_size_;
2580 
2581   // Util to help with GL.
2582   GLES2Util util_;
2583 
2584   // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
2585   GLuint attrib_0_buffer_id_;
2586 
2587   // The value currently in attrib_0.
2588   Vec4 attrib_0_value_;
2589 
2590   // Whether or not the attrib_0 buffer holds the attrib_0_value.
2591   bool attrib_0_buffer_matches_value_;
2592 
2593   // The size of attrib 0.
2594   GLsizei attrib_0_size_;
2595 
2596   // The buffer used to simulate GL_FIXED attribs.
2597   GLuint fixed_attrib_buffer_id_;
2598 
2599   // The size of fiixed attrib buffer.
2600   GLsizei fixed_attrib_buffer_size_;
2601 
2602   // The offscreen frame buffer that the client renders to. With EGL, the
2603   // depth and stencil buffers are separate. With regular GL there is a single
2604   // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
2605   // offscreen_target_stencil_render_buffer_ is unused.
2606   std::unique_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
2607   std::unique_ptr<BackTexture> offscreen_target_color_texture_;
2608   std::unique_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
2609   std::unique_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
2610   std::unique_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
2611 
2612   // The format of the texture or renderbuffer backing the offscreen
2613   // framebuffer. Also the format of the texture backing the saved offscreen
2614   // framebuffer.
2615   GLenum offscreen_target_color_format_;
2616 
2617   GLenum offscreen_target_depth_format_;
2618   GLenum offscreen_target_stencil_format_;
2619   GLsizei offscreen_target_samples_;
2620   GLboolean offscreen_target_buffer_preserved_;
2621 
2622   GLint max_offscreen_framebuffer_size_;
2623 
2624   // Whether or not offscreen color buffers exist in front/back pairs that
2625   // can be swapped.
2626   GLboolean offscreen_single_buffer_;
2627 
2628   // The saved copy of the backbuffer after a call to SwapBuffers.
2629   std::unique_ptr<BackTexture> offscreen_saved_color_texture_;
2630 
2631   // For simplicity, |offscreen_saved_color_texture_| is always bound to
2632   // |offscreen_saved_frame_buffer_|.
2633   std::unique_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
2634 
2635   // When a client requests ownership of the swapped front buffer, all
2636   // information is saved in this structure, and |in_use| is set to true. When a
2637   // client releases ownership, |in_use| is set to false.
2638   //
2639   // An instance of this struct, with |in_use| = false may be reused instead of
2640   // making a new BackTexture.
2641   struct SavedBackTexture {
2642     std::unique_ptr<BackTexture> back_texture;
2643     bool in_use;
2644   };
2645   std::vector<SavedBackTexture> saved_back_textures_;
2646 
2647   // If there's a SavedBackTexture that's not in use, takes that. Otherwise,
2648   // generates a new back texture.
2649   void CreateBackTexture();
2650   size_t create_back_texture_count_for_test_ = 0;
2651 
2652   // Releases all saved BackTextures that are not in use by a client.
2653   void ReleaseNotInUseBackTextures();
2654 
2655   // Releases all saved BackTextures.
2656   void ReleaseAllBackTextures(bool have_context);
2657 
2658   size_t GetSavedBackTextureCountForTest() override;
2659   size_t GetCreatedBackTextureCountForTest() override;
2660 
2661   // The copy that is used as the destination for multi-sample resolves.
2662   std::unique_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
2663   std::unique_ptr<BackTexture> offscreen_resolved_color_texture_;
2664   GLenum offscreen_saved_color_format_;
2665 
2666   // Whether the client requested an offscreen buffer with an alpha channel.
2667   bool offscreen_buffer_should_have_alpha_;
2668 
2669   std::unique_ptr<FramebufferManager> framebuffer_manager_;
2670 
2671   std::unique_ptr<GLES2QueryManager> query_manager_;
2672 
2673   std::unique_ptr<GpuFenceManager> gpu_fence_manager_;
2674 
2675   std::unique_ptr<MultiDrawManager> multi_draw_manager_;
2676 
2677   std::unique_ptr<VertexArrayManager> vertex_array_manager_;
2678 
2679   base::flat_set<scoped_refptr<Buffer>> writes_submitted_but_not_completed_;
2680 
2681   // The format of the back buffer_
2682   GLenum back_buffer_color_format_;
2683   bool back_buffer_has_depth_;
2684   bool back_buffer_has_stencil_;
2685 
2686   // Tracks read buffer and draw buffer for backbuffer, whether it's onscreen
2687   // or offscreen.
2688   // TODO(zmo): when ES3 APIs are exposed to Nacl, make sure read_buffer_
2689   // setting is set correctly when SwapBuffers().
2690   GLenum back_buffer_read_buffer_;
2691   GLenum back_buffer_draw_buffer_;
2692 
2693   bool surfaceless_;
2694 
2695   // Backbuffer attachments that are currently undefined.
2696   uint32_t backbuffer_needs_clear_bits_;
2697 
2698   uint64_t swaps_since_resize_;
2699 
2700   // The current decoder error communicates the decoder error through command
2701   // processing functions that do not return the error value. Should be set only
2702   // if not returning an error.
2703   error::Error current_decoder_error_;
2704 
2705   bool has_fragment_precision_high_ = false;
2706   scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
2707   scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
2708 
2709   // Cached from ContextGroup
2710   const Validators* validators_;
2711   scoped_refptr<FeatureInfo> feature_info_;
2712 
2713   int frame_number_;
2714 
2715   // Number of commands remaining to be processed in DoCommands().
2716   int commands_to_process_;
2717 
2718   bool context_was_lost_;
2719   bool reset_by_robustness_extension_;
2720   bool supports_post_sub_buffer_;
2721   bool supports_swap_buffers_with_bounds_;
2722   bool supports_commit_overlay_planes_;
2723   bool supports_async_swap_;
2724   bool supports_dc_layers_ = false;
2725 
2726   // These flags are used to override the state of the shared feature_info_
2727   // member.  Because the same FeatureInfo instance may be shared among many
2728   // contexts, the assumptions on the availablity of extensions in WebGL
2729   // contexts may be broken.  These flags override the shared state to preserve
2730   // WebGL semantics.
2731   bool derivatives_explicitly_enabled_;
2732   bool fbo_render_mipmap_explicitly_enabled_;
2733   bool frag_depth_explicitly_enabled_;
2734   bool draw_buffers_explicitly_enabled_;
2735   bool shader_texture_lod_explicitly_enabled_;
2736   bool multi_draw_explicitly_enabled_;
2737   bool draw_instanced_base_vertex_base_instance_explicitly_enabled_;
2738   bool multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_;
2739 
2740   bool compile_shader_always_succeeds_;
2741 
2742   // An optional behaviour to lose the context and group when OOM.
2743   bool lose_context_when_out_of_memory_;
2744 
2745   // Forces the backbuffer to use native GMBs rather than a TEXTURE_2D texture.
2746   bool should_use_native_gmb_for_backbuffer_;
2747 
2748   // Log extra info.
2749   bool service_logging_;
2750 
2751   std::unique_ptr<CopyTexImageResourceManager> copy_tex_image_blit_;
2752   std::unique_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_chromium_;
2753   std::unique_ptr<SRGBConverter> srgb_converter_;
2754   std::unique_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
2755 
2756   // Cached values of the currently assigned viewport dimensions.
2757   GLsizei viewport_max_width_;
2758   GLsizei viewport_max_height_;
2759 
2760   // Cached value for the number of stencil bits for the default framebuffer.
2761   GLint num_stencil_bits_;
2762 
2763   // States related to each manager.
2764   DecoderTextureState texture_state_;
2765   DecoderFramebufferState framebuffer_state_;
2766 
2767   std::unique_ptr<GPUTracer> gpu_tracer_;
2768   std::unique_ptr<GPUStateTracer> gpu_state_tracer_;
2769   const unsigned char* gpu_decoder_category_;
2770   int gpu_trace_level_;
2771   bool gpu_trace_commands_;
2772   bool gpu_debug_commands_;
2773 
2774   base::queue<FenceCallback> pending_readpixel_fences_;
2775 
2776   // After a second fence is inserted, both the GpuChannelMessageQueue and
2777   // CommandExecutor are descheduled. Once the first fence has completed, both
2778   // get rescheduled.
2779   std::vector<std::unique_ptr<gl::GLFence>> deschedule_until_finished_fences_;
2780 
2781   // Used to validate multisample renderbuffers if needed
2782   typedef std::unordered_map<GLenum, GLuint> TextureMap;
2783   TextureMap validation_textures_;
2784   GLuint validation_fbo_multisample_;
2785   GLuint validation_fbo_;
2786 
2787   typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
2788       uint32_t immediate_data_size,
2789       const volatile void* data);
2790 
2791   // A struct to hold info about each command.
2792   struct CommandInfo {
2793     CmdHandler cmd_handler;
2794     uint8_t arg_flags;   // How to handle the arguments for this command
2795     uint8_t cmd_flags;   // How to handle this command
2796     uint16_t arg_count;  // How many arguments are expected for this command.
2797   };
2798 
2799   // A table of CommandInfo for all the commands.
2800   static const CommandInfo command_info[kNumCommands - kFirstGLES2Command];
2801 
2802   // Most recent generation of the TextureManager.  If this no longer matches
2803   // the current generation when our context becomes current, then we'll rebind
2804   // all the textures to stay up to date with Texture::service_id() changes.
2805   uint32_t texture_manager_service_id_generation_;
2806 
2807   bool force_shader_name_hashing_for_test;
2808 
2809   GLfloat line_width_range_[2] = {0.0, 1.0};
2810 
2811   SamplerState default_sampler_state_;
2812 
2813   std::unique_ptr<CALayerSharedState> ca_layer_shared_state_;
2814 
2815   // All currently outstanding AbstractTextures that we've created.
2816   std::set<ValidatingAbstractTextureImpl*> abstract_textures_;
2817 
2818   // Set of texture refs that are pending destruction, at some point in the
2819   // future when our context is current.
2820   std::set<scoped_refptr<TextureRef>> texture_refs_pending_destruction_;
2821 
2822   base::WeakPtrFactory<GLES2DecoderImpl> weak_ptr_factory_{this};
2823 
2824   DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
2825 };
2826 
2827 constexpr GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
2828 #define GLES2_CMD_OP(name)                                   \
2829   {                                                          \
2830     &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags,  \
2831         cmds::name::cmd_flags,                               \
2832         sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
2833   }                                                          \
2834   , /* NOLINT */
2835     GLES2_COMMAND_LIST(GLES2_CMD_OP)
2836 #undef GLES2_CMD_OP
2837 };
2838 
ScopedGLErrorSuppressor(const char * function_name,ErrorState * error_state)2839 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
2840     const char* function_name, ErrorState* error_state)
2841     : function_name_(function_name),
2842       error_state_(error_state) {
2843   ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
2844 }
2845 
~ScopedGLErrorSuppressor()2846 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
2847   ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
2848 }
2849 
RestoreCurrentTextureBindings(ContextState * state,GLenum target,GLuint texture_unit)2850 static void RestoreCurrentTextureBindings(ContextState* state,
2851                                           GLenum target,
2852                                           GLuint texture_unit) {
2853   DCHECK(!state->texture_units.empty());
2854   DCHECK_LT(texture_unit, state->texture_units.size());
2855   TextureUnit& info = state->texture_units[texture_unit];
2856   GLuint last_id;
2857   TextureRef* texture_ref = info.GetInfoForTarget(target);
2858   if (texture_ref) {
2859     last_id = texture_ref->service_id();
2860   } else {
2861     last_id = 0;
2862   }
2863 
2864   state->api()->glBindTextureFn(target, last_id);
2865 }
2866 
ScopedTextureBinder(ContextState * state,ErrorState * error_state,GLuint id,GLenum target)2867 ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
2868                                          ErrorState* error_state,
2869                                          GLuint id,
2870                                          GLenum target)
2871     : state_(state), error_state_(error_state), target_(target) {
2872   ScopedGLErrorSuppressor suppressor("ScopedTextureBinder::ctor", error_state_);
2873 
2874   // TODO(apatrick): Check if there are any other states that need to be reset
2875   // before binding a new texture.
2876   auto* api = state->api();
2877   api->glActiveTextureFn(GL_TEXTURE0);
2878   api->glBindTextureFn(target, id);
2879 }
2880 
~ScopedTextureBinder()2881 ScopedTextureBinder::~ScopedTextureBinder() {
2882   ScopedGLErrorSuppressor suppressor("ScopedTextureBinder::dtor", error_state_);
2883   RestoreCurrentTextureBindings(state_, target_, 0);
2884   state_->RestoreActiveTexture();
2885 }
2886 
ScopedRenderBufferBinder(ContextState * state,ErrorState * error_state,GLuint id)2887 ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
2888                                                    ErrorState* error_state,
2889                                                    GLuint id)
2890     : state_(state), error_state_(error_state) {
2891   ScopedGLErrorSuppressor suppressor("ScopedRenderBufferBinder::ctor",
2892                                      error_state_);
2893   state->api()->glBindRenderbufferEXTFn(GL_RENDERBUFFER, id);
2894 }
2895 
~ScopedRenderBufferBinder()2896 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
2897   ScopedGLErrorSuppressor suppressor("ScopedRenderBufferBinder::dtor",
2898                                      error_state_);
2899   state_->RestoreRenderbufferBindings();
2900 }
2901 
ScopedFramebufferBinder(GLES2DecoderImpl * decoder,GLuint id)2902 ScopedFramebufferBinder::ScopedFramebufferBinder(GLES2DecoderImpl* decoder,
2903                                                  GLuint id)
2904     : decoder_(decoder) {
2905   ScopedGLErrorSuppressor suppressor("ScopedFramebufferBinder::ctor",
2906                                      decoder_->error_state_.get());
2907   decoder->api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, id);
2908   decoder->OnFboChanged();
2909 }
2910 
~ScopedFramebufferBinder()2911 ScopedFramebufferBinder::~ScopedFramebufferBinder() {
2912   ScopedGLErrorSuppressor suppressor("ScopedFramebufferBinder::dtor",
2913                                      decoder_->error_state_.get());
2914   decoder_->RestoreCurrentFramebufferBindings();
2915 }
2916 
ScopedResolvedFramebufferBinder(GLES2DecoderImpl * decoder,bool enforce_internal_framebuffer,bool internal)2917 ScopedResolvedFramebufferBinder::ScopedResolvedFramebufferBinder(
2918     GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
2919     : decoder_(decoder) {
2920   resolve_and_bind_ = (
2921       decoder_->offscreen_target_frame_buffer_.get() &&
2922       decoder_->IsOffscreenBufferMultisampled() &&
2923       (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2924        enforce_internal_framebuffer));
2925   if (!resolve_and_bind_)
2926     return;
2927   auto* api = decoder_->api();
2928   ScopedGLErrorSuppressor suppressor("ScopedResolvedFramebufferBinder::ctor",
2929                                      decoder_->error_state_.get());
2930 
2931   // On old AMD GPUs on macOS, glColorMask doesn't work correctly for
2932   // multisampled renderbuffers and the alpha channel can be overwritten. This
2933   // workaround clears the alpha channel before resolving.
2934   bool alpha_channel_needs_clear =
2935       decoder_->should_use_native_gmb_for_backbuffer_ &&
2936       !decoder_->offscreen_buffer_should_have_alpha_ &&
2937       decoder_->ChromiumImageNeedsRGBEmulation() &&
2938       decoder_->workarounds()
2939           .disable_multisampling_color_mask_usage;
2940   if (alpha_channel_needs_clear) {
2941     api->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER_EXT,
2942                                 decoder_->offscreen_target_frame_buffer_->id());
2943     decoder_->state_.SetDeviceColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
2944     decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
2945     decoder->ClearDeviceWindowRectangles();
2946     api->glClearColorFn(0, 0, 0, 1);
2947     api->glClearFn(GL_COLOR_BUFFER_BIT);
2948     decoder_->RestoreClearState();
2949   }
2950 
2951   api->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER_EXT,
2952                               decoder_->offscreen_target_frame_buffer_->id());
2953   GLuint targetid;
2954   if (internal) {
2955     if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2956       decoder_->offscreen_resolved_frame_buffer_.reset(
2957           new BackFramebuffer(decoder_));
2958       decoder_->offscreen_resolved_frame_buffer_->Create();
2959       decoder_->offscreen_resolved_color_texture_.reset(
2960           new BackTexture(decoder));
2961       decoder_->offscreen_resolved_color_texture_->Create();
2962 
2963       DCHECK(decoder_->offscreen_saved_color_format_);
2964       decoder_->offscreen_resolved_color_texture_->AllocateStorage(
2965           decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2966           false);
2967       decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2968           decoder_->offscreen_resolved_color_texture_.get());
2969       if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2970           GL_FRAMEBUFFER_COMPLETE) {
2971         LOG(ERROR) << "ScopedResolvedFramebufferBinder failed "
2972                    << "because offscreen resolved FBO was incomplete.";
2973         return;
2974       }
2975     }
2976     targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2977   } else {
2978     targetid = decoder_->offscreen_saved_frame_buffer_->id();
2979   }
2980   api->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER_EXT, targetid);
2981   const int width = decoder_->offscreen_size_.width();
2982   const int height = decoder_->offscreen_size_.height();
2983   decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
2984   decoder->ClearDeviceWindowRectangles();
2985   decoder->api()->glBlitFramebufferFn(0, 0, width, height, 0, 0, width, height,
2986                                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2987   api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, targetid);
2988 }
2989 
~ScopedResolvedFramebufferBinder()2990 ScopedResolvedFramebufferBinder::~ScopedResolvedFramebufferBinder() {
2991   if (!resolve_and_bind_)
2992     return;
2993 
2994   ScopedGLErrorSuppressor suppressor("ScopedResolvedFramebufferBinder::dtor",
2995                                      decoder_->error_state_.get());
2996   decoder_->RestoreCurrentFramebufferBindings();
2997   if (decoder_->state_.enable_flags.scissor_test) {
2998     decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
2999     decoder_->RestoreDeviceWindowRectangles();
3000   }
3001 }
3002 
ScopedFramebufferCopyBinder(GLES2DecoderImpl * decoder,GLint x,GLint y,GLint width,GLint height)3003 ScopedFramebufferCopyBinder::ScopedFramebufferCopyBinder(
3004     GLES2DecoderImpl* decoder,
3005     GLint x,
3006     GLint y,
3007     GLint width,
3008     GLint height)
3009     : decoder_(decoder) {
3010   const Framebuffer::Attachment* attachment =
3011       decoder->framebuffer_state_.bound_read_framebuffer.get()
3012           ->GetReadBufferAttachment();
3013   DCHECK(attachment);
3014   auto* api = decoder_->api();
3015   api->glGenTexturesFn(1, &temp_texture_);
3016 
3017   ScopedTextureBinder texture_binder(&decoder->state_,
3018                                      decoder->error_state_.get(), temp_texture_,
3019                                      GL_TEXTURE_2D);
3020   if (width == 0 || height == 0) {
3021     // Copy the whole framebuffer if a rectangle isn't specified.
3022     api->glCopyTexImage2DFn(GL_TEXTURE_2D, 0, attachment->internal_format(), 0,
3023                             0, attachment->width(), attachment->height(), 0);
3024   } else {
3025     api->glCopyTexImage2DFn(GL_TEXTURE_2D, 0, attachment->internal_format(), x,
3026                             y, width, height, 0);
3027   }
3028 
3029   api->glGenFramebuffersEXTFn(1, &temp_framebuffer_);
3030   framebuffer_binder_ =
3031       std::make_unique<ScopedFramebufferBinder>(decoder, temp_framebuffer_);
3032   api->glFramebufferTexture2DEXTFn(GL_READ_FRAMEBUFFER_EXT,
3033                                    GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3034                                    temp_texture_, 0);
3035   api->glReadBufferFn(GL_COLOR_ATTACHMENT0);
3036 }
3037 
~ScopedFramebufferCopyBinder()3038 ScopedFramebufferCopyBinder::~ScopedFramebufferCopyBinder() {
3039   auto* api = decoder_->api();
3040   framebuffer_binder_.reset();
3041   api->glDeleteFramebuffersEXTFn(1, &temp_framebuffer_);
3042   api->glDeleteTexturesFn(1, &temp_texture_);
3043   api->glReadBufferFn(
3044       decoder_->framebuffer_state_.bound_read_framebuffer.get()->read_buffer());
3045 }
3046 
ScopedPixelUnpackState(ContextState * state)3047 ScopedPixelUnpackState::ScopedPixelUnpackState(ContextState* state)
3048     : state_(state) {
3049   DCHECK(state_);
3050   state_->PushTextureUnpackState();
3051 }
3052 
~ScopedPixelUnpackState()3053 ScopedPixelUnpackState::~ScopedPixelUnpackState() {
3054   state_->RestoreUnpackState();
3055 }
3056 
BackTexture(GLES2DecoderImpl * decoder)3057 BackTexture::BackTexture(GLES2DecoderImpl* decoder)
3058     : memory_tracker_(decoder->memory_tracker()),
3059       bytes_allocated_(0),
3060       decoder_(decoder) {
3061   DCHECK(!decoder_->should_use_native_gmb_for_backbuffer_ ||
3062          decoder_->GetContextGroup()->image_factory());
3063 }
3064 
~BackTexture()3065 BackTexture::~BackTexture() {
3066   // This does not destroy the render texture because that would require that
3067   // the associated GL context was current. Just check that it was explicitly
3068   // destroyed.
3069   DCHECK_EQ(id(), 0u);
3070   DCHECK(!image_.get());
3071 }
3072 
api() const3073 inline gl::GLApi* BackTexture::api() const {
3074   return decoder_->api();
3075 }
3076 
Create()3077 void BackTexture::Create() {
3078   DCHECK_EQ(id(), 0u);
3079   ScopedGLErrorSuppressor suppressor("BackTexture::Create",
3080                                      decoder_->error_state_.get());
3081   GLuint id;
3082   api()->glGenTexturesFn(1, &id);
3083 
3084   GLenum target = Target();
3085   ScopedTextureBinder binder(&decoder_->state_, decoder_->error_state_.get(),
3086                              id, target);
3087 
3088   // No client id is necessary because this texture will never be directly
3089   // accessed by a client, only indirectly via a mailbox.
3090   texture_ref_ = TextureRef::Create(decoder_->texture_manager(), 0, id);
3091   decoder_->texture_manager()->SetTarget(texture_ref_.get(), target);
3092   decoder_->texture_manager()->SetParameteri(
3093       "BackTexture::Create", decoder_->error_state_.get(), texture_ref_.get(),
3094       GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3095   decoder_->texture_manager()->SetParameteri(
3096       "BackTexture::Create", decoder_->error_state_.get(), texture_ref_.get(),
3097       GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3098   decoder_->texture_manager()->SetParameteri(
3099       "BackTexture::Create", decoder_->error_state_.get(), texture_ref_.get(),
3100       GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3101   decoder_->texture_manager()->SetParameteri(
3102       "BackTexture::Create", decoder_->error_state_.get(), texture_ref_.get(),
3103       GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3104 }
3105 
AllocateStorage(const gfx::Size & size,GLenum format,bool zero)3106 bool BackTexture::AllocateStorage(
3107     const gfx::Size& size, GLenum format, bool zero) {
3108   DCHECK_NE(id(), 0u);
3109   ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
3110                                      decoder_->error_state_.get());
3111   ScopedTextureBinder binder(&decoder_->state_, decoder_->error_state_.get(),
3112                              id(), Target());
3113   uint32_t image_size = 0;
3114   GLES2Util::ComputeImageDataSizes(size.width(), size.height(), 1, format,
3115                                    GL_UNSIGNED_BYTE, 8, &image_size, nullptr,
3116                                    nullptr);
3117 
3118   bool success = false;
3119   size_ = size;
3120   if (decoder_->should_use_native_gmb_for_backbuffer_) {
3121     DestroyNativeGpuMemoryBuffer(true);
3122     success = AllocateNativeGpuMemoryBuffer(size, format, zero);
3123   } else {
3124     {
3125       // Add extra scope to destroy zero_data and the object it owns right
3126       // after its usage.
3127       std::unique_ptr<char[]> zero_data;
3128       if (zero) {
3129         zero_data.reset(new char[image_size]);
3130         memset(zero_data.get(), 0, image_size);
3131       }
3132 
3133       api()->glTexImage2DFn(Target(),
3134                             0,  // mip level
3135                             format, size.width(), size.height(),
3136                             0,  // border
3137                             format, GL_UNSIGNED_BYTE, zero_data.get());
3138     }
3139 
3140     decoder_->texture_manager()->SetLevelInfo(
3141         texture_ref_.get(), Target(),
3142         0,  // level
3143         GL_RGBA, size.width(), size.height(),
3144         1,  // depth
3145         0,  // border
3146         GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(size));
3147     success = api()->glGetErrorFn() == GL_NO_ERROR;
3148   }
3149 
3150   if (success) {
3151     memory_tracker_.TrackMemFree(bytes_allocated_);
3152     bytes_allocated_ = image_size;
3153     memory_tracker_.TrackMemAlloc(bytes_allocated_);
3154   }
3155   return success;
3156 }
3157 
Copy()3158 void BackTexture::Copy() {
3159   DCHECK_NE(id(), 0u);
3160   ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
3161                                      decoder_->error_state_.get());
3162   ScopedTextureBinder binder(&decoder_->state_, decoder_->error_state_.get(),
3163                              id(), Target());
3164   api()->glCopyTexSubImage2DFn(Target(),
3165                                0,  // level
3166                                0, 0, 0, 0, size_.width(), size_.height());
3167 }
3168 
Destroy()3169 void BackTexture::Destroy() {
3170   if (image_) {
3171     DCHECK(texture_ref_);
3172     ScopedTextureBinder binder(&decoder_->state_, decoder_->error_state_.get(),
3173                                id(), Target());
3174     DestroyNativeGpuMemoryBuffer(true);
3175   }
3176 
3177   if (texture_ref_) {
3178     ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
3179                                        decoder_->error_state_.get());
3180     texture_ref_ = nullptr;
3181   }
3182   memory_tracker_.TrackMemFree(bytes_allocated_);
3183   bytes_allocated_ = 0;
3184 }
3185 
Invalidate()3186 void BackTexture::Invalidate() {
3187   if (image_) {
3188     DestroyNativeGpuMemoryBuffer(false);
3189     image_ = nullptr;
3190   }
3191   if (texture_ref_) {
3192     texture_ref_->ForceContextLost();
3193     texture_ref_ = nullptr;
3194   }
3195   memory_tracker_.TrackMemFree(bytes_allocated_);
3196   bytes_allocated_ = 0;
3197 }
3198 
Target()3199 GLenum BackTexture::Target() {
3200   return decoder_->should_use_native_gmb_for_backbuffer_
3201              ? decoder_->GetContextGroup()
3202                    ->image_factory()
3203                    ->RequiredTextureType()
3204              : GL_TEXTURE_2D;
3205 }
3206 
AllocateNativeGpuMemoryBuffer(const gfx::Size & size,GLenum format,bool zero)3207 bool BackTexture::AllocateNativeGpuMemoryBuffer(const gfx::Size& size,
3208                                                 GLenum format,
3209                                                 bool zero) {
3210   if (!decoder_->GetContextGroup()
3211            ->image_factory()
3212            ->SupportsCreateAnonymousImage())
3213     return false;
3214 
3215   DCHECK(format == GL_RGB || format == GL_RGBA);
3216   bool is_cleared = false;
3217   gfx::BufferFormat buffer_format = gfx::BufferFormat::RGBA_8888;
3218   if (format == GL_RGB) {
3219 #if defined(USE_OZONE)
3220     // BGRX format is preferred for Ozone as it matches the format used by the
3221     // buffer queue and is as a result guaranteed to work on all devices.
3222     // TODO(reveman): Define this format in one place instead of having to
3223     // duplicate BGRX_8888.
3224     buffer_format = gfx::BufferFormat::BGRX_8888;
3225 #else
3226     buffer_format = gfx::BufferFormat::RGBX_8888;
3227 #endif
3228   }
3229   scoped_refptr<gl::GLImage> image =
3230       decoder_->GetContextGroup()->image_factory()->CreateAnonymousImage(
3231           size, buffer_format, gfx::BufferUsage::SCANOUT,
3232           gpu::kNullSurfaceHandle, &is_cleared);
3233   if (!image)
3234     return false;
3235   DCHECK_EQ(format, image->GetDataFormat());
3236   if (!image->BindTexImage(Target()))
3237     return false;
3238 
3239   image_ = image;
3240   decoder_->texture_manager()->SetLevelInfo(
3241       texture_ref_.get(), Target(), 0, image_->GetInternalFormat(),
3242       size.width(), size.height(), 1, 0, image->GetDataFormat(),
3243       image->GetDataType(), gfx::Rect(size));
3244   decoder_->texture_manager()->SetLevelImage(texture_ref_.get(), Target(), 0,
3245                                              image_.get(), Texture::BOUND);
3246 
3247   // Ignore the zero flag if the alpha channel needs to be cleared for RGB
3248   // emulation.
3249   bool needs_clear_for_rgb_emulation =
3250       !decoder_->offscreen_buffer_should_have_alpha_ &&
3251       decoder_->ChromiumImageNeedsRGBEmulation();
3252   if (!is_cleared || zero || needs_clear_for_rgb_emulation) {
3253     GLuint fbo;
3254     api()->glGenFramebuffersEXTFn(1, &fbo);
3255     {
3256       ScopedFramebufferBinder binder(decoder_, fbo);
3257       api()->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3258                                          Target(), id(), 0);
3259       api()->glClearColorFn(0, 0, 0, decoder_->BackBufferAlphaClearColor());
3260       decoder_->state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3261       decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3262       decoder_->ClearDeviceWindowRectangles();
3263       api()->glClearFn(GL_COLOR_BUFFER_BIT);
3264       decoder_->RestoreClearState();
3265     }
3266     api()->glDeleteFramebuffersEXTFn(1, &fbo);
3267   }
3268   return true;
3269 }
3270 
DestroyNativeGpuMemoryBuffer(bool have_context)3271 void BackTexture::DestroyNativeGpuMemoryBuffer(bool have_context) {
3272   if (image_) {
3273     ScopedGLErrorSuppressor suppressor(
3274         "BackTexture::DestroyNativeGpuMemoryBuffer",
3275         decoder_->error_state_.get());
3276 
3277     image_->ReleaseTexImage(Target());
3278 
3279     decoder_->texture_manager()->SetLevelImage(texture_ref_.get(), Target(), 0,
3280                                                nullptr, Texture::UNBOUND);
3281     image_ = nullptr;
3282   }
3283 }
3284 
BackRenderbuffer(GLES2DecoderImpl * decoder)3285 BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
3286     : decoder_(decoder),
3287       memory_tracker_(decoder->memory_tracker()),
3288       bytes_allocated_(0),
3289       id_(0) {}
3290 
~BackRenderbuffer()3291 BackRenderbuffer::~BackRenderbuffer() {
3292   // This does not destroy the render buffer because that would require that
3293   // the associated GL context was current. Just check that it was explicitly
3294   // destroyed.
3295   DCHECK_EQ(id_, 0u);
3296 }
3297 
api() const3298 inline gl::GLApi* BackRenderbuffer::api() const {
3299   return decoder_->api();
3300 }
3301 
Create()3302 void BackRenderbuffer::Create() {
3303   ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
3304                                      decoder_->error_state_.get());
3305   Destroy();
3306   api()->glGenRenderbuffersEXTFn(1, &id_);
3307 }
3308 
AllocateStorage(const gfx::Size & size,GLenum format,GLsizei samples)3309 bool BackRenderbuffer::AllocateStorage(const gfx::Size& size,
3310                                        GLenum format,
3311                                        GLsizei samples) {
3312   ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage",
3313                                      decoder_->error_state_.get());
3314   ScopedRenderBufferBinder binder(&decoder_->state_,
3315                                   decoder_->error_state_.get(), id_);
3316 
3317   uint32_t estimated_size = 0;
3318   if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
3319           size.width(), size.height(), samples, format, &estimated_size)) {
3320     return false;
3321   }
3322 
3323   // TODO(kainino): This path will not perform RegenerateRenderbufferIfNeeded on
3324   // devices where multisample_renderbuffer_resize_emulation or
3325   // depth_stencil_renderbuffer_resize_emulation is needed.  Thus any code using
3326   // this path (nacl/ppapi?) could encounter issues on those
3327   // devices. RenderbufferStorageMultisampleWithWorkaround should be used
3328   // instead, but can only be used if BackRenderbuffer tracks its renderbuffers
3329   // in the renderbuffer manager instead of manually.  http://crbug.com/731287
3330   decoder_->RenderbufferStorageMultisampleHelper(GL_RENDERBUFFER, samples,
3331                                                  format, size.width(),
3332                                                  size.height(), kDoNotForce);
3333 
3334   bool alpha_channel_needs_clear =
3335       (format == GL_RGBA || format == GL_RGBA8) &&
3336       !decoder_->offscreen_buffer_should_have_alpha_;
3337   if (alpha_channel_needs_clear) {
3338     GLuint fbo;
3339     api()->glGenFramebuffersEXTFn(1, &fbo);
3340     {
3341       ScopedFramebufferBinder frame_binder(decoder_, fbo);
3342       api()->glFramebufferRenderbufferEXTFn(
3343           GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, id_);
3344       api()->glClearColorFn(0, 0, 0, decoder_->BackBufferAlphaClearColor());
3345       decoder_->state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3346       decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3347       decoder_->ClearDeviceWindowRectangles();
3348       api()->glClearFn(GL_COLOR_BUFFER_BIT);
3349       decoder_->RestoreClearState();
3350     }
3351     api()->glDeleteFramebuffersEXTFn(1, &fbo);
3352   }
3353 
3354   bool success = api()->glGetErrorFn() == GL_NO_ERROR;
3355   if (success) {
3356     // Mark the previously allocated bytes as free.
3357     memory_tracker_.TrackMemFree(bytes_allocated_);
3358     bytes_allocated_ = estimated_size;
3359     // Track the newly allocated bytes.
3360     memory_tracker_.TrackMemAlloc(bytes_allocated_);
3361   }
3362   return success;
3363 }
3364 
Destroy()3365 void BackRenderbuffer::Destroy() {
3366   if (id_ != 0) {
3367     ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
3368                                        decoder_->error_state_.get());
3369     api()->glDeleteRenderbuffersEXTFn(1, &id_);
3370     id_ = 0;
3371   }
3372   memory_tracker_.TrackMemFree(bytes_allocated_);
3373   bytes_allocated_ = 0;
3374 }
3375 
Invalidate()3376 void BackRenderbuffer::Invalidate() {
3377   id_ = 0;
3378   memory_tracker_.TrackMemFree(bytes_allocated_);
3379   bytes_allocated_ = 0;
3380 }
3381 
BackFramebuffer(GLES2DecoderImpl * decoder)3382 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
3383     : decoder_(decoder),
3384       id_(0) {
3385 }
3386 
~BackFramebuffer()3387 BackFramebuffer::~BackFramebuffer() {
3388   // This does not destroy the frame buffer because that would require that
3389   // the associated GL context was current. Just check that it was explicitly
3390   // destroyed.
3391   DCHECK_EQ(id_, 0u);
3392 }
3393 
api() const3394 inline gl::GLApi* BackFramebuffer::api() const {
3395   return decoder_->api();
3396 }
3397 
Create()3398 void BackFramebuffer::Create() {
3399   ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
3400                                      decoder_->error_state_.get());
3401   Destroy();
3402   api()->glGenFramebuffersEXTFn(1, &id_);
3403 }
3404 
AttachRenderTexture(BackTexture * texture)3405 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
3406   DCHECK_NE(id_, 0u);
3407   ScopedGLErrorSuppressor suppressor("BackFramebuffer::AttachRenderTexture",
3408                                      decoder_->error_state_.get());
3409   ScopedFramebufferBinder binder(decoder_, id_);
3410   GLuint attach_id = texture ? texture->id() : 0;
3411   api()->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3412                                      texture->Target(), attach_id, 0);
3413 }
3414 
AttachRenderBuffer(GLenum target,BackRenderbuffer * render_buffer)3415 void BackFramebuffer::AttachRenderBuffer(GLenum target,
3416                                          BackRenderbuffer* render_buffer) {
3417   DCHECK_NE(id_, 0u);
3418   ScopedGLErrorSuppressor suppressor("BackFramebuffer::AttachRenderBuffer",
3419                                      decoder_->error_state_.get());
3420   ScopedFramebufferBinder binder(decoder_, id_);
3421   GLuint attach_id = render_buffer ? render_buffer->id() : 0;
3422   api()->glFramebufferRenderbufferEXTFn(GL_FRAMEBUFFER, target, GL_RENDERBUFFER,
3423                                         attach_id);
3424 }
3425 
Destroy()3426 void BackFramebuffer::Destroy() {
3427   if (id_ != 0) {
3428     ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
3429                                        decoder_->error_state_.get());
3430     api()->glDeleteFramebuffersEXTFn(1, &id_);
3431     id_ = 0;
3432   }
3433 }
3434 
Invalidate()3435 void BackFramebuffer::Invalidate() {
3436   id_ = 0;
3437 }
3438 
CheckStatus()3439 GLenum BackFramebuffer::CheckStatus() {
3440   DCHECK_NE(id_, 0u);
3441   ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
3442                                      decoder_->error_state_.get());
3443   ScopedFramebufferBinder binder(decoder_, id_);
3444   return api()->glCheckFramebufferStatusEXTFn(GL_FRAMEBUFFER);
3445 }
3446 
Create(DecoderClient * client,CommandBufferServiceBase * command_buffer_service,Outputter * outputter,ContextGroup * group)3447 GLES2Decoder* GLES2Decoder::Create(
3448     DecoderClient* client,
3449     CommandBufferServiceBase* command_buffer_service,
3450     Outputter* outputter,
3451     ContextGroup* group) {
3452   if (group->use_passthrough_cmd_decoder()) {
3453     return new GLES2DecoderPassthroughImpl(client, command_buffer_service,
3454                                            outputter, group);
3455   }
3456   return new GLES2DecoderImpl(client, command_buffer_service, outputter, group);
3457 }
3458 
GLES2DecoderImpl(DecoderClient * client,CommandBufferServiceBase * command_buffer_service,Outputter * outputter,ContextGroup * group)3459 GLES2DecoderImpl::GLES2DecoderImpl(
3460     DecoderClient* client,
3461     CommandBufferServiceBase* command_buffer_service,
3462     Outputter* outputter,
3463     ContextGroup* group)
3464     : GLES2Decoder(client, command_buffer_service, outputter),
3465       group_(group),
3466       logger_(&debug_marker_manager_,
3467               base::BindRepeating(&DecoderClient::OnConsoleMessage,
3468                                   base::Unretained(client),
3469                                   0),
3470               group->gpu_preferences().disable_gl_error_limit),
3471       error_state_(ErrorState::Create(this, &logger_)),
3472       state_(group_->feature_info()),
3473       attrib_0_buffer_id_(0),
3474       attrib_0_buffer_matches_value_(true),
3475       attrib_0_size_(0),
3476       fixed_attrib_buffer_id_(0),
3477       fixed_attrib_buffer_size_(0),
3478       offscreen_target_color_format_(0),
3479       offscreen_target_depth_format_(0),
3480       offscreen_target_stencil_format_(0),
3481       offscreen_target_samples_(0),
3482       offscreen_target_buffer_preserved_(true),
3483       max_offscreen_framebuffer_size_(0),
3484       offscreen_single_buffer_(false),
3485       offscreen_saved_color_format_(0),
3486       offscreen_buffer_should_have_alpha_(false),
3487       back_buffer_color_format_(0),
3488       back_buffer_has_depth_(false),
3489       back_buffer_has_stencil_(false),
3490       back_buffer_read_buffer_(GL_BACK),
3491       back_buffer_draw_buffer_(GL_BACK),
3492       surfaceless_(false),
3493       backbuffer_needs_clear_bits_(0),
3494       swaps_since_resize_(0),
3495       current_decoder_error_(error::kNoError),
3496       validators_(group_->feature_info()->validators()),
3497       feature_info_(group_->feature_info()),
3498       frame_number_(0),
3499       context_was_lost_(false),
3500       reset_by_robustness_extension_(false),
3501       supports_post_sub_buffer_(false),
3502       supports_swap_buffers_with_bounds_(false),
3503       supports_commit_overlay_planes_(false),
3504       supports_async_swap_(false),
3505       derivatives_explicitly_enabled_(false),
3506       fbo_render_mipmap_explicitly_enabled_(false),
3507       frag_depth_explicitly_enabled_(false),
3508       draw_buffers_explicitly_enabled_(false),
3509       shader_texture_lod_explicitly_enabled_(false),
3510       multi_draw_explicitly_enabled_(false),
3511       draw_instanced_base_vertex_base_instance_explicitly_enabled_(false),
3512       multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_(false),
3513       compile_shader_always_succeeds_(false),
3514       lose_context_when_out_of_memory_(false),
3515       should_use_native_gmb_for_backbuffer_(false),
3516       service_logging_(
3517           group_->gpu_preferences().enable_gpu_service_logging_gpu),
3518       viewport_max_width_(0),
3519       viewport_max_height_(0),
3520       num_stencil_bits_(0),
3521       texture_state_(group_->feature_info()->workarounds()),
3522       gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
3523           TRACE_DISABLED_BY_DEFAULT("gpu.decoder"))),
3524       gpu_trace_level_(2),
3525       gpu_trace_commands_(false),
3526       gpu_debug_commands_(false),
3527       validation_fbo_multisample_(0),
3528       validation_fbo_(0),
3529       texture_manager_service_id_generation_(0),
3530       force_shader_name_hashing_for_test(false) {
3531   DCHECK(client);
3532   DCHECK(group);
3533 }
3534 
3535 GLES2DecoderImpl::~GLES2DecoderImpl() = default;
3536 
AsWeakPtr()3537 base::WeakPtr<DecoderContext> GLES2DecoderImpl::AsWeakPtr() {
3538   return weak_ptr_factory_.GetWeakPtr();
3539 }
3540 
Initialize(const scoped_refptr<gl::GLSurface> & surface,const scoped_refptr<gl::GLContext> & context,bool offscreen,const DisallowedFeatures & disallowed_features,const ContextCreationAttribs & attrib_helper)3541 gpu::ContextResult GLES2DecoderImpl::Initialize(
3542     const scoped_refptr<gl::GLSurface>& surface,
3543     const scoped_refptr<gl::GLContext>& context,
3544     bool offscreen,
3545     const DisallowedFeatures& disallowed_features,
3546     const ContextCreationAttribs& attrib_helper) {
3547   TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
3548   DCHECK(context->IsCurrent(surface.get()));
3549   DCHECK(!context_.get());
3550   state_.set_api(gl::g_current_gl_context);
3551 
3552   surfaceless_ = surface->IsSurfaceless() && !offscreen;
3553 
3554   set_initialized();
3555   // At this point we are partially initialized and must Destroy() in any
3556   // failure case.
3557   DestroyOnFailure destroy_on_failure(this);
3558 
3559   gpu_state_tracer_ = GPUStateTracer::Create(&state_);
3560 
3561   if (group_->gpu_preferences().enable_gpu_debugging)
3562     set_debug(true);
3563 
3564   if (group_->gpu_preferences().enable_gpu_command_logging)
3565     SetLogCommands(true);
3566 
3567   compile_shader_always_succeeds_ =
3568       group_->gpu_preferences().compile_shader_always_succeeds;
3569 
3570   // Take ownership of the context and surface. The surface can be replaced with
3571   // SetSurface.
3572   context_ = context;
3573   surface_ = surface;
3574 
3575   // Set workarounds for the surface.
3576   if (workarounds().rely_on_implicit_sync_for_swap_buffers)
3577     surface_->SetRelyOnImplicitSync();
3578 
3579   if (workarounds().force_gl_flush_on_swap_buffers)
3580     surface_->SetForceGlFlushOnSwapBuffers();
3581 
3582   // Create GPU Tracer for timing values.
3583   gpu_tracer_.reset(new GPUTracer(this));
3584 
3585   if (workarounds().disable_timestamp_queries) {
3586     // Forcing time elapsed query for any GPU Timing Client forces it for all
3587     // clients in the context.
3588     GetGLContext()->CreateGPUTimingClient()->ForceTimeElapsedQuery();
3589   }
3590 
3591   // Save the loseContextWhenOutOfMemory context creation attribute.
3592   lose_context_when_out_of_memory_ =
3593       attrib_helper.lose_context_when_out_of_memory;
3594 
3595   // If the failIfMajorPerformanceCaveat context creation attribute was true
3596   // and we are using a software renderer, fail.
3597   if (attrib_helper.fail_if_major_perf_caveat &&
3598       feature_info_->feature_flags().is_swiftshader_for_webgl) {
3599     // Must not destroy ContextGroup if it is not initialized.
3600     group_ = nullptr;
3601     LOG(ERROR) << "ContextResult::kFatalFailure: "
3602                   "fail_if_major_perf_caveat + swiftshader";
3603     return gpu::ContextResult::kFatalFailure;
3604   }
3605 
3606   // Only create webgl2-compute for passthrough cmd decoder.
3607   if (attrib_helper.context_type == CONTEXT_TYPE_WEBGL2_COMPUTE) {
3608     // Must not destroy ContextGroup if it is not initialized.
3609     group_ = nullptr;
3610     LOG(ERROR)
3611         << "ContextResult::kFatalFailure: "
3612            "webgl2-compute is not supported on validating command decoder.";
3613     return gpu::ContextResult::kFatalFailure;
3614   }
3615 
3616   auto result =
3617       group_->Initialize(this, attrib_helper.context_type, disallowed_features);
3618   if (result != gpu::ContextResult::kSuccess) {
3619     // Must not destroy ContextGroup if it is not initialized.
3620     group_ = nullptr;
3621     return result;
3622   }
3623   CHECK_GL_ERROR();
3624 
3625   should_use_native_gmb_for_backbuffer_ =
3626       attrib_helper.should_use_native_gmb_for_backbuffer;
3627   if (should_use_native_gmb_for_backbuffer_) {
3628     gpu::ImageFactory* image_factory = group_->image_factory();
3629     bool supported = false;
3630     if (image_factory) {
3631       switch (image_factory->RequiredTextureType()) {
3632         case GL_TEXTURE_RECTANGLE_ARB:
3633           supported = feature_info_->feature_flags().arb_texture_rectangle;
3634           break;
3635         case GL_TEXTURE_EXTERNAL_OES:
3636           supported = feature_info_->feature_flags().oes_egl_image_external;
3637           break;
3638         case GL_TEXTURE_2D:
3639           supported = true;
3640           break;
3641         default:
3642           break;
3643       }
3644     }
3645 
3646     if (!supported) {
3647       LOG(ERROR) << "ContextResult::kFatalFailure: "
3648                     "native gmb format not supported";
3649       return gpu::ContextResult::kFatalFailure;
3650     }
3651   }
3652 
3653   // Support for CHROMIUM_texture_storage_image depends on the underlying
3654   // ImageFactory's ability to create anonymous images.
3655   gpu::ImageFactory* image_factory = group_->image_factory();
3656   if (image_factory && image_factory->SupportsCreateAnonymousImage())
3657     feature_info_->EnableCHROMIUMTextureStorageImage();
3658 
3659   // In theory |needs_emulation| needs to be true on Desktop GL 4.1 or lower.
3660   // However, we set it to true everywhere, not to trust drivers to handle
3661   // out-of-bounds buffer accesses.
3662   bool needs_emulation = true;
3663   transform_feedback_manager_.reset(new TransformFeedbackManager(
3664       group_->max_transform_feedback_separate_attribs(), needs_emulation));
3665 
3666   // Register this object as a GPU switching observer.
3667   if (feature_info_->IsWebGLContext()) {
3668     ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
3669   }
3670 
3671   if (feature_info_->IsWebGL2OrES3Context()) {
3672     // Verified in ContextGroup.
3673     DCHECK(feature_info_->IsES3Capable());
3674     feature_info_->EnableES3Validators();
3675 
3676     frag_depth_explicitly_enabled_ = true;
3677     draw_buffers_explicitly_enabled_ = true;
3678     // TODO(zmo): Look into shader_texture_lod_explicitly_enabled_ situation.
3679 
3680     // Create a fake default transform feedback and bind to it.
3681     GLuint default_transform_feedback = 0;
3682     api()->glGenTransformFeedbacksFn(1, &default_transform_feedback);
3683     state_.default_transform_feedback =
3684         transform_feedback_manager_->CreateTransformFeedback(
3685             0, default_transform_feedback);
3686     api()->glBindTransformFeedbackFn(GL_TRANSFORM_FEEDBACK,
3687                                      default_transform_feedback);
3688     state_.bound_transform_feedback = state_.default_transform_feedback.get();
3689     state_.bound_transform_feedback->SetIsBound(true);
3690   }
3691   state_.indexed_uniform_buffer_bindings =
3692       base::MakeRefCounted<gles2::IndexedBufferBindingHost>(
3693           group_->max_uniform_buffer_bindings(), GL_UNIFORM_BUFFER,
3694           needs_emulation,
3695           workarounds().round_down_uniform_bind_buffer_range_size);
3696   state_.indexed_uniform_buffer_bindings->SetIsBound(true);
3697 
3698   state_.InitGenericAttribs(group_->max_vertex_attribs());
3699   vertex_array_manager_.reset(new VertexArrayManager());
3700 
3701   GLuint default_vertex_attrib_service_id = 0;
3702   if (features().native_vertex_array_object) {
3703     api()->glGenVertexArraysOESFn(1, &default_vertex_attrib_service_id);
3704     api()->glBindVertexArrayOESFn(default_vertex_attrib_service_id);
3705   }
3706 
3707   state_.default_vertex_attrib_manager =
3708       CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
3709 
3710   state_.default_vertex_attrib_manager->Initialize(
3711       group_->max_vertex_attribs(),
3712       workarounds().init_vertex_attributes);
3713 
3714   // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
3715   DoBindVertexArrayOES(0);
3716 
3717   framebuffer_manager_.reset(new FramebufferManager(
3718       group_->max_draw_buffers(), group_->max_color_attachments(),
3719       group_->framebuffer_completeness_cache()));
3720   group_->texture_manager()->AddFramebufferManager(framebuffer_manager_.get());
3721 
3722   query_manager_.reset(new GLES2QueryManager(this, feature_info_.get()));
3723 
3724   gpu_fence_manager_.reset(new GpuFenceManager());
3725 
3726   multi_draw_manager_.reset(
3727       new MultiDrawManager(MultiDrawManager::IndexStorageType::Offset));
3728 
3729   util_.set_num_compressed_texture_formats(
3730       validators_->compressed_texture_format.GetValues().size());
3731 
3732   if (!gl_version_info().BehavesLikeGLES()) {
3733     // We have to enable vertex array 0 on GL with compatibility profile or it
3734     // won't render. Note that ES or GL with core profile does not have this
3735     // issue.
3736     state_.vertex_attrib_manager->SetDriverVertexAttribEnabled(0, true);
3737   }
3738   api()->glGenBuffersARBFn(1, &attrib_0_buffer_id_);
3739   api()->glBindBufferFn(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
3740   api()->glVertexAttribPointerFn(0, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
3741   api()->glBindBufferFn(GL_ARRAY_BUFFER, 0);
3742   api()->glGenBuffersARBFn(1, &fixed_attrib_buffer_id_);
3743 
3744   state_.texture_units.resize(group_->max_texture_units());
3745   state_.sampler_units.resize(group_->max_texture_units());
3746   for (uint32_t tt = 0; tt < state_.texture_units.size(); ++tt) {
3747     api()->glActiveTextureFn(GL_TEXTURE0 + tt);
3748     // We want the last bind to be 2D.
3749     TextureRef* ref;
3750     if (features().oes_egl_image_external ||
3751         features().nv_egl_stream_consumer_external) {
3752       ref = texture_manager()->GetDefaultTextureInfo(
3753           GL_TEXTURE_EXTERNAL_OES);
3754       state_.texture_units[tt].bound_texture_external_oes = ref;
3755       api()->glBindTextureFn(GL_TEXTURE_EXTERNAL_OES,
3756                              ref ? ref->service_id() : 0);
3757     }
3758     if (features().arb_texture_rectangle) {
3759       ref = texture_manager()->GetDefaultTextureInfo(
3760           GL_TEXTURE_RECTANGLE_ARB);
3761       state_.texture_units[tt].bound_texture_rectangle_arb = ref;
3762       api()->glBindTextureFn(GL_TEXTURE_RECTANGLE_ARB,
3763                              ref ? ref->service_id() : 0);
3764     }
3765     ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
3766     state_.texture_units[tt].bound_texture_cube_map = ref;
3767     api()->glBindTextureFn(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
3768     ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
3769     state_.texture_units[tt].bound_texture_2d = ref;
3770     api()->glBindTextureFn(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
3771   }
3772   api()->glActiveTextureFn(GL_TEXTURE0);
3773   CHECK_GL_ERROR();
3774 
3775   // cache ALPHA_BITS result for re-use with clear behaviour
3776   GLint alpha_bits = 0;
3777 
3778   if (offscreen) {
3779     offscreen_buffer_should_have_alpha_ = attrib_helper.alpha_size > 0;
3780 
3781     // Whether the offscreen buffer texture should have an alpha channel. Does
3782     // not include logic from workarounds.
3783     bool offscreen_buffer_texture_needs_alpha =
3784         offscreen_buffer_should_have_alpha_ ||
3785         (ChromiumImageNeedsRGBEmulation() &&
3786          attrib_helper.should_use_native_gmb_for_backbuffer);
3787 
3788     if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 &&
3789         features().chromium_framebuffer_multisample) {
3790       // Per ext_framebuffer_multisample spec, need max bound on sample count.
3791       // max_sample_count must be initialized to a sane value.  If
3792       // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
3793       GLint max_sample_count = 0;
3794       api()->glGetIntegervFn(GL_MAX_SAMPLES_EXT, &max_sample_count);
3795       offscreen_target_samples_ = std::min(attrib_helper.samples,
3796                                            max_sample_count);
3797     } else {
3798       offscreen_target_samples_ = 0;
3799     }
3800     offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved;
3801     offscreen_single_buffer_ = attrib_helper.single_buffer;
3802 
3803     if (gl_version_info().is_es) {
3804       const bool rgb8_supported = features().oes_rgb8_rgba8;
3805       // The only available default render buffer formats in GLES2 have very
3806       // little precision.  Don't enable multisampling unless 8-bit render
3807       // buffer formats are available--instead fall back to 8-bit textures.
3808       if (rgb8_supported && offscreen_target_samples_ > 0) {
3809         offscreen_target_color_format_ =
3810             offscreen_buffer_texture_needs_alpha ? GL_RGBA8 : GL_RGB8;
3811       } else {
3812         offscreen_target_samples_ = 0;
3813         offscreen_target_color_format_ =
3814             offscreen_buffer_texture_needs_alpha ||
3815                     workarounds().disable_gl_rgb_format
3816                 ? GL_RGBA
3817                 : GL_RGB;
3818       }
3819 
3820       // ANGLE only supports packed depth/stencil formats, so use it if it is
3821       // available.
3822       const bool depth24_stencil8_supported =
3823           feature_info_->feature_flags().packed_depth24_stencil8;
3824       VLOG(1) << "GL_OES_packed_depth_stencil "
3825               << (depth24_stencil8_supported ? "" : "not ") << "supported.";
3826       if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) &&
3827           depth24_stencil8_supported) {
3828         offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
3829         offscreen_target_stencil_format_ = 0;
3830       } else {
3831         // It may be the case that this depth/stencil combination is not
3832         // supported, but this will be checked later by CheckFramebufferStatus.
3833         offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ?
3834             GL_DEPTH_COMPONENT16 : 0;
3835         offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ?
3836             GL_STENCIL_INDEX8 : 0;
3837       }
3838     } else {
3839       offscreen_target_color_format_ =
3840           offscreen_buffer_texture_needs_alpha ||
3841                   workarounds().disable_gl_rgb_format
3842               ? GL_RGBA
3843               : GL_RGB;
3844 
3845       // If depth is requested at all, use the packed depth stencil format if
3846       // it's available, as some desktop GL drivers don't support any non-packed
3847       // formats for depth attachments.
3848       const bool depth24_stencil8_supported =
3849           feature_info_->feature_flags().packed_depth24_stencil8;
3850       VLOG(1) << "GL_EXT_packed_depth_stencil "
3851               << (depth24_stencil8_supported ? "" : "not ") << "supported.";
3852 
3853       if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) &&
3854           depth24_stencil8_supported) {
3855         offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
3856         offscreen_target_stencil_format_ = 0;
3857       } else {
3858         offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ?
3859             GL_DEPTH_COMPONENT : 0;
3860         offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ?
3861             GL_STENCIL_INDEX : 0;
3862       }
3863     }
3864 
3865     offscreen_saved_color_format_ = offscreen_buffer_texture_needs_alpha ||
3866                                             workarounds().disable_gl_rgb_format
3867                                         ? GL_RGBA
3868                                         : GL_RGB;
3869 
3870     max_offscreen_framebuffer_size_ =
3871         std::min(renderbuffer_manager()->max_renderbuffer_size(),
3872                  texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D));
3873 
3874     gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size;
3875     if (initial_size.IsEmpty()) {
3876       // If we're an offscreen surface with zero width and/or height, set to a
3877       // non-zero size so that we have a complete framebuffer for operations
3878       // like glClear.
3879       // TODO(piman): allow empty framebuffers, similar to
3880       // EGL_KHR_surfaceless_context / GL_OES_surfaceless_context.
3881       initial_size = gfx::Size(1, 1);
3882     }
3883 
3884     state_.viewport_width = initial_size.width();
3885     state_.viewport_height = initial_size.height();
3886   } else {
3887     api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, GetBackbufferServiceId());
3888     // These are NOT if the back buffer has these proprorties. They are
3889     // if we want the command buffer to enforce them regardless of what
3890     // the real backbuffer is assuming the real back buffer gives us more than
3891     // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
3892     // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
3893     // can't do anything about that.
3894 
3895     if (!surfaceless_) {
3896       GLint depth_bits = 0;
3897       GLint stencil_bits = 0;
3898 
3899       bool default_fb = (GetBackbufferServiceId() == 0);
3900 
3901       if (gl_version_info().is_desktop_core_profile) {
3902         api()->glGetFramebufferAttachmentParameterivEXTFn(
3903             GL_FRAMEBUFFER, default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
3904             GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
3905         api()->glGetFramebufferAttachmentParameterivEXTFn(
3906             GL_FRAMEBUFFER, default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
3907             GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
3908         api()->glGetFramebufferAttachmentParameterivEXTFn(
3909             GL_FRAMEBUFFER, default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
3910             GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
3911       } else {
3912         api()->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
3913         api()->glGetIntegervFn(GL_DEPTH_BITS, &depth_bits);
3914         api()->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
3915       }
3916 
3917       // This checks if the user requested RGBA and we have RGBA then RGBA. If
3918       // the user requested RGB then RGB. If the user did not specify a
3919       // preference than use whatever we were given. Same for DEPTH and STENCIL.
3920       back_buffer_color_format_ =
3921           (attrib_helper.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB;
3922       back_buffer_has_depth_ = attrib_helper.depth_size != 0 && depth_bits > 0;
3923       back_buffer_has_stencil_ =
3924           attrib_helper.stencil_size != 0 && stencil_bits > 0;
3925       num_stencil_bits_ = stencil_bits;
3926     } else {
3927       num_stencil_bits_ = attrib_helper.stencil_size;
3928     }
3929 
3930     state_.viewport_width = surface->GetSize().width();
3931     state_.viewport_height = surface->GetSize().height();
3932   }
3933 
3934   // OpenGL ES 2.0 implicitly enables the desktop GL capability
3935   // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
3936   // isn't well documented; it was discovered in the Khronos OpenGL ES
3937   // mailing list archives. It also implicitly enables the desktop GL
3938   // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
3939   // variable in fragment shaders.
3940   if (!gl_version_info().BehavesLikeGLES()) {
3941     api()->glEnableFn(GL_VERTEX_PROGRAM_POINT_SIZE);
3942     api()->glEnableFn(GL_POINT_SPRITE);
3943   } else if (gl_version_info().is_desktop_core_profile) {
3944     // The desktop core profile changed how program point size mode is
3945     // enabled.
3946     api()->glEnableFn(GL_PROGRAM_POINT_SIZE);
3947   }
3948 
3949   // ES3 requires seamless cubemap. ES2 does not.
3950   // However, when ES2 is implemented on top of DX11, seamless cubemap is
3951   // always enabled and there is no way to disable it.
3952   // Therefore, it seems OK to also always enable it on top of Desktop GL for
3953   // both ES2 and ES3 contexts.
3954   if (!workarounds().disable_texture_cube_map_seamless &&
3955       gl_version_info().IsAtLeastGL(3, 2)) {
3956     api()->glEnableFn(GL_TEXTURE_CUBE_MAP_SEAMLESS);
3957   }
3958 
3959   GLint range[2] = {0, 0};
3960   GLint precision = 0;
3961   QueryShaderPrecisionFormat(gl_version_info(), GL_FRAGMENT_SHADER,
3962                              GL_HIGH_FLOAT, range, &precision);
3963   has_fragment_precision_high_ =
3964       PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
3965 
3966   GLint viewport_params[4] = { 0 };
3967   api()->glGetIntegervFn(GL_MAX_VIEWPORT_DIMS, viewport_params);
3968   viewport_max_width_ = viewport_params[0];
3969   viewport_max_height_ = viewport_params[1];
3970 
3971   api()->glGetFloatvFn(GL_ALIASED_LINE_WIDTH_RANGE, line_width_range_);
3972   state_.SetLineWidthBounds(line_width_range_[0], line_width_range_[1]);
3973 
3974   if (feature_info_->feature_flags().ext_window_rectangles) {
3975     GLint max_window_rectangles = -1;
3976     api()->glGetIntegervFn(GL_MAX_WINDOW_RECTANGLES_EXT,
3977                            &max_window_rectangles);
3978     state_.SetMaxWindowRectangles(max_window_rectangles);
3979   }
3980 
3981   state_.scissor_width = state_.viewport_width;
3982   state_.scissor_height = state_.viewport_height;
3983 
3984   // Set all the default state because some GL drivers get it wrong.
3985   state_.InitCapabilities(nullptr);
3986   state_.InitState(nullptr);
3987 
3988   // Default state must be set before offscreen resources can be created.
3989   if (offscreen) {
3990     // Create the target frame buffer. This is the one that the client renders
3991     // directly to.
3992     offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
3993     offscreen_target_frame_buffer_->Create();
3994     // Due to GLES2 format limitations, either the color texture (for
3995     // non-multisampling) or the color render buffer (for multisampling) will be
3996     // attached to the offscreen frame buffer.  The render buffer has more
3997     // limited formats available to it, but the texture can't do multisampling.
3998     if (IsOffscreenBufferMultisampled()) {
3999       offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
4000       offscreen_target_color_render_buffer_->Create();
4001     } else {
4002       offscreen_target_color_texture_.reset(new BackTexture(this));
4003       offscreen_target_color_texture_->Create();
4004     }
4005     offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
4006     offscreen_target_depth_render_buffer_->Create();
4007     offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
4008     offscreen_target_stencil_render_buffer_->Create();
4009 
4010     if (!offscreen_single_buffer_) {
4011       // Create the saved offscreen texture. The target frame buffer is copied
4012       // here when SwapBuffers is called.
4013       offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
4014       offscreen_saved_frame_buffer_->Create();
4015       offscreen_saved_color_texture_.reset(new BackTexture(this));
4016       offscreen_saved_color_texture_->Create();
4017     }
4018 
4019     // Allocate the render buffers at their initial size and check the status
4020     // of the frame buffers is okay.
4021     if (!ResizeOffscreenFramebuffer(
4022             gfx::Size(state_.viewport_width, state_.viewport_height))) {
4023       LOG(ERROR) << "ContextResult::kFatalFailure: "
4024                     "Could not allocate offscreen buffer storage.";
4025       return gpu::ContextResult::kFatalFailure;
4026     }
4027     if (!offscreen_single_buffer_) {
4028       // Allocate the offscreen saved color texture.
4029       DCHECK(offscreen_saved_color_format_);
4030       // Use 64x64 instead of 1x1 to handle minimum framebuffer size
4031       // requirement on some platforms: b/151774454
4032       offscreen_saved_color_texture_->AllocateStorage(
4033           gfx::Size(64, 64), offscreen_saved_color_format_, true);
4034 
4035       offscreen_saved_frame_buffer_->AttachRenderTexture(
4036           offscreen_saved_color_texture_.get());
4037       if (offscreen_saved_frame_buffer_->CheckStatus() !=
4038           GL_FRAMEBUFFER_COMPLETE) {
4039         bool was_lost = CheckResetStatus();
4040         LOG(ERROR) << (was_lost ? "ContextResult::kTransientFailure: "
4041                                 : "ContextResult::kFatalFailure: ")
4042                    << "Offscreen saved FBO was incomplete.";
4043         return was_lost ? gpu::ContextResult::kTransientFailure
4044                         : gpu::ContextResult::kFatalFailure;
4045       }
4046     }
4047   }
4048 
4049   api()->glActiveTextureFn(GL_TEXTURE0 + state_.active_texture_unit);
4050 
4051   DoBindBuffer(GL_ARRAY_BUFFER, 0);
4052   DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
4053   DoBindFramebuffer(GL_FRAMEBUFFER, 0);
4054   DoBindRenderbuffer(GL_RENDERBUFFER, 0);
4055   UpdateFramebufferSRGB(nullptr);
4056 
4057   bool call_gl_clear = !surfaceless_ && !offscreen;
4058 #if defined(OS_ANDROID)
4059   // Temporary workaround for Android WebView because this clear ignores the
4060   // clip and corrupts that external UI of the App. Not calling glClear is ok
4061   // because the system already clears the buffer before each draw. Proper
4062   // fix might be setting the scissor clip properly before initialize. See
4063   // crbug.com/259023 for details.
4064   call_gl_clear = surface_->GetHandle();
4065 #endif
4066   if (call_gl_clear) {
4067     // On configs where we report no alpha, if the underlying surface has
4068     // alpha, clear the surface alpha to 1.0 to be correct on ReadPixels/etc.
4069     bool clear_alpha = back_buffer_color_format_ == GL_RGB && alpha_bits > 0;
4070     if (clear_alpha) {
4071       api()->glClearColorFn(0.0f, 0.0f, 0.0f, 1.0f);
4072     }
4073 
4074     // Clear the backbuffer.
4075     api()->glClearFn(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
4076                      GL_STENCIL_BUFFER_BIT);
4077 
4078     // Restore alpha clear value if we changed it.
4079     if (clear_alpha) {
4080       api()->glClearColorFn(0.0f, 0.0f, 0.0f, 0.0f);
4081     }
4082   }
4083 
4084   supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
4085   if (workarounds()
4086           .disable_post_sub_buffers_for_onscreen_surfaces &&
4087       !surface->IsOffscreen())
4088     supports_post_sub_buffer_ = false;
4089 
4090   supports_swap_buffers_with_bounds_ = surface->SupportsSwapBuffersWithBounds();
4091 
4092   supports_commit_overlay_planes_ = surface->SupportsCommitOverlayPlanes();
4093 
4094   supports_async_swap_ = surface->SupportsAsyncSwap();
4095 
4096   supports_dc_layers_ = !offscreen && surface->SupportsDCLayers();
4097 
4098   if (workarounds().unbind_fbo_on_context_switch) {
4099     context_->SetUnbindFboOnMakeCurrent();
4100   }
4101 
4102   if (workarounds().gl_clear_broken) {
4103     DCHECK(!clear_framebuffer_blit_.get());
4104     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
4105     clear_framebuffer_blit_ =
4106         std::make_unique<ClearFramebufferResourceManager>(this);
4107     if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR) {
4108       LOG(ERROR) << "ContextResult::kFatalFailure: "
4109                     "glClearWorkaroundInit failed";
4110       return gpu::ContextResult::kFatalFailure;
4111     }
4112   }
4113 
4114   if (group_->gpu_preferences().enable_gpu_driver_debug_logging &&
4115       feature_info_->feature_flags().khr_debug) {
4116     InitializeGLDebugLogging(true, GLDebugMessageCallback, &logger_);
4117   }
4118 
4119   if (feature_info_->feature_flags().chromium_texture_filtering_hint &&
4120       feature_info_->feature_flags().is_swiftshader) {
4121     api()->glHintFn(GL_TEXTURE_FILTERING_HINT_CHROMIUM, GL_NICEST);
4122   }
4123 
4124   if (CheckResetStatus()) {
4125     // If the context was lost at any point before or during initialization, the
4126     // values queried from the driver could be bogus, and potentially
4127     // inconsistent between various ContextStates on the same underlying real GL
4128     // context. Make sure to report the failure early, to not allow virtualized
4129     // context switches in that case.
4130     LOG(ERROR)
4131         << "  GLES2DecoderImpl: Context reset detected after initialization.";
4132     group_->LoseContexts(error::kUnknown);
4133     destroy_on_failure.LoseContext();
4134     return gpu::ContextResult::kTransientFailure;
4135   }
4136 
4137   destroy_on_failure.OnSuccess();
4138   return gpu::ContextResult::kSuccess;
4139 }
4140 
GetCapabilities()4141 Capabilities GLES2DecoderImpl::GetCapabilities() {
4142   DCHECK(initialized());
4143   Capabilities caps;
4144   const gl::GLVersionInfo& version_info = gl_version_info();
4145   caps.VisitPrecisions([&version_info](
4146                            GLenum shader, GLenum type,
4147                            Capabilities::ShaderPrecision* shader_precision) {
4148     GLint range[2] = {0, 0};
4149     GLint precision = 0;
4150     QueryShaderPrecisionFormat(version_info, shader, type, range, &precision);
4151     shader_precision->min_range = range[0];
4152     shader_precision->max_range = range[1];
4153     shader_precision->precision = precision;
4154   });
4155   DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
4156                 &caps.max_combined_texture_image_units, 1);
4157   DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size,
4158                 1);
4159   DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
4160                 &caps.max_fragment_uniform_vectors, 1);
4161   DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size, 1);
4162   DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units, 1);
4163   DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size, 1);
4164   DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors, 1);
4165   DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs, 1);
4166   DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
4167                 &caps.max_vertex_texture_image_units, 1);
4168   DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &caps.max_vertex_uniform_vectors,
4169                 1);
4170   {
4171     GLint dims[2] = {0, 0};
4172     DoGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims, 2);
4173     caps.max_viewport_width = dims[0];
4174     caps.max_viewport_height = dims[1];
4175   }
4176   DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
4177                 &caps.num_compressed_texture_formats, 1);
4178   DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats,
4179                 1);
4180   DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
4181                 &caps.bind_generates_resource_chromium, 1);
4182   if (feature_info_->IsWebGL2OrES3Context()) {
4183     // TODO(zmo): Note that some parameter values could be more than 32-bit,
4184     // but for now we clamp them to 32-bit max.
4185     DoGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps.max_3d_texture_size, 1);
4186     DoGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps.max_array_texture_layers,
4187                   1);
4188     DoGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps.max_color_attachments, 1);
4189     DoGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
4190                     &caps.max_combined_fragment_uniform_components, 1);
4191     DoGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
4192                   &caps.max_combined_uniform_blocks, 1);
4193     DoGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
4194                     &caps.max_combined_vertex_uniform_components, 1);
4195     DoGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.max_draw_buffers, 1);
4196     DoGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps.max_element_index, 1);
4197     DoGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps.max_elements_indices, 1);
4198     DoGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps.max_elements_vertices, 1);
4199     DoGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
4200                   &caps.max_fragment_input_components, 1);
4201     DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
4202                   &caps.max_fragment_uniform_blocks, 1);
4203     DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
4204                   &caps.max_fragment_uniform_components, 1);
4205     DoGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps.max_program_texel_offset,
4206                   1);
4207     DoGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps.max_server_wait_timeout,
4208                     1);
4209     // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is
4210     // returned.
4211     if (caps.max_server_wait_timeout < 0)
4212       caps.max_server_wait_timeout = 0;
4213     DoGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps.max_texture_lod_bias, 1);
4214     DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
4215                   &caps.max_transform_feedback_interleaved_components, 1);
4216     DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
4217                   &caps.max_transform_feedback_separate_attribs, 1);
4218     DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
4219                   &caps.max_transform_feedback_separate_components, 1);
4220     DoGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps.max_uniform_block_size, 1);
4221     DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
4222                   &caps.max_uniform_buffer_bindings, 1);
4223     DoGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps.max_varying_components, 1);
4224     DoGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
4225                   &caps.max_vertex_output_components, 1);
4226     DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &caps.max_vertex_uniform_blocks,
4227                   1);
4228     DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
4229                   &caps.max_vertex_uniform_components, 1);
4230     DoGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps.min_program_texel_offset,
4231                   1);
4232     DoGetIntegerv(GL_NUM_EXTENSIONS, &caps.num_extensions, 1);
4233     // TODO(vmiura): Remove GL_NUM_PROGRAM_BINARY_FORMATS.
4234     DoGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
4235                   &caps.num_program_binary_formats, 1);
4236     DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
4237                   &caps.uniform_buffer_offset_alignment, 1);
4238     // TODO(zmo): once we switch to MANGLE, we should query version numbers.
4239     caps.major_version = 3;
4240     caps.minor_version = 0;
4241   }
4242   if (feature_info_->feature_flags().multisampled_render_to_texture ||
4243       feature_info_->feature_flags().chromium_framebuffer_multisample ||
4244       feature_info_->IsWebGL2OrES3Context()) {
4245     caps.max_samples = ComputeMaxSamples();
4246   }
4247 
4248   caps.num_stencil_bits = num_stencil_bits_;
4249 
4250   caps.egl_image_external =
4251       feature_info_->feature_flags().oes_egl_image_external;
4252   caps.egl_image_external_essl3 =
4253       feature_info_->feature_flags().oes_egl_image_external_essl3;
4254   caps.texture_format_astc =
4255       feature_info_->feature_flags().ext_texture_format_astc;
4256   caps.texture_format_atc =
4257       feature_info_->feature_flags().ext_texture_format_atc;
4258   caps.texture_format_bgra8888 =
4259       feature_info_->feature_flags().ext_texture_format_bgra8888;
4260   caps.texture_format_dxt1 =
4261       feature_info_->feature_flags().ext_texture_format_dxt1;
4262   caps.texture_format_dxt5 =
4263       feature_info_->feature_flags().ext_texture_format_dxt5;
4264   caps.texture_format_etc1 =
4265       feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
4266   caps.texture_format_etc1_npot =
4267       caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
4268   // Whether or not a texture will be bound to an EGLImage is
4269   // dependent on whether we are using the sync mailbox manager.
4270   caps.disable_one_component_textures =
4271       mailbox_manager()->UsesSync() &&
4272       workarounds().avoid_one_component_egl_images;
4273   caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
4274   caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
4275   caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
4276   caps.discard_framebuffer =
4277       feature_info_->feature_flags().ext_discard_framebuffer;
4278   caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
4279 
4280   caps.chromium_image_rgb_emulation = ChromiumImageNeedsRGBEmulation();
4281 #if defined(OS_MACOSX)
4282   // This is unconditionally true on mac, no need to test for it at runtime.
4283   caps.iosurface = true;
4284 #endif
4285   caps.use_gpu_fences_for_overlay_planes = surface_->SupportsPlaneGpuFences();
4286 
4287   caps.post_sub_buffer = supports_post_sub_buffer_;
4288   caps.swap_buffers_with_bounds = supports_swap_buffers_with_bounds_;
4289   caps.commit_overlay_planes = supports_commit_overlay_planes_;
4290   caps.surfaceless = surfaceless_;
4291   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
4292   caps.surface_origin =
4293       !is_offscreen ? surface_->GetOrigin() : gfx::SurfaceOrigin::kBottomLeft;
4294   caps.msaa_is_slow = workarounds().msaa_is_slow;
4295   caps.avoid_stencil_buffers = workarounds().avoid_stencil_buffers;
4296   caps.multisample_compatibility =
4297       feature_info_->feature_flags().ext_multisample_compatibility;
4298   caps.dc_layers = supports_dc_layers_;
4299   caps.protected_video_swap_chain = surface_->SupportsProtectedVideo();
4300   caps.gpu_vsync = surface_->SupportsGpuVSync();
4301   caps.blend_equation_advanced =
4302       feature_info_->feature_flags().blend_equation_advanced;
4303   caps.blend_equation_advanced_coherent =
4304       feature_info_->feature_flags().blend_equation_advanced_coherent;
4305   caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
4306   caps.texture_norm16 = feature_info_->feature_flags().ext_texture_norm16;
4307   caps.texture_half_float_linear =
4308       feature_info_->oes_texture_half_float_linear_available();
4309   caps.color_buffer_half_float_rgba =
4310       feature_info_->ext_color_buffer_float_available() ||
4311       feature_info_->ext_color_buffer_half_float_available();
4312   caps.image_ycbcr_422 =
4313       feature_info_->feature_flags().chromium_image_ycbcr_422;
4314   caps.image_ycbcr_420v =
4315       feature_info_->feature_flags().chromium_image_ycbcr_420v;
4316   caps.image_ycbcr_420v_disabled_for_video_frames =
4317       group_->gpu_preferences()
4318           .disable_biplanar_gpu_memory_buffers_for_video_frames;
4319   caps.image_ar30 = feature_info_->feature_flags().chromium_image_ar30;
4320   caps.image_ab30 = feature_info_->feature_flags().chromium_image_ab30;
4321   caps.image_ycbcr_p010 =
4322       feature_info_->feature_flags().chromium_image_ycbcr_p010;
4323   caps.max_copy_texture_chromium_size =
4324       workarounds().max_copy_texture_chromium_size;
4325   caps.render_buffer_format_bgra8888 =
4326       feature_info_->feature_flags().ext_render_buffer_format_bgra8888;
4327   caps.occlusion_query = feature_info_->feature_flags().occlusion_query;
4328   caps.occlusion_query_boolean =
4329       feature_info_->feature_flags().occlusion_query_boolean;
4330   caps.timer_queries = query_manager_->GPUTimingAvailable();
4331   caps.gpu_rasterization =
4332       group_->gpu_feature_info()
4333           .status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] ==
4334       kGpuFeatureStatusEnabled;
4335   if (workarounds().broken_egl_image_ref_counting &&
4336       group_->gpu_preferences().enable_threaded_texture_mailboxes) {
4337     caps.disable_2d_canvas_copy_on_write = true;
4338   }
4339   caps.texture_npot = feature_info_->feature_flags().npot_ok;
4340   caps.texture_storage_image =
4341       feature_info_->feature_flags().chromium_texture_storage_image;
4342   caps.supports_oop_raster = false;
4343   caps.chromium_gpu_fence = feature_info_->feature_flags().chromium_gpu_fence;
4344   caps.unpremultiply_and_dither_copy =
4345       feature_info_->feature_flags().unpremultiply_and_dither_copy;
4346   caps.separate_stencil_ref_mask_writemask =
4347       feature_info_->feature_flags().separate_stencil_ref_mask_writemask;
4348   caps.chromium_nonblocking_readback =
4349       feature_info_->context_type() == CONTEXT_TYPE_WEBGL2;
4350   caps.num_surface_buffers = surface_->GetBufferCount();
4351   caps.mesa_framebuffer_flip_y =
4352       feature_info_->feature_flags().mesa_framebuffer_flip_y;
4353 
4354   caps.gpu_memory_buffer_formats =
4355       feature_info_->feature_flags().gpu_memory_buffer_formats;
4356   caps.texture_target_exception_list =
4357       group_->gpu_preferences().texture_target_exception_list;
4358 
4359   return caps;
4360 }
4361 
ComputeMaxSamples()4362 GLint GLES2DecoderImpl::ComputeMaxSamples() {
4363   GLint max_samples = 0;
4364   DoGetIntegerv(GL_MAX_SAMPLES, &max_samples, 1);
4365 
4366   if (feature_info_->IsWebGLContext() &&
4367       feature_info_->feature_flags().nv_internalformat_sample_query) {
4368     std::vector<GLint> temp;
4369 
4370     auto minWithSamplesForFormat = [&](GLenum internalformat) {
4371       temp.clear();
4372       InternalFormatSampleCountsHelper(GL_RENDERBUFFER, internalformat, &temp);
4373       max_samples = std::min(max_samples, temp[0]);
4374     };
4375 
4376     // OpenGL ES 3.0.5, section 4.4.2.2: "Implementations must support creation
4377     // of renderbuffers in these required formats with up to the value of
4378     // MAX_SAMPLES multisamples, with the exception of signed and unsigned
4379     // integer formats."
4380 
4381     // OpenGL ES 3.0.5, section 3.8.3.1
4382     minWithSamplesForFormat(GL_RGBA8);
4383     minWithSamplesForFormat(GL_SRGB8_ALPHA8);
4384     minWithSamplesForFormat(GL_RGB10_A2);
4385     minWithSamplesForFormat(GL_RGBA4);
4386     minWithSamplesForFormat(GL_RGB5_A1);
4387     minWithSamplesForFormat(GL_RGB8);
4388     minWithSamplesForFormat(GL_RGB565);
4389     minWithSamplesForFormat(GL_RG8);
4390     minWithSamplesForFormat(GL_R8);
4391   }
4392 
4393   return max_samples;
4394 }
4395 
UpdateCapabilities()4396 void GLES2DecoderImpl::UpdateCapabilities() {
4397   util_.set_num_compressed_texture_formats(
4398       validators_->compressed_texture_format.GetValues().size());
4399   util_.set_num_shader_binary_formats(
4400       validators_->shader_binary_format.GetValues().size());
4401 }
4402 
InitializeShaderTranslator()4403 bool GLES2DecoderImpl::InitializeShaderTranslator() {
4404   TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
4405   if (feature_info_->disable_shader_translator()) {
4406     return true;
4407   }
4408   if (vertex_translator_ || fragment_translator_) {
4409     DCHECK(vertex_translator_ && fragment_translator_);
4410     return true;
4411   }
4412   ShBuiltInResources resources;
4413   sh::InitBuiltInResources(&resources);
4414   resources.MaxVertexAttribs = group_->max_vertex_attribs();
4415   resources.MaxVertexUniformVectors =
4416       group_->max_vertex_uniform_vectors();
4417   resources.MaxVaryingVectors = group_->max_varying_vectors();
4418   resources.MaxVertexTextureImageUnits =
4419       group_->max_vertex_texture_image_units();
4420   resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
4421   resources.MaxTextureImageUnits = group_->max_texture_image_units();
4422   resources.MaxFragmentUniformVectors =
4423       group_->max_fragment_uniform_vectors();
4424   resources.MaxDrawBuffers = group_->max_draw_buffers();
4425   resources.MaxExpressionComplexity = 256;
4426   resources.MaxCallStackDepth = 256;
4427   resources.MaxDualSourceDrawBuffers = group_->max_dual_source_draw_buffers();
4428 
4429   if (!feature_info_->IsWebGL1OrES2Context()) {
4430     resources.MaxVertexOutputVectors =
4431         group_->max_vertex_output_components() / 4;
4432     resources.MaxFragmentInputVectors =
4433         group_->max_fragment_input_components() / 4;
4434     resources.MaxProgramTexelOffset = group_->max_program_texel_offset();
4435     resources.MinProgramTexelOffset = group_->min_program_texel_offset();
4436   }
4437 
4438   resources.FragmentPrecisionHigh = has_fragment_precision_high_;
4439 
4440   ShShaderSpec shader_spec;
4441   switch (feature_info_->context_type()) {
4442     case CONTEXT_TYPE_WEBGL1:
4443       shader_spec = SH_WEBGL_SPEC;
4444       resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
4445       resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
4446       resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
4447       if (!draw_buffers_explicitly_enabled_)
4448         resources.MaxDrawBuffers = 1;
4449       resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
4450       resources.NV_draw_buffers =
4451           draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
4452       break;
4453     case CONTEXT_TYPE_WEBGL2:
4454       shader_spec = SH_WEBGL2_SPEC;
4455       break;
4456     case CONTEXT_TYPE_OPENGLES2:
4457       shader_spec = SH_GLES2_SPEC;
4458       resources.OES_standard_derivatives =
4459           features().oes_standard_derivatives ? 1 : 0;
4460       resources.ARB_texture_rectangle =
4461           features().arb_texture_rectangle ? 1 : 0;
4462       resources.OES_EGL_image_external =
4463           features().oes_egl_image_external ? 1 : 0;
4464       resources.NV_EGL_stream_consumer_external =
4465           features().nv_egl_stream_consumer_external ? 1 : 0;
4466       resources.EXT_draw_buffers =
4467           features().ext_draw_buffers ? 1 : 0;
4468       resources.EXT_frag_depth =
4469           features().ext_frag_depth ? 1 : 0;
4470       resources.EXT_shader_texture_lod =
4471           features().ext_shader_texture_lod ? 1 : 0;
4472       resources.NV_draw_buffers =
4473           features().nv_draw_buffers ? 1 : 0;
4474       resources.EXT_blend_func_extended =
4475           features().ext_blend_func_extended ? 1 : 0;
4476       break;
4477     case CONTEXT_TYPE_OPENGLES3:
4478       shader_spec = SH_GLES3_SPEC;
4479       resources.ARB_texture_rectangle =
4480           features().arb_texture_rectangle ? 1 : 0;
4481       resources.OES_EGL_image_external =
4482           features().oes_egl_image_external ? 1 : 0;
4483       resources.NV_EGL_stream_consumer_external =
4484           features().nv_egl_stream_consumer_external ? 1 : 0;
4485       resources.EXT_blend_func_extended =
4486           features().ext_blend_func_extended ? 1 : 0;
4487       break;
4488     default:
4489       NOTREACHED();
4490       shader_spec = SH_GLES2_SPEC;
4491       break;
4492   }
4493 
4494   if (shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) {
4495     resources.ANGLE_multi_draw =
4496         multi_draw_explicitly_enabled_ && features().webgl_multi_draw;
4497   }
4498 
4499   if (shader_spec == SH_WEBGL2_SPEC) {
4500     resources.ANGLE_base_vertex_base_instance =
4501         (draw_instanced_base_vertex_base_instance_explicitly_enabled_ &&
4502          features().webgl_draw_instanced_base_vertex_base_instance) ||
4503         (multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_ &&
4504          features().webgl_multi_draw_instanced_base_vertex_base_instance);
4505   }
4506 
4507   if (((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
4508        features().enable_shader_name_hashing) ||
4509       force_shader_name_hashing_for_test) {
4510     // TODO(https://crbug.com/902789): In theory, it should be OK to change this
4511     // hash. However, in practice, this seems to cause some tests to fail. See
4512     // https://crbug.com/963889.
4513     resources.HashFunction = +[](const char* data, size_t size) {
4514       return base::legacy::CityHash64(
4515           base::as_bytes(base::make_span(data, size)));
4516     };
4517   } else {
4518     resources.HashFunction = nullptr;
4519   }
4520 
4521   ShCompileOptions driver_bug_workarounds = 0;
4522   if (workarounds().init_gl_position_in_vertex_shader)
4523     driver_bug_workarounds |= SH_INIT_GL_POSITION;
4524   if (workarounds().unfold_short_circuit_as_ternary_operation)
4525     driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
4526   if (workarounds().scalarize_vec_and_mat_constructor_args)
4527     driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
4528   if (workarounds().regenerate_struct_names)
4529     driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
4530   if (workarounds().remove_pow_with_constant_exponent)
4531     driver_bug_workarounds |= SH_REMOVE_POW_WITH_CONSTANT_EXPONENT;
4532   if (workarounds().emulate_abs_int_function)
4533     driver_bug_workarounds |= SH_EMULATE_ABS_INT_FUNCTION;
4534   if (workarounds().rewrite_texelfetchoffset_to_texelfetch)
4535     driver_bug_workarounds |= SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH;
4536   if (workarounds().add_and_true_to_loop_condition)
4537     driver_bug_workarounds |= SH_ADD_AND_TRUE_TO_LOOP_CONDITION;
4538   if (workarounds().rewrite_do_while_loops)
4539     driver_bug_workarounds |= SH_REWRITE_DO_WHILE_LOOPS;
4540   if (workarounds().emulate_isnan_on_float)
4541     driver_bug_workarounds |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
4542   if (workarounds().use_unused_standard_shared_blocks)
4543     driver_bug_workarounds |= SH_USE_UNUSED_STANDARD_SHARED_BLOCKS;
4544   if (workarounds().dont_remove_invariant_for_fragment_input)
4545     driver_bug_workarounds |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT;
4546   if (workarounds().remove_invariant_and_centroid_for_essl3)
4547     driver_bug_workarounds |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
4548   if (workarounds().rewrite_float_unary_minus_operator)
4549     driver_bug_workarounds |= SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR;
4550   if (workarounds().dont_use_loops_to_initialize_variables)
4551     driver_bug_workarounds |= SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES;
4552   if (workarounds().remove_dynamic_indexing_of_swizzled_vector)
4553     driver_bug_workarounds |= SH_REMOVE_DYNAMIC_INDEXING_OF_SWIZZLED_VECTOR;
4554 
4555   // Initialize uninitialized locals by default
4556   if (!workarounds().dont_initialize_uninitialized_locals)
4557     driver_bug_workarounds |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
4558 
4559   resources.WEBGL_debug_shader_precision =
4560       group_->gpu_preferences().emulate_shader_precision;
4561 
4562   ShShaderOutput shader_output_language =
4563       ShaderTranslator::GetShaderOutputLanguageForContext(gl_version_info());
4564 
4565   vertex_translator_ = shader_translator_cache()->GetTranslator(
4566       GL_VERTEX_SHADER, shader_spec, &resources, shader_output_language,
4567       driver_bug_workarounds);
4568   if (!vertex_translator_.get()) {
4569     LOG(ERROR) << "Could not initialize vertex shader translator.";
4570     Destroy(true);
4571     return false;
4572   }
4573 
4574   fragment_translator_ = shader_translator_cache()->GetTranslator(
4575       GL_FRAGMENT_SHADER, shader_spec, &resources, shader_output_language,
4576       driver_bug_workarounds);
4577   if (!fragment_translator_.get()) {
4578     LOG(ERROR) << "Could not initialize fragment shader translator.";
4579     Destroy(true);
4580     return false;
4581   }
4582   return true;
4583 }
4584 
DestroyShaderTranslator()4585 void GLES2DecoderImpl::DestroyShaderTranslator() {
4586   vertex_translator_ = nullptr;
4587   fragment_translator_ = nullptr;
4588 }
4589 
GenBuffersHelper(GLsizei n,const GLuint * client_ids)4590 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
4591   for (GLsizei ii = 0; ii < n; ++ii) {
4592     if (GetBuffer(client_ids[ii])) {
4593       return false;
4594     }
4595   }
4596   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4597   api()->glGenBuffersARBFn(n, service_ids.get());
4598   for (GLsizei ii = 0; ii < n; ++ii) {
4599     CreateBuffer(client_ids[ii], service_ids[ii]);
4600   }
4601   return true;
4602 }
4603 
GenFramebuffersHelper(GLsizei n,const GLuint * client_ids)4604 bool GLES2DecoderImpl::GenFramebuffersHelper(
4605     GLsizei n, const GLuint* client_ids) {
4606   for (GLsizei ii = 0; ii < n; ++ii) {
4607     if (GetFramebuffer(client_ids[ii])) {
4608       return false;
4609     }
4610   }
4611   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4612   api()->glGenFramebuffersEXTFn(n, service_ids.get());
4613   for (GLsizei ii = 0; ii < n; ++ii) {
4614     CreateFramebuffer(client_ids[ii], service_ids[ii]);
4615   }
4616   return true;
4617 }
4618 
GenRenderbuffersHelper(GLsizei n,const GLuint * client_ids)4619 bool GLES2DecoderImpl::GenRenderbuffersHelper(
4620     GLsizei n, const GLuint* client_ids) {
4621   for (GLsizei ii = 0; ii < n; ++ii) {
4622     if (GetRenderbuffer(client_ids[ii])) {
4623       return false;
4624     }
4625   }
4626   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4627   api()->glGenRenderbuffersEXTFn(n, service_ids.get());
4628   for (GLsizei ii = 0; ii < n; ++ii) {
4629     CreateRenderbuffer(client_ids[ii], service_ids[ii]);
4630   }
4631   return true;
4632 }
4633 
GenTexturesHelper(GLsizei n,const GLuint * client_ids)4634 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
4635   for (GLsizei ii = 0; ii < n; ++ii) {
4636     if (GetTexture(client_ids[ii])) {
4637       return false;
4638     }
4639   }
4640   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4641   api()->glGenTexturesFn(n, service_ids.get());
4642   for (GLsizei ii = 0; ii < n; ++ii) {
4643     CreateTexture(client_ids[ii], service_ids[ii]);
4644   }
4645   return true;
4646 }
4647 
GenSamplersHelper(GLsizei n,const GLuint * client_ids)4648 bool GLES2DecoderImpl::GenSamplersHelper(GLsizei n, const GLuint* client_ids) {
4649   for (GLsizei ii = 0; ii < n; ++ii) {
4650     if (GetSampler(client_ids[ii])) {
4651       return false;
4652     }
4653   }
4654   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4655   api()->glGenSamplersFn(n, service_ids.get());
4656   for (GLsizei ii = 0; ii < n; ++ii) {
4657     CreateSampler(client_ids[ii], service_ids[ii]);
4658   }
4659   return true;
4660 }
4661 
GenTransformFeedbacksHelper(GLsizei n,const GLuint * client_ids)4662 bool GLES2DecoderImpl::GenTransformFeedbacksHelper(
4663     GLsizei n, const GLuint* client_ids) {
4664   for (GLsizei ii = 0; ii < n; ++ii) {
4665     if (GetTransformFeedback(client_ids[ii])) {
4666       return false;
4667     }
4668   }
4669   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
4670   api()->glGenTransformFeedbacksFn(n, service_ids.get());
4671   for (GLsizei ii = 0; ii < n; ++ii) {
4672     CreateTransformFeedback(client_ids[ii], service_ids[ii]);
4673   }
4674   return true;
4675 }
4676 
DeleteBuffersHelper(GLsizei n,const volatile GLuint * client_ids)4677 void GLES2DecoderImpl::DeleteBuffersHelper(GLsizei n,
4678                                            const volatile GLuint* client_ids) {
4679   for (GLsizei ii = 0; ii < n; ++ii) {
4680     GLuint client_id = client_ids[ii];
4681     Buffer* buffer = GetBuffer(client_id);
4682     if (buffer && !buffer->IsDeleted()) {
4683       if (buffer->GetMappedRange()) {
4684         // The buffer is not guaranteed to still be bound to any binding point,
4685         // even though it is mapped. If it is not bound, we will need to bind
4686         // it temporarily in order to unmap it.
4687         GLenum target = buffer->initial_target();
4688         Buffer* currently_bound =
4689             buffer_manager()->GetBufferInfoForTarget(&state_, target);
4690         if (currently_bound != buffer) {
4691           api()->glBindBufferFn(target, buffer->service_id());
4692         }
4693         UnmapBufferHelper(buffer, target);
4694         if (currently_bound != buffer) {
4695           api()->glBindBufferFn(
4696               target, currently_bound ? currently_bound->service_id() : 0);
4697         }
4698       }
4699       state_.RemoveBoundBuffer(buffer);
4700       buffer_manager()->RemoveBuffer(client_id);
4701     }
4702   }
4703 }
4704 
DeleteFramebuffersHelper(GLsizei n,const volatile GLuint * client_ids)4705 void GLES2DecoderImpl::DeleteFramebuffersHelper(
4706     GLsizei n,
4707     const volatile GLuint* client_ids) {
4708   for (GLsizei ii = 0; ii < n; ++ii) {
4709     GLuint client_id = client_ids[ii];
4710     Framebuffer* framebuffer = GetFramebuffer(client_id);
4711     if (framebuffer && !framebuffer->IsDeleted()) {
4712       if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
4713         GLenum target = GetDrawFramebufferTarget();
4714 
4715         // Unbind attachments on FBO before deletion.
4716         if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
4717           framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
4718 
4719         api()->glBindFramebufferEXTFn(target, GetBackbufferServiceId());
4720         state_.UpdateWindowRectanglesForBoundDrawFramebufferClientID(0);
4721         framebuffer_state_.bound_draw_framebuffer = nullptr;
4722         framebuffer_state_.clear_state_dirty = true;
4723       }
4724       if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
4725         framebuffer_state_.bound_read_framebuffer = nullptr;
4726         GLenum target = GetReadFramebufferTarget();
4727         api()->glBindFramebufferEXTFn(target, GetBackbufferServiceId());
4728       }
4729       OnFboChanged();
4730       RemoveFramebuffer(client_id);
4731     }
4732   }
4733 }
4734 
DeleteRenderbuffersHelper(GLsizei n,const volatile GLuint * client_ids)4735 void GLES2DecoderImpl::DeleteRenderbuffersHelper(
4736     GLsizei n,
4737     const volatile GLuint* client_ids) {
4738   bool supports_separate_framebuffer_binds =
4739      features().chromium_framebuffer_multisample;
4740   for (GLsizei ii = 0; ii < n; ++ii) {
4741     GLuint client_id = client_ids[ii];
4742     Renderbuffer* renderbuffer = GetRenderbuffer(client_id);
4743     if (renderbuffer && !renderbuffer->IsDeleted()) {
4744       if (state_.bound_renderbuffer.get() == renderbuffer) {
4745         state_.bound_renderbuffer = nullptr;
4746       }
4747       // Unbind from current framebuffers.
4748       if (supports_separate_framebuffer_binds) {
4749         if (framebuffer_state_.bound_read_framebuffer.get()) {
4750           framebuffer_state_.bound_read_framebuffer
4751               ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
4752         }
4753         if (framebuffer_state_.bound_draw_framebuffer.get()) {
4754           framebuffer_state_.bound_draw_framebuffer
4755               ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
4756         }
4757       } else {
4758         if (framebuffer_state_.bound_draw_framebuffer.get()) {
4759           framebuffer_state_.bound_draw_framebuffer
4760               ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
4761         }
4762       }
4763       framebuffer_state_.clear_state_dirty = true;
4764       RemoveRenderbuffer(client_id);
4765     }
4766   }
4767 }
4768 
DeleteTexturesHelper(GLsizei n,const volatile GLuint * client_ids)4769 void GLES2DecoderImpl::DeleteTexturesHelper(GLsizei n,
4770                                             const volatile GLuint* client_ids) {
4771   bool supports_separate_framebuffer_binds = SupportsSeparateFramebufferBinds();
4772   for (GLsizei ii = 0; ii < n; ++ii) {
4773     GLuint client_id = client_ids[ii];
4774     TextureRef* texture_ref = GetTexture(client_id);
4775     if (texture_ref) {
4776       UnbindTexture(texture_ref, supports_separate_framebuffer_binds);
4777       RemoveTexture(client_id);
4778     }
4779   }
4780 }
4781 
DeleteSamplersHelper(GLsizei n,const volatile GLuint * client_ids)4782 void GLES2DecoderImpl::DeleteSamplersHelper(GLsizei n,
4783                                             const volatile GLuint* client_ids) {
4784   for (GLsizei ii = 0; ii < n; ++ii) {
4785     GLuint client_id = client_ids[ii];
4786     Sampler* sampler = GetSampler(client_id);
4787     if (sampler && !sampler->IsDeleted()) {
4788       // Unbind from current sampler units.
4789       state_.UnbindSampler(sampler);
4790 
4791       RemoveSampler(client_id);
4792     }
4793   }
4794 }
4795 
DeleteTransformFeedbacksHelper(GLsizei n,const volatile GLuint * client_ids)4796 void GLES2DecoderImpl::DeleteTransformFeedbacksHelper(
4797     GLsizei n,
4798     const volatile GLuint* client_ids) {
4799   for (GLsizei ii = 0; ii < n; ++ii) {
4800     GLuint client_id = client_ids[ii];
4801     TransformFeedback* transform_feedback = GetTransformFeedback(client_id);
4802     if (transform_feedback) {
4803       if (transform_feedback->active()) {
4804         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glDeleteTransformFeedbacks",
4805                            "Deleting transform feedback is active");
4806         return;
4807       }
4808       if (state_.bound_transform_feedback.get() == transform_feedback) {
4809         // Bind to the default transform feedback.
4810         DCHECK(state_.default_transform_feedback.get());
4811         state_.default_transform_feedback->DoBindTransformFeedback(
4812             GL_TRANSFORM_FEEDBACK, state_.bound_transform_feedback.get(),
4813             state_.bound_transform_feedback_buffer.get());
4814         state_.bound_transform_feedback =
4815             state_.default_transform_feedback.get();
4816       }
4817       RemoveTransformFeedback(client_id);
4818     }
4819   }
4820 }
4821 
DeleteSyncHelper(GLuint sync)4822 void GLES2DecoderImpl::DeleteSyncHelper(GLuint sync) {
4823   GLsync service_id = 0;
4824   if (group_->GetSyncServiceId(sync, &service_id)) {
4825     api()->glDeleteSyncFn(service_id);
4826     group_->RemoveSyncId(sync);
4827   } else if (sync != 0) {
4828     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteSync", "unknown sync");
4829   }
4830 }
4831 
MakeCurrent()4832 bool GLES2DecoderImpl::MakeCurrent() {
4833   DCHECK(surface_);
4834   if (!context_.get())
4835     return false;
4836 
4837   if (WasContextLost()) {
4838     LOG(ERROR) << "  GLES2DecoderImpl: Trying to make lost context current.";
4839     return false;
4840   }
4841 
4842   if (!context_->MakeCurrent(surface_.get())) {
4843     LOG(ERROR) << "  GLES2DecoderImpl: Context lost during MakeCurrent.";
4844     MarkContextLost(error::kMakeCurrentFailed);
4845     group_->LoseContexts(error::kUnknown);
4846     return false;
4847   }
4848   DCHECK_EQ(api(), gl::g_current_gl_context);
4849 
4850   if (CheckResetStatus()) {
4851     LOG(ERROR)
4852         << "  GLES2DecoderImpl: Context reset detected after MakeCurrent.";
4853     group_->LoseContexts(error::kUnknown);
4854     return false;
4855   }
4856 
4857   ProcessFinishedAsyncTransfers();
4858 
4859   // Rebind the FBO if it was unbound by the context.
4860   if (workarounds().unbind_fbo_on_context_switch)
4861     RestoreFramebufferBindings();
4862 
4863   framebuffer_state_.clear_state_dirty = true;
4864   state_.stencil_state_changed_since_validation = true;
4865 
4866   // Rebind textures if the service ids may have changed.
4867   RestoreAllExternalTextureBindingsIfNeeded();
4868 
4869   // Since we have a context now, take the opportunity to drop any TextureRefs
4870   // that are pending destruction.
4871   texture_refs_pending_destruction_.clear();
4872 
4873   return true;
4874 }
4875 
ProcessFinishedAsyncTransfers()4876 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
4877   ProcessPendingReadPixels(false);
4878 }
4879 
RebindCurrentFramebuffer(gl::GLApi * api,GLenum target,Framebuffer * framebuffer,GLuint back_buffer_service_id)4880 static void RebindCurrentFramebuffer(gl::GLApi* api,
4881                                      GLenum target,
4882                                      Framebuffer* framebuffer,
4883                                      GLuint back_buffer_service_id) {
4884   GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
4885 
4886   if (framebuffer_id == 0) {
4887     framebuffer_id = back_buffer_service_id;
4888   }
4889 
4890   api->glBindFramebufferEXTFn(target, framebuffer_id);
4891 }
4892 
RestoreCurrentFramebufferBindings()4893 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
4894   framebuffer_state_.clear_state_dirty = true;
4895 
4896   if (!SupportsSeparateFramebufferBinds()) {
4897     RebindCurrentFramebuffer(api(), GL_FRAMEBUFFER,
4898                              framebuffer_state_.bound_draw_framebuffer.get(),
4899                              GetBackbufferServiceId());
4900   } else {
4901     RebindCurrentFramebuffer(api(), GL_READ_FRAMEBUFFER_EXT,
4902                              framebuffer_state_.bound_read_framebuffer.get(),
4903                              GetBackbufferServiceId());
4904     RebindCurrentFramebuffer(api(), GL_DRAW_FRAMEBUFFER_EXT,
4905                              framebuffer_state_.bound_draw_framebuffer.get(),
4906                              GetBackbufferServiceId());
4907   }
4908   OnFboChanged();
4909 }
4910 
CheckFramebufferValid(Framebuffer * framebuffer,GLenum target,GLenum gl_error,const char * func_name)4911 bool GLES2DecoderImpl::CheckFramebufferValid(
4912     Framebuffer* framebuffer,
4913     GLenum target,
4914     GLenum gl_error,
4915     const char* func_name) {
4916   if (!framebuffer) {
4917     if (surfaceless_)
4918       return false;
4919     if (backbuffer_needs_clear_bits_) {
4920       api()->glClearColorFn(0, 0, 0, BackBufferAlphaClearColor());
4921       state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
4922       api()->glClearStencilFn(0);
4923       state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
4924       state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
4925       api()->glClearDepthFn(1.0f);
4926       state_.SetDeviceDepthMask(GL_TRUE);
4927       state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
4928       ClearDeviceWindowRectangles();
4929       bool reset_draw_buffer = false;
4930       if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
4931           back_buffer_draw_buffer_ == GL_NONE) {
4932         reset_draw_buffer = true;
4933         GLenum buf = GL_BACK;
4934         if (GetBackbufferServiceId() != 0)  // emulated backbuffer
4935           buf = GL_COLOR_ATTACHMENT0;
4936         api()->glDrawBuffersARBFn(1, &buf);
4937       }
4938       if (workarounds().gl_clear_broken) {
4939         ClearFramebufferForWorkaround(backbuffer_needs_clear_bits_);
4940       } else {
4941         api()->glClearFn(backbuffer_needs_clear_bits_);
4942       }
4943       if (reset_draw_buffer) {
4944         GLenum buf = GL_NONE;
4945         api()->glDrawBuffersARBFn(1, &buf);
4946       }
4947       backbuffer_needs_clear_bits_ = 0;
4948       RestoreClearState();
4949     }
4950     return true;
4951   }
4952 
4953   if (!framebuffer_manager()->IsComplete(framebuffer)) {
4954     GLenum completeness = framebuffer->IsPossiblyComplete(feature_info_.get());
4955     if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4956       LOCAL_SET_GL_ERROR(gl_error, func_name, "framebuffer incomplete");
4957       return false;
4958     }
4959 
4960     if (framebuffer->GetStatus(texture_manager(), target) !=
4961         GL_FRAMEBUFFER_COMPLETE) {
4962       LOCAL_SET_GL_ERROR(
4963           gl_error, func_name, "framebuffer incomplete (check)");
4964       return false;
4965     }
4966     framebuffer_manager()->MarkAsComplete(framebuffer);
4967   }
4968 
4969   // Are all the attachments cleared?
4970   if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
4971       texture_manager()->HaveUnclearedMips()) {
4972     if (!framebuffer->IsCleared()) {
4973       ClearUnclearedAttachments(target, framebuffer);
4974     }
4975   }
4976   return true;
4977 }
4978 
CheckBoundDrawFramebufferValid(const char * func_name,bool check_float_blending)4979 bool GLES2DecoderImpl::CheckBoundDrawFramebufferValid(
4980     const char* func_name,
4981     bool check_float_blending) {
4982   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
4983   bool valid = CheckFramebufferValid(
4984       framebuffer, GetDrawFramebufferTarget(),
4985       GL_INVALID_FRAMEBUFFER_OPERATION, func_name);
4986   if (!valid)
4987     return false;
4988 
4989   if (check_float_blending) {
4990     // only is true when called by DoMultiDrawArrays or DoMultiDrawElements
4991     if (framebuffer && state_.GetEnabled(GL_BLEND) &&
4992         !features().ext_float_blend) {
4993       if (framebuffer->HasActiveFloat32ColorAttachment()) {
4994         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
4995                            "GL_BLEND with floating-point color attachments "
4996                            "requires the EXT_float_blend extension");
4997         return false;
4998       }
4999     }
5000   }
5001 
5002   if (!SupportsSeparateFramebufferBinds())
5003     OnUseFramebuffer();
5004 
5005   UpdateFramebufferSRGB(framebuffer);
5006   return true;
5007 }
5008 
UpdateFramebufferSRGB(Framebuffer * framebuffer)5009 void GLES2DecoderImpl::UpdateFramebufferSRGB(Framebuffer* framebuffer) {
5010   // Manually set the value of FRAMEBUFFER_SRGB based on the state that was set
5011   // by the client.
5012   bool needs_enable_disable_framebuffer_srgb = false;
5013   bool enable_framebuffer_srgb = true;
5014   if (feature_info_->feature_flags().ext_srgb_write_control) {
5015     needs_enable_disable_framebuffer_srgb = true;
5016     enable_framebuffer_srgb &= state_.GetEnabled(GL_FRAMEBUFFER_SRGB);
5017   }
5018   // On desktop, enable FRAMEBUFFER_SRGB only if the framebuffer contains sRGB
5019   // attachments. In theory, we can just leave FRAMEBUFFER_SRGB enabled,
5020   // however,
5021   // many drivers behave incorrectly when no attachments are sRGB. When at
5022   // least one attachment is sRGB, then they behave correctly.
5023   if (feature_info_->feature_flags().desktop_srgb_support) {
5024     needs_enable_disable_framebuffer_srgb = true;
5025     // Assume that the default fbo does not have an sRGB image.
5026     enable_framebuffer_srgb &= framebuffer && framebuffer->HasSRGBAttachments();
5027   }
5028   if (needs_enable_disable_framebuffer_srgb)
5029     state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
5030 }
5031 
CheckBoundReadFramebufferValid(const char * func_name,GLenum gl_error)5032 bool GLES2DecoderImpl::CheckBoundReadFramebufferValid(
5033     const char* func_name, GLenum gl_error) {
5034   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5035   bool valid = CheckFramebufferValid(
5036       framebuffer, GetReadFramebufferTarget(), gl_error, func_name);
5037   return valid;
5038 }
5039 
CheckBoundFramebufferValid(const char * func_name)5040 bool GLES2DecoderImpl::CheckBoundFramebufferValid(const char* func_name) {
5041   GLenum gl_error = GL_INVALID_FRAMEBUFFER_OPERATION;
5042   Framebuffer* draw_framebuffer = GetBoundDrawFramebuffer();
5043   bool valid = CheckFramebufferValid(
5044       draw_framebuffer, GetDrawFramebufferTarget(), gl_error, func_name);
5045 
5046   Framebuffer* read_framebuffer = GetBoundReadFramebuffer();
5047   valid = valid && CheckFramebufferValid(
5048       read_framebuffer, GetReadFramebufferTarget(), gl_error, func_name);
5049   return valid;
5050 }
5051 
FormsTextureCopyingFeedbackLoop(TextureRef * texture,GLint level,GLint layer)5052 bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
5053     TextureRef* texture, GLint level, GLint layer) {
5054   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5055   if (!framebuffer)
5056     return false;
5057   const Framebuffer::Attachment* attachment =
5058       framebuffer->GetReadBufferAttachment();
5059   if (!attachment)
5060     return false;
5061   return attachment->FormsFeedbackLoop(texture, level, layer);
5062 }
5063 
GetBoundReadFramebufferSize()5064 gfx::Size GLES2DecoderImpl::GetBoundReadFramebufferSize() {
5065   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5066   if (framebuffer) {
5067     return framebuffer->GetFramebufferValidSize();
5068   } else if (offscreen_target_frame_buffer_.get()) {
5069     return offscreen_size_;
5070   } else {
5071     return surface_->GetSize();
5072   }
5073 }
5074 
GetBoundDrawFramebufferSize()5075 gfx::Size GLES2DecoderImpl::GetBoundDrawFramebufferSize() {
5076   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
5077   if (framebuffer) {
5078     return framebuffer->GetFramebufferValidSize();
5079   } else if (offscreen_target_frame_buffer_.get()) {
5080     return offscreen_size_;
5081   } else {
5082     return surface_->GetSize();
5083   }
5084 }
5085 
GetBoundReadFramebufferServiceId()5086 GLuint GLES2DecoderImpl::GetBoundReadFramebufferServiceId() {
5087   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5088   if (framebuffer) {
5089     return framebuffer->service_id();
5090   }
5091   if (offscreen_resolved_frame_buffer_.get()) {
5092     return offscreen_resolved_frame_buffer_->id();
5093   }
5094   if (offscreen_target_frame_buffer_.get()) {
5095     return offscreen_target_frame_buffer_->id();
5096   }
5097   if (surface_.get()) {
5098     return surface_->GetBackingFramebufferObject();
5099   }
5100   return 0;
5101 }
5102 
GetBoundDrawFramebufferServiceId() const5103 GLuint GLES2DecoderImpl::GetBoundDrawFramebufferServiceId() const {
5104   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
5105   if (framebuffer) {
5106     return framebuffer->service_id();
5107   }
5108   if (offscreen_target_frame_buffer_.get()) {
5109     return offscreen_target_frame_buffer_->id();
5110   }
5111   if (surface_.get()) {
5112     return surface_->GetBackingFramebufferObject();
5113   }
5114   return 0;
5115 }
5116 
GetBoundReadFramebufferTextureType()5117 GLenum GLES2DecoderImpl::GetBoundReadFramebufferTextureType() {
5118   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5119   if (framebuffer) {
5120     return framebuffer->GetReadBufferTextureType();
5121   } else {  // Back buffer.
5122     if (back_buffer_read_buffer_ == GL_NONE)
5123       return 0;
5124     return GL_UNSIGNED_BYTE;
5125   }
5126 }
5127 
GetBoundReadFramebufferInternalFormat()5128 GLenum GLES2DecoderImpl::GetBoundReadFramebufferInternalFormat() {
5129   Framebuffer* framebuffer = GetBoundReadFramebuffer();
5130   if (framebuffer) {
5131     return framebuffer->GetReadBufferInternalFormat();
5132   } else {  // Back buffer.
5133     if (back_buffer_read_buffer_ == GL_NONE)
5134       return 0;
5135     if (offscreen_target_frame_buffer_.get()) {
5136       return offscreen_target_color_format_;
5137     }
5138     return back_buffer_color_format_;
5139   }
5140 }
5141 
GetBoundColorDrawBufferType(GLint drawbuffer_i)5142 GLenum GLES2DecoderImpl::GetBoundColorDrawBufferType(GLint drawbuffer_i) {
5143   DCHECK(drawbuffer_i >= 0 &&
5144          drawbuffer_i < static_cast<GLint>(group_->max_draw_buffers()));
5145   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
5146   if (!framebuffer) {
5147     return 0;
5148   }
5149   GLenum drawbuffer = static_cast<GLenum>(GL_DRAW_BUFFER0 + drawbuffer_i);
5150   if (framebuffer->GetDrawBuffer(drawbuffer) == GL_NONE) {
5151     return 0;
5152   }
5153   GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer_i);
5154   const Framebuffer::Attachment* buffer =
5155       framebuffer->GetAttachment(attachment);
5156   if (!buffer) {
5157     return 0;
5158   }
5159   return buffer->texture_type();
5160 }
5161 
GetBoundColorDrawBufferInternalFormat(GLint drawbuffer_i)5162 GLenum GLES2DecoderImpl::GetBoundColorDrawBufferInternalFormat(
5163     GLint drawbuffer_i) {
5164   DCHECK(drawbuffer_i >= 0 &&
5165          drawbuffer_i < static_cast<GLint>(group_->max_draw_buffers()));
5166   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
5167   if (!framebuffer) {
5168     return 0;
5169   }
5170   GLenum drawbuffer = static_cast<GLenum>(GL_DRAW_BUFFER0 + drawbuffer_i);
5171   if (framebuffer->GetDrawBuffer(drawbuffer) == GL_NONE) {
5172     return 0;
5173   }
5174   GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer_i);
5175   const Framebuffer::Attachment* buffer =
5176       framebuffer->GetAttachment(attachment);
5177   if (!buffer) {
5178     return 0;
5179   }
5180   return buffer->internal_format();
5181 }
5182 
GetBoundFramebufferSamples(GLenum target)5183 GLsizei GLES2DecoderImpl::GetBoundFramebufferSamples(GLenum target) {
5184   DCHECK(target == GL_DRAW_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER ||
5185          target == GL_FRAMEBUFFER);
5186   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5187   if (framebuffer) {
5188     return framebuffer->GetSamples();
5189   } else {  // Back buffer.
5190     if (offscreen_target_frame_buffer_.get()) {
5191       return offscreen_target_samples_;
5192     }
5193     return 0;
5194   }
5195 }
5196 
GetBoundFramebufferDepthFormat(GLenum target)5197 GLenum GLES2DecoderImpl::GetBoundFramebufferDepthFormat(
5198     GLenum target) {
5199   DCHECK(target == GL_DRAW_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER ||
5200          target == GL_FRAMEBUFFER);
5201   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5202   if (framebuffer) {
5203     return framebuffer->GetDepthFormat();
5204   } else {  // Back buffer.
5205     if (offscreen_target_frame_buffer_.get()) {
5206       return offscreen_target_depth_format_;
5207     }
5208     if (back_buffer_has_depth_)
5209       return GL_DEPTH;
5210     return 0;
5211   }
5212 }
5213 
GetBoundFramebufferStencilFormat(GLenum target)5214 GLenum GLES2DecoderImpl::GetBoundFramebufferStencilFormat(
5215     GLenum target) {
5216   DCHECK(target == GL_DRAW_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER ||
5217          target == GL_FRAMEBUFFER);
5218   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5219   if (framebuffer) {
5220     return framebuffer->GetStencilFormat();
5221   } else {  // Back buffer.
5222     if (offscreen_target_frame_buffer_.get()) {
5223       return offscreen_target_stencil_format_;
5224     }
5225     if (back_buffer_has_stencil_)
5226       return GL_STENCIL;
5227     return 0;
5228   }
5229 }
5230 
MarkDrawBufferAsCleared(GLenum buffer,GLint drawbuffer_i)5231 void GLES2DecoderImpl::MarkDrawBufferAsCleared(
5232     GLenum buffer, GLint drawbuffer_i) {
5233   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
5234   if (!framebuffer)
5235     return;
5236   GLenum attachment  = 0;
5237   switch (buffer) {
5238     case GL_COLOR:
5239       DCHECK(drawbuffer_i >= 0 &&
5240              drawbuffer_i < static_cast<GLint>(group_->max_draw_buffers()));
5241       attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer_i);
5242       break;
5243     case GL_DEPTH:
5244       attachment = GL_DEPTH_ATTACHMENT;
5245       break;
5246     case GL_STENCIL:
5247       attachment = GL_STENCIL_ATTACHMENT;
5248       break;
5249     default:
5250       // Caller is responsible for breaking GL_DEPTH_STENCIL into GL_DEPTH and
5251       // GL_STENCIL.
5252       NOTREACHED();
5253   }
5254   framebuffer->MarkAttachmentAsCleared(
5255       renderbuffer_manager(), texture_manager(), attachment, true);
5256 }
5257 
GetLogger()5258 Logger* GLES2DecoderImpl::GetLogger() {
5259   return &logger_;
5260 }
5261 
BeginDecoding()5262 void GLES2DecoderImpl::BeginDecoding() {
5263   gpu_tracer_->BeginDecoding();
5264   gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
5265   gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_;
5266   query_manager_->ProcessFrameBeginUpdates();
5267   query_manager_->BeginProcessingCommands();
5268 }
5269 
EndDecoding()5270 void GLES2DecoderImpl::EndDecoding() {
5271   gpu_tracer_->EndDecoding();
5272   query_manager_->EndProcessingCommands();
5273 }
5274 
GetErrorState()5275 ErrorState* GLES2DecoderImpl::GetErrorState() {
5276   return error_state_.get();
5277 }
5278 
GetServiceTextureId(uint32_t client_texture_id,uint32_t * service_texture_id)5279 bool GLES2DecoderImpl::GetServiceTextureId(uint32_t client_texture_id,
5280                                            uint32_t* service_texture_id) {
5281   TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
5282   if (texture_ref) {
5283     *service_texture_id = texture_ref->service_id();
5284     return true;
5285   }
5286   return false;
5287 }
5288 
GetTextureBase(uint32_t client_id)5289 TextureBase* GLES2DecoderImpl::GetTextureBase(uint32_t client_id) {
5290   TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
5291   return texture_ref ? texture_ref->texture() : nullptr;
5292 }
5293 
SetLevelInfo(uint32_t client_id,int level,unsigned internal_format,unsigned width,unsigned height,unsigned depth,unsigned format,unsigned type,const gfx::Rect & cleared_rect)5294 void GLES2DecoderImpl::SetLevelInfo(uint32_t client_id,
5295                                     int level,
5296                                     unsigned internal_format,
5297                                     unsigned width,
5298                                     unsigned height,
5299                                     unsigned depth,
5300                                     unsigned format,
5301                                     unsigned type,
5302                                     const gfx::Rect& cleared_rect) {
5303   TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
5304   texture_manager()->SetLevelInfo(texture_ref, texture_ref->texture()->target(),
5305                                   level, internal_format, width, height, depth,
5306                                   0 /* border */, format, type, cleared_rect);
5307 }
5308 
OnGpuSwitched(gl::GpuPreference active_gpu_heuristic)5309 void GLES2DecoderImpl::OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) {
5310   // Send OnGpuSwitched notification to renderer process via decoder client.
5311   client()->OnGpuSwitched(active_gpu_heuristic);
5312 }
5313 
Destroy(bool have_context)5314 void GLES2DecoderImpl::Destroy(bool have_context) {
5315   if (!initialized())
5316     return;
5317 
5318   DCHECK(!have_context || context_->IsCurrent(nullptr));
5319 
5320   // Prepare to destroy the surface while the context is still current, because
5321   // some surface destructors make GL calls.
5322   if (surface_)
5323     surface_->PrepareToDestroy(have_context);
5324 
5325   // Destroy any textures that are pending destruction.
5326   if (!have_context) {
5327     for (auto iter : texture_refs_pending_destruction_)
5328       iter->ForceContextLost();
5329   }
5330   texture_refs_pending_destruction_.clear();
5331 
5332   // Notify any AbstractTextures to drop their texture ref.
5333   for (auto* iter : abstract_textures_)
5334     iter->OnDecoderWillDestroy(have_context);
5335   abstract_textures_.clear();
5336 
5337   ReleaseAllBackTextures(have_context);
5338   if (have_context) {
5339     if (copy_tex_image_blit_.get()) {
5340       copy_tex_image_blit_->Destroy();
5341       copy_tex_image_blit_.reset();
5342     }
5343 
5344     if (copy_texture_chromium_.get()) {
5345       copy_texture_chromium_->Destroy();
5346       copy_texture_chromium_.reset();
5347     }
5348 
5349     if (srgb_converter_.get()) {
5350       srgb_converter_->Destroy();
5351       srgb_converter_.reset();
5352     }
5353 
5354     if (clear_framebuffer_blit_.get()) {
5355       clear_framebuffer_blit_->Destroy();
5356       clear_framebuffer_blit_.reset();
5357     }
5358 
5359     if (state_.current_program.get()) {
5360       program_manager()->UnuseProgram(shader_manager(),
5361                                       state_.current_program.get());
5362     }
5363 
5364     if (attrib_0_buffer_id_) {
5365       api()->glDeleteBuffersARBFn(1, &attrib_0_buffer_id_);
5366     }
5367     if (fixed_attrib_buffer_id_) {
5368       api()->glDeleteBuffersARBFn(1, &fixed_attrib_buffer_id_);
5369     }
5370 
5371     if (validation_fbo_) {
5372       api()->glDeleteFramebuffersEXTFn(1, &validation_fbo_multisample_);
5373       api()->glDeleteFramebuffersEXTFn(1, &validation_fbo_);
5374     }
5375     while (!validation_textures_.empty()) {
5376       GLuint tex;
5377       tex = validation_textures_.begin()->second;
5378       api()->glDeleteTexturesFn(1, &tex);
5379       validation_textures_.erase(validation_textures_.begin());
5380     }
5381 
5382     if (offscreen_target_frame_buffer_.get())
5383       offscreen_target_frame_buffer_->Destroy();
5384     if (offscreen_target_color_texture_.get())
5385       offscreen_target_color_texture_->Destroy();
5386     if (offscreen_target_color_render_buffer_.get())
5387       offscreen_target_color_render_buffer_->Destroy();
5388     if (offscreen_target_depth_render_buffer_.get())
5389       offscreen_target_depth_render_buffer_->Destroy();
5390     if (offscreen_target_stencil_render_buffer_.get())
5391       offscreen_target_stencil_render_buffer_->Destroy();
5392     if (offscreen_saved_frame_buffer_.get())
5393       offscreen_saved_frame_buffer_->Destroy();
5394     if (offscreen_saved_color_texture_.get())
5395       offscreen_saved_color_texture_->Destroy();
5396     if (offscreen_resolved_frame_buffer_.get())
5397       offscreen_resolved_frame_buffer_->Destroy();
5398     if (offscreen_resolved_color_texture_.get())
5399       offscreen_resolved_color_texture_->Destroy();
5400   } else {
5401     if (offscreen_target_frame_buffer_.get())
5402       offscreen_target_frame_buffer_->Invalidate();
5403     if (offscreen_target_color_texture_.get())
5404       offscreen_target_color_texture_->Invalidate();
5405     if (offscreen_target_color_render_buffer_.get())
5406       offscreen_target_color_render_buffer_->Invalidate();
5407     if (offscreen_target_depth_render_buffer_.get())
5408       offscreen_target_depth_render_buffer_->Invalidate();
5409     if (offscreen_target_stencil_render_buffer_.get())
5410       offscreen_target_stencil_render_buffer_->Invalidate();
5411     if (offscreen_saved_frame_buffer_.get())
5412       offscreen_saved_frame_buffer_->Invalidate();
5413     if (offscreen_saved_color_texture_.get())
5414       offscreen_saved_color_texture_->Invalidate();
5415     if (offscreen_resolved_frame_buffer_.get())
5416       offscreen_resolved_frame_buffer_->Invalidate();
5417     if (offscreen_resolved_color_texture_.get())
5418       offscreen_resolved_color_texture_->Invalidate();
5419     for (auto& fence : deschedule_until_finished_fences_) {
5420       fence->Invalidate();
5421     }
5422 
5423     if (group_ && group_->texture_manager())
5424       group_->texture_manager()->MarkContextLost();
5425     state_.MarkContextLost();
5426   }
5427   deschedule_until_finished_fences_.clear();
5428 
5429   ReportProgress();
5430 
5431   // Unbind everything.
5432   state_.vertex_attrib_manager = nullptr;
5433   state_.default_vertex_attrib_manager = nullptr;
5434   state_.texture_units.clear();
5435   state_.sampler_units.clear();
5436   state_.bound_array_buffer = nullptr;
5437   state_.bound_copy_read_buffer = nullptr;
5438   state_.bound_copy_write_buffer = nullptr;
5439   state_.bound_pixel_pack_buffer = nullptr;
5440   state_.bound_pixel_unpack_buffer = nullptr;
5441   state_.bound_transform_feedback_buffer = nullptr;
5442   state_.bound_uniform_buffer = nullptr;
5443   framebuffer_state_.bound_read_framebuffer = nullptr;
5444   framebuffer_state_.bound_draw_framebuffer = nullptr;
5445   state_.current_draw_framebuffer_client_id = 0;
5446   state_.bound_renderbuffer = nullptr;
5447   state_.bound_transform_feedback = nullptr;
5448   state_.default_transform_feedback = nullptr;
5449   state_.indexed_uniform_buffer_bindings = nullptr;
5450 
5451   // Current program must be cleared after calling ProgramManager::UnuseProgram.
5452   // Otherwise, we can leak objects. http://crbug.com/258772.
5453   // state_.current_program must be reset before group_ is reset because
5454   // the later deletes the ProgramManager object that referred by
5455   // state_.current_program object.
5456   state_.current_program = nullptr;
5457 
5458   copy_tex_image_blit_.reset();
5459   copy_texture_chromium_.reset();
5460   srgb_converter_.reset();
5461   clear_framebuffer_blit_.reset();
5462 
5463   ReportProgress();
5464 
5465   if (framebuffer_manager_.get()) {
5466     framebuffer_manager_->Destroy(have_context);
5467     if (group_->texture_manager())
5468       group_->texture_manager()->RemoveFramebufferManager(
5469           framebuffer_manager_.get());
5470     framebuffer_manager_.reset();
5471   }
5472 
5473   multi_draw_manager_.reset();
5474 
5475   if (query_manager_.get()) {
5476     query_manager_->Destroy(have_context);
5477     query_manager_.reset();
5478   }
5479 
5480   if (gpu_fence_manager_.get()) {
5481     gpu_fence_manager_->Destroy(have_context);
5482     gpu_fence_manager_.reset();
5483   }
5484 
5485   if (vertex_array_manager_ .get()) {
5486     vertex_array_manager_->Destroy(have_context);
5487     vertex_array_manager_.reset();
5488   }
5489 
5490   if (transform_feedback_manager_.get()) {
5491     if (!have_context) {
5492       transform_feedback_manager_->MarkContextLost();
5493     }
5494     transform_feedback_manager_->Destroy();
5495     transform_feedback_manager_.reset();
5496   }
5497 
5498   ReportProgress();
5499 
5500   offscreen_target_frame_buffer_.reset();
5501   offscreen_target_color_texture_.reset();
5502   offscreen_target_color_render_buffer_.reset();
5503   offscreen_target_depth_render_buffer_.reset();
5504   offscreen_target_stencil_render_buffer_.reset();
5505   offscreen_saved_frame_buffer_.reset();
5506   offscreen_saved_color_texture_.reset();
5507   offscreen_resolved_frame_buffer_.reset();
5508   offscreen_resolved_color_texture_.reset();
5509 
5510   // Release all fences now, because some fence types need the context to be
5511   // current on destruction.
5512   pending_readpixel_fences_ = base::queue<FenceCallback>();
5513 
5514   // Need to release these before releasing |group_| which may own the
5515   // ShaderTranslatorCache.
5516   DestroyShaderTranslator();
5517 
5518   ReportProgress();
5519 
5520   // Destroy the GPU Tracer which may own some in process GPU Timings.
5521   if (gpu_tracer_) {
5522     gpu_tracer_->Destroy(have_context);
5523     gpu_tracer_.reset();
5524   }
5525 
5526   // Unregister this object as a GPU switching observer.
5527   if (feature_info_->IsWebGLContext()) {
5528     ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
5529   }
5530 
5531   if (group_.get()) {
5532     group_->Destroy(this, have_context);
5533     group_ = nullptr;
5534   }
5535 
5536   if (context_.get()) {
5537     context_->ReleaseCurrent(nullptr);
5538     context_ = nullptr;
5539   }
5540   surface_ = nullptr;
5541 }
5542 
SetSurface(const scoped_refptr<gl::GLSurface> & surface)5543 void GLES2DecoderImpl::SetSurface(const scoped_refptr<gl::GLSurface>& surface) {
5544   DCHECK(context_->IsCurrent(nullptr));
5545   DCHECK(surface);
5546   surface_ = surface;
5547   RestoreCurrentFramebufferBindings();
5548 }
5549 
ReleaseSurface()5550 void GLES2DecoderImpl::ReleaseSurface() {
5551   if (!context_.get())
5552     return;
5553   if (WasContextLost()) {
5554     DLOG(ERROR) << "  GLES2DecoderImpl: Trying to release lost context.";
5555     return;
5556   }
5557   context_->ReleaseCurrent(surface_.get());
5558   surface_ = nullptr;
5559 }
5560 
TakeFrontBuffer(const Mailbox & mailbox)5561 void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) {
5562   if (offscreen_single_buffer_) {
5563     mailbox_manager()->ProduceTexture(
5564         mailbox, offscreen_target_color_texture_->texture_ref()->texture());
5565     return;
5566   }
5567 
5568   if (!offscreen_saved_color_texture_.get()) {
5569     DLOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context";
5570     return;
5571   }
5572 
5573   mailbox_manager()->ProduceTexture(
5574       mailbox, offscreen_saved_color_texture_->texture_ref()->texture());
5575 
5576   // Save the BackTexture and TextureRef. There's no need to update
5577   // |offscreen_saved_frame_buffer_| since CreateBackTexture() will take care of
5578   // that.
5579   SavedBackTexture save;
5580   save.back_texture.swap(offscreen_saved_color_texture_);
5581   save.in_use = true;
5582   saved_back_textures_.push_back(std::move(save));
5583 
5584   CreateBackTexture();
5585 }
5586 
ReturnFrontBuffer(const Mailbox & mailbox,bool is_lost)5587 void GLES2DecoderImpl::ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) {
5588   TextureBase* texture = mailbox_manager()->ConsumeTexture(mailbox);
5589   mailbox_manager()->TextureDeleted(texture);
5590 
5591   if (offscreen_single_buffer_)
5592     return;
5593 
5594   for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
5595        ++it) {
5596     if (texture != it->back_texture->texture_ref()->texture())
5597       continue;
5598 
5599     if (is_lost || it->back_texture->size() != offscreen_size_) {
5600       if (is_lost)
5601         it->back_texture->Invalidate();
5602       else
5603         it->back_texture->Destroy();
5604       saved_back_textures_.erase(it);
5605       return;
5606     }
5607 
5608     it->in_use = false;
5609     return;
5610   }
5611 
5612   DLOG(ERROR) << "Attempting to return a frontbuffer that was not saved.";
5613 }
5614 
HandleCreateGpuFenceINTERNAL(uint32_t immediate_data_size,const volatile void * cmd_data)5615 error::Error GLES2DecoderImpl::HandleCreateGpuFenceINTERNAL(
5616     uint32_t immediate_data_size,
5617     const volatile void* cmd_data) {
5618   const volatile gles2::cmds::CreateGpuFenceINTERNAL& c =
5619       *static_cast<const volatile gles2::cmds::CreateGpuFenceINTERNAL*>(
5620           cmd_data);
5621   if (!features().chromium_gpu_fence) {
5622     return error::kUnknownCommand;
5623   }
5624   GLuint gpu_fence_id = static_cast<GLuint>(c.gpu_fence_id);
5625   if (!GetGpuFenceManager()->CreateGpuFence(gpu_fence_id))
5626     return error::kInvalidArguments;
5627   return error::kNoError;
5628 }
5629 
HandleWaitGpuFenceCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)5630 error::Error GLES2DecoderImpl::HandleWaitGpuFenceCHROMIUM(
5631     uint32_t immediate_data_size,
5632     const volatile void* cmd_data) {
5633   const volatile gles2::cmds::WaitGpuFenceCHROMIUM& c =
5634       *static_cast<const volatile gles2::cmds::WaitGpuFenceCHROMIUM*>(cmd_data);
5635   if (!features().chromium_gpu_fence) {
5636     return error::kUnknownCommand;
5637   }
5638   GLuint gpu_fence_id = static_cast<GLuint>(c.gpu_fence_id);
5639   if (!GetGpuFenceManager()->GpuFenceServerWait(gpu_fence_id))
5640     return error::kInvalidArguments;
5641   return error::kNoError;
5642 }
5643 
HandleDestroyGpuFenceCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)5644 error::Error GLES2DecoderImpl::HandleDestroyGpuFenceCHROMIUM(
5645     uint32_t immediate_data_size,
5646     const volatile void* cmd_data) {
5647   const volatile gles2::cmds::DestroyGpuFenceCHROMIUM& c =
5648       *static_cast<const volatile gles2::cmds::DestroyGpuFenceCHROMIUM*>(
5649           cmd_data);
5650   if (!features().chromium_gpu_fence) {
5651     return error::kUnknownCommand;
5652   }
5653   GLuint gpu_fence_id = static_cast<GLuint>(c.gpu_fence_id);
5654   if (!GetGpuFenceManager()->RemoveGpuFence(gpu_fence_id))
5655     return error::kInvalidArguments;
5656   return error::kNoError;
5657 }
5658 
CreateBackTexture()5659 void GLES2DecoderImpl::CreateBackTexture() {
5660   for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
5661        ++it) {
5662     if (it->in_use)
5663       continue;
5664 
5665     if (it->back_texture->size() != offscreen_size_)
5666       continue;
5667     offscreen_saved_color_texture_ = std::move(it->back_texture);
5668     offscreen_saved_frame_buffer_->AttachRenderTexture(
5669         offscreen_saved_color_texture_.get());
5670     saved_back_textures_.erase(it);
5671     return;
5672   }
5673 
5674   ++create_back_texture_count_for_test_;
5675   offscreen_saved_color_texture_.reset(new BackTexture(this));
5676   offscreen_saved_color_texture_->Create();
5677   offscreen_saved_color_texture_->AllocateStorage(
5678       offscreen_size_, offscreen_saved_color_format_, false);
5679   offscreen_saved_frame_buffer_->AttachRenderTexture(
5680       offscreen_saved_color_texture_.get());
5681 }
5682 
ReleaseNotInUseBackTextures()5683 void GLES2DecoderImpl::ReleaseNotInUseBackTextures() {
5684   for (auto& saved_back_texture : saved_back_textures_) {
5685     if (!saved_back_texture.in_use)
5686       saved_back_texture.back_texture->Destroy();
5687   }
5688 
5689   base::EraseIf(saved_back_textures_,
5690                 [](const SavedBackTexture& saved_back_texture) {
5691                   return !saved_back_texture.in_use;
5692                 });
5693 }
5694 
ReleaseAllBackTextures(bool have_context)5695 void GLES2DecoderImpl::ReleaseAllBackTextures(bool have_context) {
5696   for (auto& saved_back_texture : saved_back_textures_) {
5697     if (have_context)
5698       saved_back_texture.back_texture->Destroy();
5699     else
5700       saved_back_texture.back_texture->Invalidate();
5701   }
5702   saved_back_textures_.clear();
5703 }
5704 
GetSavedBackTextureCountForTest()5705 size_t GLES2DecoderImpl::GetSavedBackTextureCountForTest() {
5706   return saved_back_textures_.size();
5707 }
5708 
GetCreatedBackTextureCountForTest()5709 size_t GLES2DecoderImpl::GetCreatedBackTextureCountForTest() {
5710   return create_back_texture_count_for_test_;
5711 }
5712 
ResizeOffscreenFramebuffer(const gfx::Size & size)5713 bool GLES2DecoderImpl::ResizeOffscreenFramebuffer(const gfx::Size& size) {
5714   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
5715   if (!is_offscreen) {
5716     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer called "
5717                << " with an onscreen framebuffer.";
5718     return false;
5719   }
5720 
5721   if (offscreen_size_ == size)
5722     return true;
5723 
5724   offscreen_size_ = size;
5725   int w = offscreen_size_.width();
5726   int h = offscreen_size_.height();
5727   if (w < 0 || h < 0 || w > max_offscreen_framebuffer_size_ ||
5728       h > max_offscreen_framebuffer_size_) {
5729     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5730                << "to allocate storage due to excessive dimensions.";
5731     return false;
5732   }
5733 
5734   // Reallocate the offscreen target buffers.
5735   DCHECK(offscreen_target_color_format_);
5736   if (IsOffscreenBufferMultisampled()) {
5737     if (!offscreen_target_color_render_buffer_->AllocateStorage(
5738             offscreen_size_, offscreen_target_color_format_,
5739             offscreen_target_samples_)) {
5740       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5741                  << "to allocate storage for offscreen target color buffer.";
5742       return false;
5743     }
5744   } else {
5745     if (!offscreen_target_color_texture_->AllocateStorage(
5746         offscreen_size_, offscreen_target_color_format_, false)) {
5747       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5748                  << "to allocate storage for offscreen target color texture.";
5749       return false;
5750     }
5751   }
5752   if (offscreen_target_depth_format_ &&
5753       !offscreen_target_depth_render_buffer_->AllocateStorage(
5754           offscreen_size_, offscreen_target_depth_format_,
5755           offscreen_target_samples_)) {
5756     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5757                << "to allocate storage for offscreen target depth buffer.";
5758     return false;
5759   }
5760   if (offscreen_target_stencil_format_ &&
5761       !offscreen_target_stencil_render_buffer_->AllocateStorage(
5762           offscreen_size_, offscreen_target_stencil_format_,
5763           offscreen_target_samples_)) {
5764     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5765                << "to allocate storage for offscreen target stencil buffer.";
5766     return false;
5767   }
5768 
5769   // Attach the offscreen target buffers to the target frame buffer.
5770   if (IsOffscreenBufferMultisampled()) {
5771     offscreen_target_frame_buffer_->AttachRenderBuffer(
5772         GL_COLOR_ATTACHMENT0,
5773         offscreen_target_color_render_buffer_.get());
5774   } else {
5775     offscreen_target_frame_buffer_->AttachRenderTexture(
5776         offscreen_target_color_texture_.get());
5777   }
5778   if (offscreen_target_depth_format_) {
5779     offscreen_target_frame_buffer_->AttachRenderBuffer(
5780         GL_DEPTH_ATTACHMENT,
5781         offscreen_target_depth_render_buffer_.get());
5782   }
5783   const bool packed_depth_stencil =
5784       offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
5785   if (packed_depth_stencil) {
5786     offscreen_target_frame_buffer_->AttachRenderBuffer(
5787         GL_STENCIL_ATTACHMENT,
5788         offscreen_target_depth_render_buffer_.get());
5789   } else if (offscreen_target_stencil_format_) {
5790     offscreen_target_frame_buffer_->AttachRenderBuffer(
5791         GL_STENCIL_ATTACHMENT,
5792         offscreen_target_stencil_render_buffer_.get());
5793   }
5794 
5795   if (offscreen_target_frame_buffer_->CheckStatus() !=
5796       GL_FRAMEBUFFER_COMPLETE) {
5797       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
5798                  << "because offscreen FBO was incomplete.";
5799     return false;
5800   }
5801 
5802   // Clear the target frame buffer.
5803   {
5804     ScopedFramebufferBinder binder(this, offscreen_target_frame_buffer_->id());
5805     api()->glClearColorFn(0, 0, 0, BackBufferAlphaClearColor());
5806     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5807     api()->glClearStencilFn(0);
5808     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5809     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
5810     api()->glClearDepthFn(0);
5811     state_.SetDeviceDepthMask(GL_TRUE);
5812     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5813     ClearDeviceWindowRectangles();
5814     api()->glClearFn(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
5815                      GL_STENCIL_BUFFER_BIT);
5816     RestoreClearState();
5817   }
5818 
5819   // Destroy the offscreen resolved framebuffers.
5820   if (offscreen_resolved_frame_buffer_.get())
5821     offscreen_resolved_frame_buffer_->Destroy();
5822   if (offscreen_resolved_color_texture_.get())
5823     offscreen_resolved_color_texture_->Destroy();
5824   offscreen_resolved_color_texture_.reset();
5825   offscreen_resolved_frame_buffer_.reset();
5826 
5827   return true;
5828 }
5829 
HandleResizeCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)5830 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
5831     uint32_t immediate_data_size,
5832     const volatile void* cmd_data) {
5833   const volatile gles2::cmds::ResizeCHROMIUM& c =
5834       *static_cast<const volatile gles2::cmds::ResizeCHROMIUM*>(cmd_data);
5835   if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
5836     return error::kDeferCommandUntilLater;
5837 
5838   GLuint width = static_cast<GLuint>(c.width);
5839   GLuint height = static_cast<GLuint>(c.height);
5840   GLfloat scale_factor = c.scale_factor;
5841   GLboolean has_alpha = c.alpha;
5842   gfx::ColorSpace color_space;
5843   if (!ReadColorSpace(c.shm_id, c.shm_offset, c.color_space_size,
5844                       &color_space)) {
5845     return error::kOutOfBounds;
5846   }
5847   TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
5848 
5849   // gfx::Size uses integers, make sure width and height do not overflow
5850   static_assert(sizeof(GLuint) >= sizeof(int), "Unexpected GLuint size.");
5851   static const GLuint kMaxDimension =
5852       static_cast<GLuint>(std::numeric_limits<int>::max());
5853   width = base::ClampToRange(width, 1U, kMaxDimension);
5854   height = base::ClampToRange(height, 1U, kMaxDimension);
5855 
5856   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
5857   if (is_offscreen) {
5858     if (!ResizeOffscreenFramebuffer(gfx::Size(width, height))) {
5859       LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
5860                  << "ResizeOffscreenFramebuffer failed.";
5861       return error::kLostContext;
5862     }
5863   } else {
5864     if (!surface_->Resize(gfx::Size(width, height), scale_factor, color_space,
5865                           !!has_alpha)) {
5866       LOG(ERROR) << "GLES2DecoderImpl: Context lost because resize failed.";
5867       return error::kLostContext;
5868     }
5869     DCHECK(context_->IsCurrent(surface_.get()));
5870     if (!context_->IsCurrent(surface_.get())) {
5871       LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
5872                  << "current after resize callback.";
5873       return error::kLostContext;
5874     }
5875     if (surface_->BuffersFlipped()) {
5876       backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
5877     }
5878   }
5879 
5880   swaps_since_resize_ = 0;
5881 
5882   return error::kNoError;
5883 }
5884 
GetCommandName(unsigned int command_id) const5885 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
5886   if (command_id >= kFirstGLES2Command && command_id < kNumCommands) {
5887     return gles2::GetCommandName(static_cast<CommandId>(command_id));
5888   }
5889   return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
5890 }
5891 
5892 // Decode multiple commands, and call the corresponding GL functions.
5893 // NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
5894 // changed by a (malicious) client at any time, so if validation has to happen,
5895 // it should operate on a copy of them.
5896 // NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
5897 // interest of performance in this critical execution loop.
5898 template <bool DebugImpl>
DoCommandsImpl(unsigned int num_commands,const volatile void * buffer,int num_entries,int * entries_processed)5899 error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
5900                                               const volatile void* buffer,
5901                                               int num_entries,
5902                                               int* entries_processed) {
5903   DCHECK(entries_processed);
5904   commands_to_process_ = num_commands;
5905   error::Error result = error::kNoError;
5906   const volatile CommandBufferEntry* cmd_data =
5907       static_cast<const volatile CommandBufferEntry*>(buffer);
5908   int process_pos = 0;
5909   unsigned int command = 0;
5910 
5911   while (process_pos < num_entries && result == error::kNoError &&
5912          commands_to_process_--) {
5913     const unsigned int size = cmd_data->value_header.size;
5914     command = cmd_data->value_header.command;
5915 
5916     if (size == 0) {
5917       result = error::kInvalidSize;
5918       break;
5919     }
5920 
5921     if (static_cast<int>(size) + process_pos > num_entries) {
5922       result = error::kOutOfBounds;
5923       break;
5924     }
5925 
5926     if (DebugImpl && log_commands()) {
5927       LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
5928                  << "cmd: " << GetCommandName(command);
5929     }
5930 
5931     const unsigned int arg_count = size - 1;
5932     unsigned int command_index = command - kFirstGLES2Command;
5933     if (command_index < base::size(command_info)) {
5934       const CommandInfo& info = command_info[command_index];
5935       unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
5936       if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
5937           (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
5938         bool doing_gpu_trace = false;
5939         if (DebugImpl && gpu_trace_commands_) {
5940           if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
5941             doing_gpu_trace = true;
5942             gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu.decoder"),
5943                                GetCommandName(command), kTraceDecoder);
5944           }
5945         }
5946 
5947         uint32_t immediate_data_size = (arg_count - info_arg_count) *
5948                                        sizeof(CommandBufferEntry);  // NOLINT
5949 
5950         result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
5951 
5952         if (DebugImpl && doing_gpu_trace)
5953           gpu_tracer_->End(kTraceDecoder);
5954 
5955         if (DebugImpl && debug() && !WasContextLost()) {
5956           GLenum error;
5957           while ((error = api()->glGetErrorFn()) != GL_NO_ERROR) {
5958             LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
5959                        << "GL ERROR: " << GLES2Util::GetStringEnum(error)
5960                        << " : " << GetCommandName(command);
5961             LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
5962           }
5963         }
5964       } else {
5965         result = error::kInvalidArguments;
5966       }
5967     } else {
5968       result = DoCommonCommand(command, arg_count, cmd_data);
5969     }
5970 
5971     if (result == error::kNoError &&
5972         current_decoder_error_ != error::kNoError) {
5973       result = current_decoder_error_;
5974       current_decoder_error_ = error::kNoError;
5975     }
5976 
5977     if (result != error::kDeferCommandUntilLater) {
5978       process_pos += size;
5979       cmd_data += size;
5980     }
5981   }
5982 
5983 #if defined(OS_MACOSX)
5984   // Aggressively call glFlush on macOS. This is the only fix that has been
5985   // found so far to avoid crashes on Intel drivers. The workaround
5986   // isn't needed for WebGL contexts, though.
5987   // https://crbug.com/863817
5988   if (!feature_info_->IsWebGLContext())
5989     context_->FlushForDriverCrashWorkaround();
5990 #endif
5991 
5992   *entries_processed = process_pos;
5993 
5994   if (error::IsError(result)) {
5995     LOG(ERROR) << "Error: " << result << " for Command "
5996                << GetCommandName(command);
5997   }
5998 
5999   return result;
6000 }
6001 
DoCommands(unsigned int num_commands,const volatile void * buffer,int num_entries,int * entries_processed)6002 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
6003                                           const volatile void* buffer,
6004                                           int num_entries,
6005                                           int* entries_processed) {
6006   if (gpu_debug_commands_) {
6007     return DoCommandsImpl<true>(
6008         num_commands, buffer, num_entries, entries_processed);
6009   } else {
6010     return DoCommandsImpl<false>(
6011         num_commands, buffer, num_entries, entries_processed);
6012   }
6013 }
6014 
ExitCommandProcessingEarly()6015 void GLES2DecoderImpl::ExitCommandProcessingEarly() {
6016   commands_to_process_ = 0;
6017 }
6018 
DoFinish()6019 void GLES2DecoderImpl::DoFinish() {
6020   api()->glFinishFn();
6021   ProcessPendingReadPixels(true);
6022   ProcessPendingQueries(true);
6023 }
6024 
DoFlush()6025 void GLES2DecoderImpl::DoFlush() {
6026   api()->glFlushFn();
6027   ProcessPendingQueries(false);
6028 }
6029 
DoActiveTexture(GLenum texture_unit)6030 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
6031   GLuint texture_index = texture_unit - GL_TEXTURE0;
6032   if (texture_index >= state_.texture_units.size()) {
6033     LOCAL_SET_GL_ERROR_INVALID_ENUM(
6034         "glActiveTexture", texture_unit, "texture_unit");
6035     return;
6036   }
6037   state_.active_texture_unit = texture_index;
6038   api()->glActiveTextureFn(texture_unit);
6039 }
6040 
DoBindBuffer(GLenum target,GLuint client_id)6041 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
6042   Buffer* buffer = nullptr;
6043   GLuint service_id = 0;
6044   if (client_id != 0) {
6045     buffer = GetBuffer(client_id);
6046     if (!buffer) {
6047       if (!group_->bind_generates_resource()) {
6048         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6049                            "glBindBuffer",
6050                            "id not generated by glGenBuffers");
6051         return;
6052       }
6053 
6054       // It's a new id so make a buffer buffer for it.
6055       api()->glGenBuffersARBFn(1, &service_id);
6056       CreateBuffer(client_id, service_id);
6057       buffer = GetBuffer(client_id);
6058     }
6059   }
6060   LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
6061   if (buffer) {
6062     if (!buffer_manager()->SetTarget(buffer, target)) {
6063       LOCAL_SET_GL_ERROR(
6064           GL_INVALID_OPERATION,
6065           "glBindBuffer", "buffer bound to more than 1 target");
6066       return;
6067     }
6068     service_id = buffer->service_id();
6069   }
6070   state_.SetBoundBuffer(target, buffer);
6071   api()->glBindBufferFn(target, service_id);
6072 }
6073 
BindIndexedBufferImpl(GLenum target,GLuint index,GLuint client_id,GLintptr offset,GLsizeiptr size,BindIndexedBufferFunctionType function_type,const char * function_name)6074 void GLES2DecoderImpl::BindIndexedBufferImpl(
6075     GLenum target, GLuint index, GLuint client_id,
6076     GLintptr offset, GLsizeiptr size,
6077     BindIndexedBufferFunctionType function_type, const char* function_name) {
6078   switch (target) {
6079     case GL_TRANSFORM_FEEDBACK_BUFFER: {
6080       if (index >= group_->max_transform_feedback_separate_attribs()) {
6081         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
6082                            "index out of range");
6083         return;
6084       }
6085       DCHECK(state_.bound_transform_feedback.get());
6086       if (state_.bound_transform_feedback->active()) {
6087         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6088                            "bound transform feedback is active");
6089         return;
6090       }
6091       break;
6092     }
6093     case GL_UNIFORM_BUFFER: {
6094       if (index >= group_->max_uniform_buffer_bindings()) {
6095         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
6096                            "index out of range");
6097         return;
6098       }
6099       break;
6100     }
6101     default:
6102       NOTREACHED();
6103       break;
6104   }
6105 
6106   if (function_type == BindIndexedBufferFunctionType::kBindBufferRange) {
6107     switch (target) {
6108       case GL_TRANSFORM_FEEDBACK_BUFFER:
6109         if ((size % 4 != 0) || (offset % 4 != 0)) {
6110           LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
6111                              "size or offset are not multiples of 4");
6112           return;
6113         }
6114         break;
6115       case GL_UNIFORM_BUFFER: {
6116         if (offset % group_->uniform_buffer_offset_alignment() != 0) {
6117           LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
6118               "offset is not a multiple of UNIFORM_BUFFER_OFFSET_ALIGNMENT");
6119           return;
6120         }
6121         break;
6122       }
6123       default:
6124         NOTREACHED();
6125         break;
6126     }
6127 
6128     if (client_id != 0) {
6129       if (size <= 0) {
6130         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "size <= 0");
6131         return;
6132       }
6133       if (offset < 0) {
6134         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
6135         return;
6136       }
6137     }
6138   }
6139 
6140   Buffer* buffer = nullptr;
6141   GLuint service_id = 0;
6142   if (client_id != 0) {
6143     buffer = GetBuffer(client_id);
6144     if (!buffer) {
6145       if (!group_->bind_generates_resource()) {
6146         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6147                            "id not generated by glGenBuffers");
6148         return;
6149       }
6150 
6151       // It's a new id so make a buffer for it.
6152       api()->glGenBuffersARBFn(1, &service_id);
6153       CreateBuffer(client_id, service_id);
6154       buffer = GetBuffer(client_id);
6155       DCHECK(buffer);
6156     }
6157     if (!buffer_manager()->SetTarget(buffer, target)) {
6158       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6159                          "buffer bound to more than 1 target");
6160       return;
6161     }
6162     service_id = buffer->service_id();
6163   }
6164   LogClientServiceForInfo(buffer, client_id, function_name);
6165 
6166   scoped_refptr<IndexedBufferBindingHost> bindings;
6167   switch (target) {
6168     case GL_TRANSFORM_FEEDBACK_BUFFER:
6169       bindings = state_.bound_transform_feedback.get();
6170       break;
6171     case GL_UNIFORM_BUFFER:
6172       bindings = state_.indexed_uniform_buffer_bindings.get();
6173       break;
6174     default:
6175       NOTREACHED();
6176       break;
6177   }
6178   DCHECK(bindings);
6179   switch (function_type) {
6180     case BindIndexedBufferFunctionType::kBindBufferBase:
6181       bindings->DoBindBufferBase(index, buffer);
6182       break;
6183     case BindIndexedBufferFunctionType::kBindBufferRange:
6184       bindings->DoBindBufferRange(index, buffer, offset, size);
6185       break;
6186     default:
6187       NOTREACHED();
6188       break;
6189   }
6190   state_.SetBoundBuffer(target, buffer);
6191 }
6192 
DoBindBufferBase(GLenum target,GLuint index,GLuint client_id)6193 void GLES2DecoderImpl::DoBindBufferBase(GLenum target, GLuint index,
6194                                         GLuint client_id) {
6195   BindIndexedBufferImpl(target, index, client_id, 0, 0,
6196                         BindIndexedBufferFunctionType::kBindBufferBase,
6197                         "glBindBufferBase");
6198 }
6199 
DoBindBufferRange(GLenum target,GLuint index,GLuint client_id,GLintptr offset,GLsizeiptr size)6200 void GLES2DecoderImpl::DoBindBufferRange(GLenum target, GLuint index,
6201                                          GLuint client_id,
6202                                          GLintptr offset,
6203                                          GLsizeiptr size) {
6204   BindIndexedBufferImpl(target, index, client_id, offset, size,
6205                         BindIndexedBufferFunctionType::kBindBufferRange,
6206                         "glBindBufferRange");
6207 }
6208 
BoundFramebufferAllowsChangesToAlphaChannel()6209 bool GLES2DecoderImpl::BoundFramebufferAllowsChangesToAlphaChannel() {
6210   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
6211   if (framebuffer)
6212     return framebuffer->HasAlphaMRT();
6213   if (back_buffer_draw_buffer_ == GL_NONE)
6214     return false;
6215   if (offscreen_target_frame_buffer_.get()) {
6216     GLenum format = offscreen_target_color_format_;
6217     return (format == GL_RGBA || format == GL_RGBA8) &&
6218            offscreen_buffer_should_have_alpha_;
6219   }
6220   return (back_buffer_color_format_ == GL_RGBA ||
6221           back_buffer_color_format_ == GL_RGBA8);
6222 }
6223 
BoundFramebufferHasDepthAttachment()6224 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
6225   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
6226   if (framebuffer) {
6227     return framebuffer->HasDepthAttachment();
6228   }
6229   if (offscreen_target_frame_buffer_.get()) {
6230     return offscreen_target_depth_format_ != 0;
6231   }
6232   return back_buffer_has_depth_;
6233 }
6234 
BoundFramebufferHasStencilAttachment()6235 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
6236   Framebuffer* framebuffer = GetBoundDrawFramebuffer();
6237   if (framebuffer) {
6238     return framebuffer->HasStencilAttachment();
6239   }
6240   if (offscreen_target_frame_buffer_.get()) {
6241     return offscreen_target_stencil_format_ != 0 ||
6242            offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
6243   }
6244   return back_buffer_has_stencil_;
6245 }
6246 
ApplyDirtyState()6247 void GLES2DecoderImpl::ApplyDirtyState() {
6248   if (framebuffer_state_.clear_state_dirty) {
6249     bool allows_alpha_change = BoundFramebufferAllowsChangesToAlphaChannel();
6250     state_.SetDeviceColorMask(state_.color_mask_red, state_.color_mask_green,
6251                               state_.color_mask_blue,
6252                               state_.color_mask_alpha && allows_alpha_change);
6253 
6254     bool have_depth = BoundFramebufferHasDepthAttachment();
6255     state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
6256 
6257     bool have_stencil = BoundFramebufferHasStencilAttachment();
6258     state_.SetDeviceStencilMaskSeparate(
6259         GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
6260     state_.SetDeviceStencilMaskSeparate(
6261         GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
6262 
6263     state_.SetDeviceCapabilityState(
6264         GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
6265     state_.SetDeviceCapabilityState(
6266         GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
6267     framebuffer_state_.clear_state_dirty = false;
6268   }
6269 }
6270 
GetBackbufferServiceId() const6271 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
6272   return (offscreen_target_frame_buffer_.get())
6273              ? offscreen_target_frame_buffer_->id()
6274              : (surface_.get() ? surface_->GetBackingFramebufferObject() : 0);
6275 }
6276 
RestoreState(const ContextState * prev_state)6277 void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
6278   TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
6279                "context", logger_.GetLogPrefix());
6280   // Restore the Framebuffer first because of bugs in Intel drivers.
6281   // Intel drivers incorrectly clip the viewport settings to
6282   // the size of the current framebuffer object.
6283   RestoreFramebufferBindings();
6284   state_.RestoreState(prev_state);
6285 }
6286 
RestoreBufferBinding(unsigned int target)6287 void GLES2DecoderImpl::RestoreBufferBinding(unsigned int target) {
6288   if (target == GL_PIXEL_PACK_BUFFER) {
6289     state_.UpdatePackParameters();
6290   } else if (target == GL_PIXEL_UNPACK_BUFFER) {
6291     state_.UpdateUnpackParameters();
6292   }
6293   Buffer* bound_buffer =
6294       buffer_manager()->GetBufferInfoForTarget(&state_, target);
6295   api()->glBindBufferFn(target, bound_buffer ? bound_buffer->service_id() : 0);
6296 }
6297 
RestoreFramebufferBindings() const6298 void GLES2DecoderImpl::RestoreFramebufferBindings() const {
6299   GLuint service_id =
6300       framebuffer_state_.bound_draw_framebuffer.get()
6301           ? framebuffer_state_.bound_draw_framebuffer->service_id()
6302           : GetBackbufferServiceId();
6303   if (!SupportsSeparateFramebufferBinds()) {
6304     api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, service_id);
6305   } else {
6306     api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, service_id);
6307     service_id = framebuffer_state_.bound_read_framebuffer.get()
6308                      ? framebuffer_state_.bound_read_framebuffer->service_id()
6309                      : GetBackbufferServiceId();
6310     api()->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER, service_id);
6311   }
6312   OnFboChanged();
6313 }
6314 
RestoreRenderbufferBindings()6315 void GLES2DecoderImpl::RestoreRenderbufferBindings() {
6316   state_.RestoreRenderbufferBindings();
6317 }
6318 
RestoreTextureState(unsigned service_id)6319 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) {
6320   Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
6321   if (texture) {
6322     GLenum target = texture->target();
6323     api()->glBindTextureFn(target, service_id);
6324     api()->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, texture->wrap_s());
6325     api()->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, texture->wrap_t());
6326     api()->glTexParameteriFn(target, GL_TEXTURE_MIN_FILTER,
6327                              texture->min_filter());
6328     api()->glTexParameteriFn(target, GL_TEXTURE_MAG_FILTER,
6329                              texture->mag_filter());
6330     if (feature_info_->IsWebGL2OrES3Context()) {
6331       api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
6332                                texture->base_level());
6333     }
6334     RestoreTextureUnitBindings(state_.active_texture_unit);
6335   }
6336 }
6337 
ClearDeviceWindowRectangles() const6338 void GLES2DecoderImpl::ClearDeviceWindowRectangles() const {
6339   if (!feature_info_->feature_flags().ext_window_rectangles) {
6340     return;
6341   }
6342   api()->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
6343 }
6344 
RestoreDeviceWindowRectangles() const6345 void GLES2DecoderImpl::RestoreDeviceWindowRectangles() const {
6346   state_.UpdateWindowRectangles();
6347 }
6348 
ClearAllAttributes() const6349 void GLES2DecoderImpl::ClearAllAttributes() const {
6350   // Must use native VAO 0, as RestoreAllAttributes can't fully restore
6351   // other VAOs.
6352   if (feature_info_->feature_flags().native_vertex_array_object)
6353     api()->glBindVertexArrayOESFn(0);
6354 
6355   for (uint32_t i = 0; i < group_->max_vertex_attribs(); ++i) {
6356     if (i != 0)  // Never disable attribute 0
6357       state_.vertex_attrib_manager->SetDriverVertexAttribEnabled(i, false);
6358     if (features().angle_instanced_arrays)
6359       api()->glVertexAttribDivisorANGLEFn(i, 0);
6360   }
6361 }
6362 
RestoreAllAttributes() const6363 void GLES2DecoderImpl::RestoreAllAttributes() const {
6364   state_.RestoreVertexAttribs(nullptr);
6365 }
6366 
SetIgnoreCachedStateForTest(bool ignore)6367 void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
6368   state_.SetIgnoreCachedStateForTest(ignore);
6369 }
6370 
SetForceShaderNameHashingForTest(bool force)6371 void GLES2DecoderImpl::SetForceShaderNameHashingForTest(bool force) {
6372   force_shader_name_hashing_for_test = force;
6373 }
6374 
6375 // Added specifically for testing backbuffer_needs_clear_bits unittests.
GetAndClearBackbufferClearBitsForTest()6376 uint32_t GLES2DecoderImpl::GetAndClearBackbufferClearBitsForTest() {
6377   uint32_t clear_bits = backbuffer_needs_clear_bits_;
6378   backbuffer_needs_clear_bits_ = 0;
6379   return clear_bits;
6380 }
6381 
OnFboChanged() const6382 void GLES2DecoderImpl::OnFboChanged() const {
6383   state_.fbo_binding_for_scissor_workaround_dirty = true;
6384   state_.stencil_state_changed_since_validation = true;
6385 
6386   if (workarounds().flush_on_framebuffer_change)
6387     api()->glFlushFn();
6388 }
6389 
6390 // Called after the FBO is checked for completeness.
OnUseFramebuffer() const6391 void GLES2DecoderImpl::OnUseFramebuffer() const {
6392   if (!state_.fbo_binding_for_scissor_workaround_dirty)
6393     return;
6394   state_.fbo_binding_for_scissor_workaround_dirty = false;
6395 
6396   if (supports_dc_layers_) {
6397     gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset();
6398     api()->glViewportFn(state_.viewport_x + draw_offset.x(),
6399                         state_.viewport_y + draw_offset.y(),
6400                         state_.viewport_width, state_.viewport_height);
6401   }
6402 
6403   if (workarounds().restore_scissor_on_fbo_change || supports_dc_layers_) {
6404     // The driver forgets the correct scissor when modifying the FBO binding.
6405     gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
6406     api()->glScissorFn(state_.scissor_x + scissor_offset.x(),
6407                        state_.scissor_y + scissor_offset.y(),
6408                        state_.scissor_width, state_.scissor_height);
6409   }
6410 
6411   if (workarounds().restore_scissor_on_fbo_change) {
6412     // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
6413     // it's unclear how this bug works.
6414     api()->glFlushFn();
6415   }
6416 
6417   if (workarounds().force_update_scissor_state_when_binding_fbo0 &&
6418       GetBoundDrawFramebufferServiceId() == 0) {
6419     // The theory is that FBO0 keeps some internal (in HW regs maybe?) scissor
6420     // test state, but the driver forgets to update it with GL_SCISSOR_TEST
6421     // when FBO0 gets bound. (So it stuck with whatever state we last switched
6422     // from it.)
6423     // If the internal scissor test state was enabled, it does update its
6424     // internal scissor rect with GL_SCISSOR_BOX though.
6425     if (state_.enable_flags.cached_scissor_test) {
6426       // The driver early outs if the new state matches previous state so some
6427       // shake up is needed.
6428       api()->glDisableFn(GL_SCISSOR_TEST);
6429       api()->glEnableFn(GL_SCISSOR_TEST);
6430     } else {
6431       // Ditto.
6432       api()->glEnableFn(GL_SCISSOR_TEST);
6433       api()->glDisableFn(GL_SCISSOR_TEST);
6434     }
6435   }
6436 }
6437 
DoBindFramebuffer(GLenum target,GLuint client_id)6438 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
6439   Framebuffer* framebuffer = nullptr;
6440   GLuint service_id = 0;
6441   if (client_id != 0) {
6442     framebuffer = GetFramebuffer(client_id);
6443     if (!framebuffer) {
6444       if (!group_->bind_generates_resource()) {
6445         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6446                            "glBindFramebuffer",
6447                            "id not generated by glGenFramebuffers");
6448         return;
6449       }
6450 
6451       // It's a new id so make a framebuffer framebuffer for it.
6452       api()->glGenFramebuffersEXTFn(1, &service_id);
6453       CreateFramebuffer(client_id, service_id);
6454       framebuffer = GetFramebuffer(client_id);
6455     } else {
6456       service_id = framebuffer->service_id();
6457     }
6458     framebuffer->MarkAsValid();
6459   }
6460   LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
6461 
6462   if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
6463     framebuffer_state_.bound_draw_framebuffer = framebuffer;
6464     state_.UpdateWindowRectanglesForBoundDrawFramebufferClientID(client_id);
6465   }
6466 
6467   // vmiura: This looks like dup code
6468   if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
6469     framebuffer_state_.bound_read_framebuffer = framebuffer;
6470   }
6471 
6472   framebuffer_state_.clear_state_dirty = true;
6473 
6474   // If we are rendering to the backbuffer get the FBO id for any simulated
6475   // backbuffer.
6476   if (framebuffer == nullptr) {
6477     service_id = GetBackbufferServiceId();
6478   }
6479 
6480   api()->glBindFramebufferEXTFn(target, service_id);
6481   OnFboChanged();
6482 }
6483 
DoBindRenderbuffer(GLenum target,GLuint client_id)6484 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
6485   DCHECK_EQ(target, (GLenum)GL_RENDERBUFFER);
6486   Renderbuffer* renderbuffer = nullptr;
6487   GLuint service_id = 0;
6488   if (client_id != 0) {
6489     renderbuffer = GetRenderbuffer(client_id);
6490     if (!renderbuffer) {
6491       if (!group_->bind_generates_resource()) {
6492         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6493                            "glBindRenderbuffer",
6494                            "id not generated by glGenRenderbuffers");
6495         return;
6496       }
6497 
6498       // It's a new id so make a renderbuffer for it.
6499       api()->glGenRenderbuffersEXTFn(1, &service_id);
6500       CreateRenderbuffer(client_id, service_id);
6501       renderbuffer = GetRenderbuffer(client_id);
6502     } else {
6503       service_id = renderbuffer->service_id();
6504     }
6505     renderbuffer->MarkAsValid();
6506   }
6507   LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
6508   state_.bound_renderbuffer = renderbuffer;
6509   state_.bound_renderbuffer_valid = true;
6510   api()->glBindRenderbufferEXTFn(GL_RENDERBUFFER, service_id);
6511 }
6512 
DoBindTexture(GLenum target,GLuint client_id)6513 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
6514   TextureRef* texture_ref = nullptr;
6515   GLuint service_id = 0;
6516   if (client_id != 0) {
6517     texture_ref = GetTexture(client_id);
6518     if (!texture_ref) {
6519       if (!group_->bind_generates_resource()) {
6520         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6521                            "glBindTexture",
6522                            "id not generated by glGenTextures");
6523         return;
6524       }
6525 
6526       // It's a new id so make a texture texture for it.
6527       api()->glGenTexturesFn(1, &service_id);
6528       DCHECK_NE(0u, service_id);
6529       CreateTexture(client_id, service_id);
6530       texture_ref = GetTexture(client_id);
6531     }
6532   } else {
6533     texture_ref = texture_manager()->GetDefaultTextureInfo(target);
6534   }
6535 
6536   // Check the texture exists
6537   if (texture_ref) {
6538     Texture* texture = texture_ref->texture();
6539     // Check that we are not trying to bind it to a different target.
6540     if (texture->target() != 0 && texture->target() != target) {
6541       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6542                          "glBindTexture",
6543                          "texture bound to more than 1 target.");
6544       return;
6545     }
6546     LogClientServiceForInfo(texture, client_id, "glBindTexture");
6547     api()->glBindTextureFn(target, texture->service_id());
6548     if (texture->target() == 0) {
6549       texture_manager()->SetTarget(texture_ref, target);
6550       if (!gl_version_info().BehavesLikeGLES() &&
6551           gl_version_info().IsAtLeastGL(3, 2)) {
6552         // In Desktop GL core profile and GL ES, depth textures are always
6553         // sampled to the RED channel, whereas on Desktop GL compatibility
6554         // proifle, they are sampled to RED, LUMINANCE, INTENSITY, or ALPHA
6555         // channel, depending on the DEPTH_TEXTURE_MODE value.
6556         // In theory we only need to apply this for depth textures, but it is
6557         // simpler to apply to all textures.
6558         api()->glTexParameteriFn(target, GL_DEPTH_TEXTURE_MODE, GL_RED);
6559       }
6560     }
6561   } else {
6562     api()->glBindTextureFn(target, 0);
6563   }
6564 
6565   TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
6566   unit.bind_target = target;
6567   unit.SetInfoForTarget(target, texture_ref);
6568 }
6569 
DoBindSampler(GLuint unit,GLuint client_id)6570 void GLES2DecoderImpl::DoBindSampler(GLuint unit, GLuint client_id) {
6571   if (unit >= group_->max_texture_units()) {
6572     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBindSampler", "unit out of bounds");
6573     return;
6574   }
6575   Sampler* sampler = nullptr;
6576   if (client_id != 0) {
6577     sampler = GetSampler(client_id);
6578     if (!sampler) {
6579       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6580                          "glBindSampler",
6581                          "id not generated by glGenSamplers");
6582       return;
6583     }
6584   }
6585 
6586   // Check the sampler exists
6587   if (sampler) {
6588     LogClientServiceForInfo(sampler, client_id, "glBindSampler");
6589     api()->glBindSamplerFn(unit, sampler->service_id());
6590   } else {
6591     api()->glBindSamplerFn(unit, 0);
6592   }
6593 
6594   state_.sampler_units[unit] = sampler;
6595 }
6596 
DoBindTransformFeedback(GLenum target,GLuint client_id)6597 void GLES2DecoderImpl::DoBindTransformFeedback(
6598     GLenum target, GLuint client_id) {
6599   const char* function_name = "glBindTransformFeedback";
6600 
6601   TransformFeedback* transform_feedback = nullptr;
6602   if (client_id != 0) {
6603     transform_feedback = GetTransformFeedback(client_id);
6604     if (!transform_feedback) {
6605       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6606                          "id not generated by glGenTransformFeedbacks");
6607       return;
6608     }
6609   } else {
6610     transform_feedback = state_.default_transform_feedback.get();
6611   }
6612   DCHECK(transform_feedback);
6613   if (transform_feedback == state_.bound_transform_feedback.get())
6614     return;
6615   if (state_.bound_transform_feedback->active() &&
6616       !state_.bound_transform_feedback->paused()) {
6617     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6618                        "currently bound transform feedback is active");
6619     return;
6620   }
6621   LogClientServiceForInfo(transform_feedback, client_id, function_name);
6622   transform_feedback->DoBindTransformFeedback(
6623       target, state_.bound_transform_feedback.get(),
6624       state_.bound_transform_feedback_buffer.get());
6625   state_.bound_transform_feedback = transform_feedback;
6626 }
6627 
DoBeginTransformFeedback(GLenum primitive_mode)6628 void GLES2DecoderImpl::DoBeginTransformFeedback(GLenum primitive_mode) {
6629   const char* function_name = "glBeginTransformFeedback";
6630   TransformFeedback* transform_feedback = state_.bound_transform_feedback.get();
6631   DCHECK(transform_feedback);
6632   if (transform_feedback->active()) {
6633     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6634                        "transform feedback is already active");
6635     return;
6636   }
6637   if (!CheckCurrentProgram(function_name)) {
6638     return;
6639   }
6640   Program* program = state_.current_program.get();
6641   DCHECK(program);
6642   size_t required_buffer_count =
6643       program->effective_transform_feedback_varyings().size();
6644   if (required_buffer_count == 0) {
6645     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6646                        "no active transform feedback varyings");
6647     return;
6648   }
6649   if (required_buffer_count > 1 &&
6650       GL_INTERLEAVED_ATTRIBS ==
6651           program->effective_transform_feedback_buffer_mode()) {
6652     required_buffer_count = 1;
6653   }
6654   for (size_t ii = 0; ii < required_buffer_count; ++ii) {
6655     Buffer* buffer = transform_feedback->GetBufferBinding(ii);
6656     if (!buffer) {
6657       std::string msg = base::StringPrintf("missing buffer bound at index %i",
6658                                            static_cast<int>(ii));
6659       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str());
6660       return;
6661     }
6662     if (buffer->GetMappedRange()) {
6663       std::string msg = base::StringPrintf(
6664           "bound buffer bound at index %i is mapped", static_cast<int>(ii));
6665       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str());
6666       return;
6667     }
6668     if (buffer->IsDoubleBoundForTransformFeedback()) {
6669       std::string msg = base::StringPrintf(
6670           "buffer at index %i is bound for multiple transform feedback outputs",
6671           static_cast<int>(ii));
6672       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str());
6673       return;
6674     }
6675   }
6676   transform_feedback->DoBeginTransformFeedback(primitive_mode);
6677   DCHECK(transform_feedback->active());
6678 }
6679 
DoEndTransformFeedback()6680 void GLES2DecoderImpl::DoEndTransformFeedback() {
6681   const char* function_name = "glEndTransformFeedback";
6682   DCHECK(state_.bound_transform_feedback.get());
6683   if (!state_.bound_transform_feedback->active()) {
6684     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6685                        "transform feedback is not active");
6686     return;
6687   }
6688   // TODO(zmo): Validate binding points.
6689   state_.bound_transform_feedback->DoEndTransformFeedback();
6690 }
6691 
DoPauseTransformFeedback()6692 void GLES2DecoderImpl::DoPauseTransformFeedback() {
6693   DCHECK(state_.bound_transform_feedback.get());
6694   if (!state_.bound_transform_feedback->active() ||
6695       state_.bound_transform_feedback->paused()) {
6696     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPauseTransformFeedback",
6697                        "transform feedback is not active or already paused");
6698     return;
6699   }
6700   state_.bound_transform_feedback->DoPauseTransformFeedback();
6701 }
6702 
DoResumeTransformFeedback()6703 void GLES2DecoderImpl::DoResumeTransformFeedback() {
6704   DCHECK(state_.bound_transform_feedback.get());
6705   if (!state_.bound_transform_feedback->active() ||
6706       !state_.bound_transform_feedback->paused()) {
6707     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glResumeTransformFeedback",
6708                        "transform feedback is not active or not paused");
6709     return;
6710   }
6711   if (workarounds().rebind_transform_feedback_before_resume) {
6712     api()->glBindTransformFeedbackFn(GL_TRANSFORM_FEEDBACK, 0);
6713     api()->glBindTransformFeedbackFn(
6714         GL_TRANSFORM_FEEDBACK, state_.bound_transform_feedback->service_id());
6715   }
6716   state_.bound_transform_feedback->DoResumeTransformFeedback();
6717 }
6718 
DoDisableVertexAttribArray(GLuint index)6719 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
6720   if (state_.vertex_attrib_manager->Enable(index, false)) {
6721     if (index != 0 || gl_version_info().BehavesLikeGLES()) {
6722       state_.vertex_attrib_manager->SetDriverVertexAttribEnabled(index, false);
6723     }
6724   } else {
6725     LOCAL_SET_GL_ERROR(
6726         GL_INVALID_VALUE,
6727         "glDisableVertexAttribArray", "index out of range");
6728   }
6729 }
6730 
InvalidateFramebufferImpl(GLenum target,GLsizei count,const volatile GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height,const char * function_name,FramebufferOperation op)6731 void GLES2DecoderImpl::InvalidateFramebufferImpl(
6732     GLenum target,
6733     GLsizei count,
6734     const volatile GLenum* attachments,
6735     GLint x,
6736     GLint y,
6737     GLsizei width,
6738     GLsizei height,
6739     const char* function_name,
6740     FramebufferOperation op) {
6741   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
6742 
6743   // Because of performance issues, no-op if the format of the attachment is
6744   // DEPTH_STENCIL and only one part is intended to be invalidated.
6745   bool has_depth_stencil_format = framebuffer &&
6746       framebuffer->HasDepthStencilFormatAttachment();
6747   bool invalidate_depth = false;
6748   bool invalidate_stencil = false;
6749   std::unique_ptr<GLenum[]> validated_attachments(new GLenum[count+1]);
6750   GLsizei validated_count = 0;
6751 
6752   // Validates the attachments. If one of them fails, the whole command fails.
6753   GLenum thresh0 = GL_COLOR_ATTACHMENT0 + group_->max_color_attachments();
6754   GLenum thresh1 = GL_COLOR_ATTACHMENT15;
6755   for (GLsizei i = 0; i < count; ++i) {
6756     GLenum attachment = attachments[i];
6757     if (framebuffer) {
6758       if (attachment >= thresh0 && attachment <= thresh1) {
6759         LOCAL_SET_GL_ERROR(
6760             GL_INVALID_OPERATION, function_name, "invalid attachment");
6761         return;
6762       }
6763       if (!validators_->attachment.IsValid(attachment)) {
6764         LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, attachment,
6765                                         "attachments");
6766         return;
6767       }
6768       if (has_depth_stencil_format) {
6769         switch (attachment) {
6770           case GL_DEPTH_ATTACHMENT:
6771             invalidate_depth = true;
6772             continue;
6773           case GL_STENCIL_ATTACHMENT:
6774             invalidate_stencil = true;
6775             continue;
6776           case GL_DEPTH_STENCIL_ATTACHMENT:
6777             invalidate_depth = true;
6778             invalidate_stencil = true;
6779             continue;
6780         }
6781       }
6782     } else {
6783       if (!validators_->backbuffer_attachment.IsValid(attachment)) {
6784         LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, attachment,
6785                                         "attachments");
6786         return;
6787       }
6788     }
6789     validated_attachments[validated_count++] = attachment;
6790   }
6791   if (invalidate_depth && invalidate_stencil) {
6792     // We do not use GL_DEPTH_STENCIL_ATTACHMENT here because
6793     // it is not a valid token for glDiscardFramebufferEXT.
6794     validated_attachments[validated_count++] = GL_DEPTH_ATTACHMENT;
6795     validated_attachments[validated_count++] = GL_STENCIL_ATTACHMENT;
6796   }
6797 
6798   // If the default framebuffer is bound but we are still rendering to an
6799   // FBO, translate attachment names that refer to default framebuffer
6800   // channels to corresponding framebuffer attachments.
6801   std::unique_ptr<GLenum[]> translated_attachments(new GLenum[validated_count]);
6802   for (GLsizei i = 0; i < validated_count; ++i) {
6803     GLenum attachment = validated_attachments[i];
6804     if (!framebuffer && GetBackbufferServiceId()) {
6805       switch (attachment) {
6806         case GL_COLOR_EXT:
6807           attachment = GL_COLOR_ATTACHMENT0;
6808           break;
6809         case GL_DEPTH_EXT:
6810           attachment = GL_DEPTH_ATTACHMENT;
6811           break;
6812         case GL_STENCIL_EXT:
6813           attachment = GL_STENCIL_ATTACHMENT;
6814           break;
6815         default:
6816           NOTREACHED();
6817           return;
6818       }
6819     }
6820     translated_attachments[i] = attachment;
6821   }
6822 
6823   bool dirty = false;
6824   switch (op) {
6825     case kFramebufferDiscard:
6826       if (gl_version_info().is_es3) {
6827         api()->glInvalidateFramebufferFn(target, validated_count,
6828                                          translated_attachments.get());
6829       } else {
6830         api()->glDiscardFramebufferEXTFn(target, validated_count,
6831                                          translated_attachments.get());
6832       }
6833       dirty = true;
6834       break;
6835     case kFramebufferInvalidate:
6836       if (gl_version_info().IsLowerThanGL(4, 3)) {
6837         // no-op since the function isn't supported.
6838       } else {
6839         api()->glInvalidateFramebufferFn(target, validated_count,
6840                                          translated_attachments.get());
6841         dirty = true;
6842       }
6843       break;
6844     case kFramebufferInvalidateSub:
6845       // Make it an no-op because we don't have a mechanism to mark partial
6846       // pixels uncleared yet.
6847       // TODO(zmo): Revisit this.
6848       break;
6849   }
6850 
6851   if (!dirty)
6852     return;
6853 
6854   // Marks each one of them as not cleared.
6855   for (GLsizei i = 0; i < validated_count; ++i) {
6856     if (framebuffer) {
6857       if (validated_attachments[i] == GL_DEPTH_STENCIL_ATTACHMENT) {
6858         framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
6859                                              texture_manager(),
6860                                              GL_DEPTH_ATTACHMENT,
6861                                              false);
6862         framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
6863                                              texture_manager(),
6864                                              GL_STENCIL_ATTACHMENT,
6865                                              false);
6866       } else {
6867         framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
6868                                              texture_manager(),
6869                                              validated_attachments[i],
6870                                              false);
6871       }
6872     } else {
6873       switch (validated_attachments[i]) {
6874         case GL_COLOR_EXT:
6875           backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
6876           break;
6877         case GL_DEPTH_EXT:
6878           backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
6879           break;
6880         case GL_STENCIL_EXT:
6881           backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
6882           break;
6883         default:
6884           NOTREACHED();
6885           break;
6886       }
6887     }
6888   }
6889 }
6890 
DoDiscardFramebufferEXT(GLenum target,GLsizei count,const volatile GLenum * attachments)6891 void GLES2DecoderImpl::DoDiscardFramebufferEXT(
6892     GLenum target,
6893     GLsizei count,
6894     const volatile GLenum* attachments) {
6895   if (workarounds().disable_discard_framebuffer)
6896     return;
6897 
6898   const GLsizei kWidthNotUsed = 1;
6899   const GLsizei kHeightNotUsed = 1;
6900   InvalidateFramebufferImpl(
6901       target, count, attachments, 0, 0, kWidthNotUsed, kHeightNotUsed,
6902       "glDiscardFramebufferEXT", kFramebufferDiscard);
6903 }
6904 
DoInvalidateFramebuffer(GLenum target,GLsizei count,const volatile GLenum * attachments)6905 void GLES2DecoderImpl::DoInvalidateFramebuffer(
6906     GLenum target,
6907     GLsizei count,
6908     const volatile GLenum* attachments) {
6909   const GLsizei kWidthNotUsed = 1;
6910   const GLsizei kHeightNotUsed = 1;
6911   InvalidateFramebufferImpl(
6912       target, count, attachments, 0, 0, kWidthNotUsed, kHeightNotUsed,
6913       "glInvalidateFramebuffer", kFramebufferInvalidate);
6914 }
6915 
DoInvalidateSubFramebuffer(GLenum target,GLsizei count,const volatile GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)6916 void GLES2DecoderImpl::DoInvalidateSubFramebuffer(
6917     GLenum target,
6918     GLsizei count,
6919     const volatile GLenum* attachments,
6920     GLint x,
6921     GLint y,
6922     GLsizei width,
6923     GLsizei height) {
6924   InvalidateFramebufferImpl(
6925       target, count, attachments, x, y, width, height,
6926       "glInvalidateSubFramebuffer", kFramebufferInvalidateSub);
6927 }
6928 
DoEnableVertexAttribArray(GLuint index)6929 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
6930   if (state_.vertex_attrib_manager->Enable(index, true)) {
6931     state_.vertex_attrib_manager->SetDriverVertexAttribEnabled(index, true);
6932   } else {
6933     LOCAL_SET_GL_ERROR(
6934         GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
6935   }
6936 }
6937 
DoGenerateMipmap(GLenum target)6938 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
6939   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
6940       &state_, target);
6941   if (!texture_ref ||
6942       !texture_manager()->CanGenerateMipmaps(texture_ref)) {
6943     LOCAL_SET_GL_ERROR(
6944         GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
6945     return;
6946   }
6947   Texture* tex = texture_ref->texture();
6948   GLint base_level = tex->base_level();
6949 
6950   if (target == GL_TEXTURE_CUBE_MAP) {
6951     for (int i = 0; i < 6; ++i) {
6952       GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
6953       if (!texture_manager()->ClearTextureLevel(this, texture_ref, face,
6954                                                 base_level)) {
6955         LOCAL_SET_GL_ERROR(
6956             GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
6957         return;
6958       }
6959     }
6960   } else {
6961     if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
6962                                               base_level)) {
6963       LOCAL_SET_GL_ERROR(
6964           GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
6965       return;
6966     }
6967   }
6968 
6969   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
6970   // Workaround for Mac driver bug. If the base level is non-zero but the zero
6971   // level of a texture has not been set glGenerateMipmaps sets the entire mip
6972   // chain to opaque black. If the zero level is set at all, however, the mip
6973   // chain is properly generated from the base level.
6974   bool texture_zero_level_set = false;
6975   GLenum type = 0;
6976   GLenum internal_format = 0;
6977   GLenum format = 0;
6978   if (workarounds().set_zero_level_before_generating_mipmap &&
6979       target == GL_TEXTURE_2D) {
6980     if (base_level != 0 &&
6981         !tex->GetLevelType(target, 0, &type, &internal_format) &&
6982         tex->GetLevelType(target, tex->base_level(), &type, &internal_format)) {
6983       format = TextureManager::ExtractFormatFromStorageFormat(internal_format);
6984       ScopedPixelUnpackState reset_restore(&state_);
6985       api()->glTexImage2DFn(target, 0, internal_format, 1, 1, 0, format, type,
6986                             nullptr);
6987       texture_zero_level_set = true;
6988     }
6989   }
6990 
6991   bool enable_srgb = 0;
6992   if (target == GL_TEXTURE_2D) {
6993     tex->GetLevelType(target, tex->base_level(), &type, &internal_format);
6994     enable_srgb = GLES2Util::GetColorEncodingFromInternalFormat(
6995                       internal_format) == GL_SRGB;
6996   }
6997   if (enable_srgb && feature_info_->feature_flags().desktop_srgb_support) {
6998     state_.EnableDisableFramebufferSRGB(enable_srgb);
6999   }
7000   if (workarounds().clamp_texture_base_level_and_max_level) {
7001     tex->ApplyClampedBaseLevelAndMaxLevelToDriver();
7002   }
7003   if (enable_srgb && workarounds().decode_encode_srgb_for_generatemipmap) {
7004     if (target == GL_TEXTURE_2D) {
7005       if (!InitializeSRGBConverter("generateMipmap")) {
7006         return;
7007       }
7008       srgb_converter_->GenerateMipmap(this, tex, target);
7009     } else {
7010       // TODO(yizhou): If the target is GL_TEXTURE_3D ,GL_TEXTURE_2D_ARRAY,
7011       // GL_TEXTURE_CUBE_MAP,
7012       // this change can not generate correct mipmap.
7013       api()->glGenerateMipmapEXTFn(target);
7014     }
7015   } else {
7016     api()->glGenerateMipmapEXTFn(target);
7017   }
7018 
7019   if (texture_zero_level_set) {
7020     // This may have some unwanted side effects, but we expect command buffer
7021     // validation to prevent you from doing anything weird with the texture
7022     // after this, like calling texSubImage2D sucessfully.
7023     ScopedPixelUnpackState reset_restore(&state_);
7024     api()->glTexImage2DFn(target, 0, internal_format, 0, 0, 0, format, type,
7025                           nullptr);
7026   }
7027 
7028   GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
7029   if (error == GL_NO_ERROR) {
7030     texture_manager()->MarkMipmapsGenerated(texture_ref);
7031   }
7032 }
7033 
GetHelper(GLenum pname,GLint * params,GLsizei * num_written)7034 bool GLES2DecoderImpl::GetHelper(
7035     GLenum pname, GLint* params, GLsizei* num_written) {
7036   DCHECK(num_written);
7037   switch (pname) {
7038     case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
7039     case GL_IMPLEMENTATION_COLOR_READ_TYPE:
7040       *num_written = 1;
7041       {
7042         Framebuffer* framebuffer = GetBoundReadFramebuffer();
7043         if (framebuffer &&
7044             framebuffer->IsPossiblyComplete(feature_info_.get()) !=
7045             GL_FRAMEBUFFER_COMPLETE) {
7046           // Here we avoid querying the driver framebuffer status because the
7047           // above should cover most cases. This is an effort to reduce crashes
7048           // on MacOSX. See crbug.com/662802.
7049           LOCAL_SET_GL_ERROR(
7050               GL_INVALID_OPERATION, "glGetIntegerv", "incomplete framebuffer");
7051           if (params) {
7052             *params = 0;
7053           }
7054           return true;
7055         }
7056       }
7057       if (params) {
7058         if (feature_info_->gl_version_info().is_es) {
7059           api()->glGetIntegervFn(pname, params);
7060         } else {
7061           // On Desktop GL where these two enums can be queried, instead of
7062           // returning the second pair of read format/type, the preferred pair
7063           // is returned. So this semantic is different from GL ES.
7064           if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT) {
7065             *params = GLES2Util::GetGLReadPixelsImplementationFormat(
7066                 GetBoundReadFramebufferInternalFormat(),
7067                 GetBoundReadFramebufferTextureType(),
7068                 feature_info_->feature_flags().ext_read_format_bgra);
7069           } else {
7070             *params = GLES2Util::GetGLReadPixelsImplementationType(
7071                 GetBoundReadFramebufferInternalFormat(),
7072                 GetBoundReadFramebufferTextureType());
7073           }
7074         }
7075         if (*params == GL_HALF_FLOAT && feature_info_->IsWebGL1OrES2Context()) {
7076           *params = GL_HALF_FLOAT_OES;
7077         }
7078         if (*params == GL_SRGB_ALPHA_EXT) {
7079           *params = GL_RGBA;
7080         }
7081         if (*params == GL_SRGB_EXT) {
7082           *params = GL_RGB;
7083         }
7084       }
7085       return true;
7086     default:
7087       break;
7088   }
7089 
7090   if (!gl_version_info().is_es) {
7091     switch (pname) {
7092       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
7093         *num_written = 1;
7094         if (params) {
7095           *params = group_->max_fragment_uniform_vectors();
7096         }
7097         return true;
7098       case GL_MAX_VARYING_VECTORS:
7099         *num_written = 1;
7100         if (params) {
7101           *params = group_->max_varying_vectors();
7102         }
7103         return true;
7104       case GL_MAX_VERTEX_UNIFORM_VECTORS:
7105         *num_written = 1;
7106         if (params) {
7107           *params = group_->max_vertex_uniform_vectors();
7108         }
7109         return true;
7110       }
7111   }
7112   if (feature_info_->IsWebGL2OrES3Context()) {
7113     switch (pname) {
7114       case GL_MAX_VARYING_COMPONENTS: {
7115         if (gl_version_info().is_es) {
7116           // We can just delegate this query to the driver.
7117           *num_written = 1;
7118           break;
7119         }
7120 
7121         // GL_MAX_VARYING_COMPONENTS is deprecated in the desktop
7122         // OpenGL core profile, so for simplicity, just compute it
7123         // from GL_MAX_VARYING_VECTORS on non-OpenGL ES
7124         // configurations.
7125         GLint max_varying_vectors = 0;
7126         api()->glGetIntegervFn(GL_MAX_VARYING_VECTORS, &max_varying_vectors);
7127         *num_written = 1;
7128         if (params) {
7129           *params = max_varying_vectors * 4;
7130         }
7131         return true;
7132       }
7133       case GL_READ_BUFFER:
7134         *num_written = 1;
7135         if (params) {
7136           Framebuffer* framebuffer = GetBoundReadFramebuffer();
7137           GLenum read_buffer;
7138           if (framebuffer) {
7139             read_buffer = framebuffer->read_buffer();
7140           } else {
7141             read_buffer = back_buffer_read_buffer_;
7142           }
7143           *params = static_cast<GLint>(read_buffer);
7144         }
7145         return true;
7146       case GL_TRANSFORM_FEEDBACK_ACTIVE:
7147         *num_written = 1;
7148         if (params) {
7149           *params =
7150               static_cast<GLint>(state_.bound_transform_feedback->active());
7151         }
7152         return true;
7153       case GL_TRANSFORM_FEEDBACK_PAUSED:
7154         *num_written = 1;
7155         if (params) {
7156           *params =
7157               static_cast<GLint>(state_.bound_transform_feedback->paused());
7158         }
7159         return true;
7160       case GL_WINDOW_RECTANGLE_EXT:
7161         *num_written = 4;
7162         // This is only used for glGetIntegeri_v and similar, so params will
7163         // always be null - the only path here is through
7164         // GetNumValuesReturnedForGLGet.
7165         DCHECK(!params);
7166         return true;
7167     }
7168   }
7169   switch (pname) {
7170     case GL_MAX_VIEWPORT_DIMS:
7171       *num_written = 2;
7172       if (offscreen_target_frame_buffer_.get()) {
7173         if (params) {
7174           params[0] = renderbuffer_manager()->max_renderbuffer_size();
7175           params[1] = renderbuffer_manager()->max_renderbuffer_size();
7176         }
7177         return true;
7178       }
7179       break;
7180     case GL_MAX_SAMPLES:
7181       *num_written = 1;
7182       if (params) {
7183         params[0] = renderbuffer_manager()->max_samples();
7184       }
7185       return true;
7186     case GL_MAX_RENDERBUFFER_SIZE:
7187       *num_written = 1;
7188       if (params) {
7189         params[0] = renderbuffer_manager()->max_renderbuffer_size();
7190       }
7191       return true;
7192     case GL_MAX_TEXTURE_SIZE:
7193       *num_written = 1;
7194       if (params) {
7195         params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
7196       }
7197       return true;
7198     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
7199       *num_written = 1;
7200       if (params) {
7201         params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
7202       }
7203       return true;
7204     case GL_MAX_3D_TEXTURE_SIZE:
7205       *num_written = 1;
7206       if (params) {
7207         params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_3D);
7208       }
7209       return true;
7210     case GL_MAX_ARRAY_TEXTURE_LAYERS:
7211       *num_written = 1;
7212       if (params) {
7213         params[0] = texture_manager()->max_array_texture_layers();
7214       }
7215       return true;
7216     case GL_MAX_COLOR_ATTACHMENTS_EXT:
7217       *num_written = 1;
7218       if (params) {
7219         params[0] = group_->max_color_attachments();
7220       }
7221       return true;
7222     case GL_MAX_DRAW_BUFFERS_ARB:
7223       *num_written = 1;
7224       if (params) {
7225         params[0] = group_->max_draw_buffers();
7226       }
7227       return true;
7228     case GL_ALPHA_BITS:
7229       *num_written = 1;
7230       if (params) {
7231         GLint v = 0;
7232         Framebuffer* framebuffer = GetBoundDrawFramebuffer();
7233         if (framebuffer) {
7234           if (framebuffer->HasAlphaMRT() &&
7235               framebuffer->HasSameInternalFormatsMRT()) {
7236             if (gl_version_info().is_desktop_core_profile) {
7237               for (uint32_t i = 0; i < group_->max_draw_buffers(); i++) {
7238                 if (framebuffer->HasColorAttachment(i)) {
7239                   api()->glGetFramebufferAttachmentParameterivEXTFn(
7240                       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
7241                       GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
7242                   break;
7243                 }
7244               }
7245             } else {
7246               api()->glGetIntegervFn(GL_ALPHA_BITS, &v);
7247             }
7248           }
7249         } else {
7250           v = (ClientExposedBackBufferHasAlpha() ? 8 : 0);
7251         }
7252         params[0] = v;
7253       }
7254       return true;
7255     case GL_DEPTH_BITS:
7256       *num_written = 1;
7257       if (params) {
7258         GLint v = 0;
7259         if (gl_version_info().is_desktop_core_profile) {
7260           Framebuffer* framebuffer = GetBoundDrawFramebuffer();
7261           if (framebuffer) {
7262             if (framebuffer->HasDepthAttachment()) {
7263               api()->glGetFramebufferAttachmentParameterivEXTFn(
7264                   GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
7265                   GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
7266             }
7267           } else {
7268             v = (back_buffer_has_depth_ ? 24 : 0);
7269           }
7270         } else {
7271           api()->glGetIntegervFn(GL_DEPTH_BITS, &v);
7272         }
7273         params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
7274       }
7275       return true;
7276     case GL_RED_BITS:
7277     case GL_GREEN_BITS:
7278     case GL_BLUE_BITS:
7279       *num_written = 1;
7280       if (params) {
7281         GLint v = 0;
7282         if (gl_version_info().is_desktop_core_profile) {
7283           Framebuffer* framebuffer = GetBoundDrawFramebuffer();
7284           if (framebuffer) {
7285             if (framebuffer->HasSameInternalFormatsMRT()) {
7286               GLenum framebuffer_enum = 0;
7287               switch (pname) {
7288                 case GL_RED_BITS:
7289                   framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
7290                   break;
7291                 case GL_GREEN_BITS:
7292                   framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
7293                   break;
7294                 case GL_BLUE_BITS:
7295                   framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
7296                   break;
7297               }
7298               for (uint32_t i = 0; i < group_->max_draw_buffers(); i++) {
7299                 if (framebuffer->HasColorAttachment(i)) {
7300                   api()->glGetFramebufferAttachmentParameterivEXTFn(
7301                       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
7302                       framebuffer_enum, &v);
7303                   break;
7304                 }
7305               }
7306             }
7307           } else {
7308             v = 8;
7309           }
7310         } else {
7311           api()->glGetIntegervFn(pname, &v);
7312         }
7313         params[0] = v;
7314       }
7315       return true;
7316     case GL_STENCIL_BITS:
7317       *num_written = 1;
7318       if (params) {
7319         GLint v = 0;
7320         if (gl_version_info().is_desktop_core_profile) {
7321           Framebuffer* framebuffer = GetBoundDrawFramebuffer();
7322           if (framebuffer) {
7323             if (framebuffer->HasStencilAttachment()) {
7324               api()->glGetFramebufferAttachmentParameterivEXTFn(
7325                   GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
7326                   GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
7327             }
7328           } else {
7329             v = (back_buffer_has_stencil_ ? 8 : 0);
7330           }
7331         } else {
7332           api()->glGetIntegervFn(GL_STENCIL_BITS, &v);
7333         }
7334         params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
7335       }
7336       return true;
7337     case GL_COMPRESSED_TEXTURE_FORMATS:
7338       *num_written = validators_->compressed_texture_format.GetValues().size();
7339       if (params) {
7340         for (GLint ii = 0; ii < *num_written; ++ii) {
7341           params[ii] = validators_->compressed_texture_format.GetValues()[ii];
7342         }
7343       }
7344       return true;
7345     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
7346       *num_written = 1;
7347       if (params) {
7348         *params = validators_->compressed_texture_format.GetValues().size();
7349       }
7350       return true;
7351     case GL_NUM_SHADER_BINARY_FORMATS:
7352       *num_written = 1;
7353       if (params) {
7354         *params = validators_->shader_binary_format.GetValues().size();
7355       }
7356       return true;
7357     case GL_SHADER_BINARY_FORMATS:
7358       *num_written = validators_->shader_binary_format.GetValues().size();
7359       if (params) {
7360         for (GLint ii = 0; ii <  *num_written; ++ii) {
7361           params[ii] = validators_->shader_binary_format.GetValues()[ii];
7362         }
7363       }
7364       return true;
7365     case GL_SHADER_COMPILER:
7366       *num_written = 1;
7367       if (params) {
7368         *params = GL_TRUE;
7369       }
7370       return true;
7371     case GL_ARRAY_BUFFER_BINDING:
7372       *num_written = 1;
7373       if (params) {
7374         *params = GetClientId(
7375             buffer_manager(), state_.bound_array_buffer.get());
7376       }
7377       return true;
7378     case GL_ELEMENT_ARRAY_BUFFER_BINDING:
7379       *num_written = 1;
7380       if (params) {
7381         *params = GetClientId(
7382             buffer_manager(),
7383             state_.vertex_attrib_manager->element_array_buffer());
7384       }
7385       return true;
7386     case GL_COPY_READ_BUFFER_BINDING:
7387       *num_written = 1;
7388       if (params) {
7389         *params = GetClientId(
7390             buffer_manager(), state_.bound_copy_read_buffer.get());
7391       }
7392       return true;
7393     case GL_COPY_WRITE_BUFFER_BINDING:
7394       *num_written = 1;
7395       if (params) {
7396         *params = GetClientId(
7397             buffer_manager(), state_.bound_copy_write_buffer.get());
7398       }
7399       return true;
7400     case GL_PIXEL_PACK_BUFFER_BINDING:
7401       *num_written = 1;
7402       if (params) {
7403         *params = GetClientId(
7404             buffer_manager(), state_.bound_pixel_pack_buffer.get());
7405       }
7406       return true;
7407     case GL_PIXEL_UNPACK_BUFFER_BINDING:
7408       *num_written = 1;
7409       if (params) {
7410         *params = GetClientId(
7411             buffer_manager(), state_.bound_pixel_unpack_buffer.get());
7412       }
7413       return true;
7414     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
7415       *num_written = 1;
7416       if (params) {
7417         *params = GetClientId(
7418             buffer_manager(), state_.bound_transform_feedback_buffer.get());
7419       }
7420       return true;
7421     case GL_UNIFORM_BUFFER_BINDING:
7422       *num_written = 1;
7423       if (params) {
7424         *params = GetClientId(
7425             buffer_manager(), state_.bound_uniform_buffer.get());
7426       }
7427       return true;
7428     case GL_FRAMEBUFFER_BINDING:
7429     // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
7430       *num_written = 1;
7431       if (params) {
7432         *params = GetClientId(
7433             framebuffer_manager(),
7434             GetFramebufferInfoForTarget(GL_FRAMEBUFFER));
7435       }
7436       return true;
7437     case GL_READ_FRAMEBUFFER_BINDING_EXT:
7438       *num_written = 1;
7439       if (params) {
7440         *params = GetClientId(
7441             framebuffer_manager(),
7442             GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT));
7443       }
7444       return true;
7445     case GL_RENDERBUFFER_BINDING:
7446       *num_written = 1;
7447       if (params) {
7448         Renderbuffer* renderbuffer =
7449             GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
7450         if (renderbuffer) {
7451           *params = renderbuffer->client_id();
7452         } else {
7453           *params = 0;
7454         }
7455       }
7456       return true;
7457     case GL_CURRENT_PROGRAM:
7458       *num_written = 1;
7459       if (params) {
7460         *params = GetClientId(program_manager(), state_.current_program.get());
7461       }
7462       return true;
7463     case GL_VERTEX_ARRAY_BINDING_OES:
7464       *num_written = 1;
7465       if (params) {
7466         if (state_.vertex_attrib_manager.get() !=
7467             state_.default_vertex_attrib_manager.get()) {
7468           GLuint client_id = 0;
7469           vertex_array_manager_->GetClientId(
7470               state_.vertex_attrib_manager->service_id(), &client_id);
7471           *params = client_id;
7472         } else {
7473           *params = 0;
7474         }
7475       }
7476       return true;
7477     case GL_TEXTURE_BINDING_2D:
7478       *num_written = 1;
7479       if (params) {
7480         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7481         if (unit.bound_texture_2d.get()) {
7482           *params = unit.bound_texture_2d->client_id();
7483         } else {
7484           *params = 0;
7485         }
7486       }
7487       return true;
7488     case GL_TEXTURE_BINDING_CUBE_MAP:
7489       *num_written = 1;
7490       if (params) {
7491         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7492         if (unit.bound_texture_cube_map.get()) {
7493           *params = unit.bound_texture_cube_map->client_id();
7494         } else {
7495           *params = 0;
7496         }
7497       }
7498       return true;
7499     case GL_TEXTURE_BINDING_EXTERNAL_OES:
7500       *num_written = 1;
7501       if (params) {
7502         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7503         if (unit.bound_texture_external_oes.get()) {
7504           *params = unit.bound_texture_external_oes->client_id();
7505         } else {
7506           *params = 0;
7507         }
7508       }
7509       return true;
7510     case GL_TEXTURE_BINDING_RECTANGLE_ARB:
7511       *num_written = 1;
7512       if (params) {
7513         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7514         if (unit.bound_texture_rectangle_arb.get()) {
7515           *params = unit.bound_texture_rectangle_arb->client_id();
7516         } else {
7517           *params = 0;
7518         }
7519       }
7520       return true;
7521     case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
7522       *num_written = 1;
7523       if (params) {
7524         params[0] = group_->bind_generates_resource() ? 1 : 0;
7525       }
7526       return true;
7527     case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
7528       *num_written = 1;
7529       if (params) {
7530         params[0] = group_->max_dual_source_draw_buffers();
7531       }
7532       return true;
7533 
7534     case GL_MAJOR_VERSION:
7535       *num_written = 1;
7536       if (params) {
7537         // TODO(zmo): once we switch to MANGLE, we should query version numbers.
7538         params[0] = 3;
7539       }
7540       return true;
7541     case GL_MINOR_VERSION:
7542       // TODO(zmo): once we switch to MANGLE, we should query version numbers.
7543       *num_written = 1;
7544       if (params) {
7545         params[0] = 0;
7546       }
7547       return true;
7548 
7549     case GL_NUM_EXTENSIONS:
7550       // TODO(vmiura): Should the command buffer support this?
7551       *num_written = 1;
7552       if (params) {
7553         params[0] = 0;
7554       }
7555       return true;
7556     case GL_GPU_DISJOINT_EXT:
7557       // TODO(vmiura): Should the command buffer support this?
7558       *num_written = 1;
7559       if (params) {
7560         params[0] = 0;
7561       }
7562       return true;
7563     case GL_TIMESTAMP_EXT:
7564       // TODO(vmiura): Should the command buffer support this?
7565       *num_written = 1;
7566       if (params) {
7567         params[0] = 0;
7568       }
7569       return true;
7570     case GL_TEXTURE_BINDING_2D_ARRAY:
7571       *num_written = 1;
7572       if (params) {
7573         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7574         if (unit.bound_texture_2d_array.get()) {
7575           *params = unit.bound_texture_2d_array->client_id();
7576         } else {
7577           *params = 0;
7578         }
7579       }
7580       return true;
7581     case GL_TEXTURE_BINDING_3D:
7582       *num_written = 1;
7583       if (params) {
7584         TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
7585         if (unit.bound_texture_3d.get()) {
7586           *params = unit.bound_texture_3d->client_id();
7587         } else {
7588           *params = 0;
7589         }
7590       }
7591       return true;
7592     case GL_SAMPLER_BINDING:
7593       *num_written = 1;
7594       if (params) {
7595         DCHECK_LT(state_.active_texture_unit, state_.sampler_units.size());
7596         Sampler* sampler =
7597             state_.sampler_units[state_.active_texture_unit].get();
7598         *params = sampler ? sampler->client_id() : 0;
7599 
7600 #if DCHECK_IS_ON()
7601         if (sampler) {
7602           GLint bound_sampler = 0;
7603           glGetIntegerv(GL_SAMPLER_BINDING, &bound_sampler);
7604           DCHECK_EQ(static_cast<GLuint>(bound_sampler), sampler->service_id());
7605         }
7606 #endif
7607       }
7608       return true;
7609     case GL_TRANSFORM_FEEDBACK_BINDING:
7610       *num_written = 1;
7611       if (params) {
7612         *params = state_.bound_transform_feedback->client_id();
7613       }
7614       return true;
7615     case GL_NUM_PROGRAM_BINARY_FORMATS:
7616       *num_written = 1;
7617       if (params) {
7618         *params = 0;
7619       }
7620       return true;
7621     case GL_PROGRAM_BINARY_FORMATS:
7622       *num_written = 0;
7623       return true;
7624     default:
7625       if (pname >= GL_DRAW_BUFFER0_ARB && pname <= GL_DRAW_BUFFER15_ARB) {
7626         *num_written = 1;
7627         if (params) {
7628           if (pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
7629             Framebuffer* framebuffer =
7630                 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
7631             if (framebuffer) {
7632               *params = framebuffer->GetDrawBuffer(pname);
7633             } else {  // backbuffer
7634               if (pname == GL_DRAW_BUFFER0_ARB)
7635                 *params = back_buffer_draw_buffer_;
7636               else
7637                 *params = GL_NONE;
7638             }
7639           } else {
7640             *params = GL_NONE;
7641           }
7642         }
7643         return true;
7644       }
7645 
7646       *num_written = util_.GLGetNumValuesReturned(pname);
7647       if (*num_written)
7648         break;
7649 
7650       return false;
7651   }
7652 
7653   if (params) {
7654     DCHECK(*num_written);
7655     pname = AdjustGetPname(pname);
7656     api()->glGetIntegervFn(pname, params);
7657   }
7658   return true;
7659 }
7660 
GetNumValuesReturnedForGLGet(GLenum pname,GLsizei * num_values)7661 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
7662     GLenum pname, GLsizei* num_values) {
7663   *num_values = 0;
7664   if (state_.GetStateAsGLint(pname, nullptr, num_values)) {
7665     return true;
7666   }
7667   return GetHelper(pname, nullptr, num_values);
7668 }
7669 
AdjustGetPname(GLenum pname)7670 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
7671   if (GL_MAX_SAMPLES == pname &&
7672       features().use_img_for_multisampled_render_to_texture) {
7673     return GL_MAX_SAMPLES_IMG;
7674   }
7675   if (GL_ALIASED_POINT_SIZE_RANGE == pname &&
7676       gl_version_info().is_desktop_core_profile) {
7677     return GL_POINT_SIZE_RANGE;
7678   }
7679   return pname;
7680 }
7681 
DoGetBooleanv(GLenum pname,GLboolean * params,GLsizei params_size)7682 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname,
7683                                      GLboolean* params,
7684                                      GLsizei params_size) {
7685   DCHECK(params);
7686   std::unique_ptr<GLint[]> values(new GLint[params_size]);
7687   memset(values.get(), 0, params_size * sizeof(GLint));
7688   DoGetIntegerv(pname, values.get(), params_size);
7689   for (GLsizei ii = 0; ii < params_size; ++ii) {
7690     params[ii] = static_cast<GLboolean>(values[ii]);
7691   }
7692 }
7693 
DoGetFloatv(GLenum pname,GLfloat * params,GLsizei params_size)7694 void GLES2DecoderImpl::DoGetFloatv(GLenum pname,
7695                                    GLfloat* params,
7696                                    GLsizei params_size) {
7697   DCHECK(params);
7698   GLsizei num_written = 0;
7699   if (state_.GetStateAsGLfloat(pname, params, &num_written)) {
7700     DCHECK_EQ(num_written, params_size);
7701     return;
7702   }
7703 
7704   switch (pname) {
7705     case GL_ALIASED_POINT_SIZE_RANGE:
7706     case GL_ALIASED_LINE_WIDTH_RANGE:
7707     case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
7708       DCHECK_EQ(params_size, util_.GLGetNumValuesReturned(pname));
7709       pname = AdjustGetPname(pname);
7710       api()->glGetFloatvFn(pname, params);
7711       return;
7712   }
7713 
7714   std::unique_ptr<GLint[]> values(new GLint[params_size]);
7715   memset(values.get(), 0, params_size * sizeof(GLint));
7716   DoGetIntegerv(pname, values.get(), params_size);
7717   for (GLsizei ii = 0; ii < params_size; ++ii) {
7718     params[ii] = static_cast<GLfloat>(values[ii]);
7719   }
7720 }
7721 
DoGetInteger64v(GLenum pname,GLint64 * params,GLsizei params_size)7722 void GLES2DecoderImpl::DoGetInteger64v(GLenum pname,
7723                                        GLint64* params,
7724                                        GLsizei params_size) {
7725   DCHECK(params);
7726   if (feature_info_->IsWebGL2OrES3Context()) {
7727     switch (pname) {
7728       case GL_MAX_ELEMENT_INDEX: {
7729         DCHECK_EQ(params_size, 1);
7730         if (gl_version_info().IsAtLeastGLES(3, 0) ||
7731             gl_version_info().IsAtLeastGL(4, 3)) {
7732           api()->glGetInteger64vFn(GL_MAX_ELEMENT_INDEX, params);
7733         } else {
7734           // Assume that desktop GL implementations can generally support
7735           // 32-bit indices.
7736           if (params) {
7737             *params = std::numeric_limits<unsigned int>::max();
7738           }
7739         }
7740         return;
7741       }
7742     }
7743   }
7744 
7745   std::unique_ptr<GLint[]> values(new GLint[params_size]);
7746   memset(values.get(), 0, params_size * sizeof(GLint));
7747   DoGetIntegerv(pname, values.get(), params_size);
7748   for (GLsizei ii = 0; ii < params_size; ++ii) {
7749     params[ii] = static_cast<GLint64>(values[ii]);
7750   }
7751 }
7752 
DoGetIntegerv(GLenum pname,GLint * params,GLsizei params_size)7753 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname,
7754                                      GLint* params,
7755                                      GLsizei params_size) {
7756   DCHECK(params);
7757   GLsizei num_written = 0;
7758   if (state_.GetStateAsGLint(pname, params, &num_written) ||
7759       GetHelper(pname, params, &num_written)) {
7760     DCHECK_EQ(num_written, params_size);
7761     return;
7762   }
7763   NOTREACHED() << "Unhandled enum " << pname;
7764 }
7765 
7766 template <typename TYPE>
GetIndexedIntegerImpl(const char * function_name,GLenum target,GLuint index,TYPE * data)7767 void GLES2DecoderImpl::GetIndexedIntegerImpl(
7768     const char* function_name, GLenum target, GLuint index, TYPE* data) {
7769   DCHECK(data);
7770 
7771   if (features().ext_window_rectangles && target == GL_WINDOW_RECTANGLE_EXT) {
7772     if (index >= state_.GetMaxWindowRectangles()) {
7773       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
7774                          "window rectangle index out of bounds");
7775     }
7776     // This must be queried from the state tracker because the driver state is
7777     // "wrong" if the bound framebuffer is 0 (backbuffer).
7778     state_.GetWindowRectangle(index, data);
7779     return;
7780   }
7781   scoped_refptr<IndexedBufferBindingHost> bindings;
7782   switch (target) {
7783     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
7784     case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
7785     case GL_TRANSFORM_FEEDBACK_BUFFER_START:
7786       if (index >= group_->max_transform_feedback_separate_attribs()) {
7787         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid index");
7788         return;
7789       }
7790       bindings = state_.bound_transform_feedback.get();
7791       break;
7792     case GL_UNIFORM_BUFFER_BINDING:
7793     case GL_UNIFORM_BUFFER_SIZE:
7794     case GL_UNIFORM_BUFFER_START:
7795       if (index >= group_->max_uniform_buffer_bindings()) {
7796         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid index");
7797         return;
7798       }
7799       bindings = state_.indexed_uniform_buffer_bindings.get();
7800       break;
7801     default:
7802       NOTREACHED();
7803       break;
7804   }
7805   DCHECK(bindings);
7806   switch (target) {
7807     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
7808     case GL_UNIFORM_BUFFER_BINDING:
7809       {
7810         Buffer* buffer = bindings->GetBufferBinding(index);
7811         *data = static_cast<TYPE>(buffer ? buffer->service_id() : 0);
7812       }
7813       break;
7814     case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
7815     case GL_UNIFORM_BUFFER_SIZE:
7816       *data = static_cast<TYPE>(bindings->GetBufferSize(index));
7817       break;
7818     case GL_TRANSFORM_FEEDBACK_BUFFER_START:
7819     case GL_UNIFORM_BUFFER_START:
7820       *data = static_cast<TYPE>(bindings->GetBufferStart(index));
7821       break;
7822     default:
7823       NOTREACHED();
7824       break;
7825   }
7826 }
7827 
DoGetIntegeri_v(GLenum target,GLuint index,GLint * params,GLsizei params_size)7828 void GLES2DecoderImpl::DoGetIntegeri_v(GLenum target,
7829                                        GLuint index,
7830                                        GLint* params,
7831                                        GLsizei params_size) {
7832   GetIndexedIntegerImpl<GLint>("glGetIntegeri_v", target, index, params);
7833 }
7834 
DoGetInteger64i_v(GLenum target,GLuint index,GLint64 * params,GLsizei params_size)7835 void GLES2DecoderImpl::DoGetInteger64i_v(GLenum target,
7836                                          GLuint index,
7837                                          GLint64* params,
7838                                          GLsizei params_size) {
7839   GetIndexedIntegerImpl<GLint64>("glGetInteger64i_v", target, index, params);
7840 }
7841 
DoGetProgramiv(GLuint program_id,GLenum pname,GLint * params,GLsizei params_size)7842 void GLES2DecoderImpl::DoGetProgramiv(GLuint program_id,
7843                                       GLenum pname,
7844                                       GLint* params,
7845                                       GLsizei params_size) {
7846   Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
7847   if (!program) {
7848     return;
7849   }
7850   program->GetProgramiv(pname, params);
7851 }
7852 
DoGetSynciv(GLuint sync_id,GLenum pname,GLsizei num_values,GLsizei * length,GLint * values)7853 void GLES2DecoderImpl::DoGetSynciv(GLuint sync_id,
7854                                    GLenum pname,
7855                                    GLsizei num_values,
7856                                    GLsizei* length,
7857                                    GLint* values) {
7858   GLsync service_sync = 0;
7859   if (!group_->GetSyncServiceId(sync_id, &service_sync)) {
7860     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glGetSynciv", "invalid sync id");
7861     return;
7862   }
7863   api()->glGetSyncivFn(service_sync, pname, num_values, nullptr, values);
7864 }
7865 
DoGetBufferParameteri64v(GLenum target,GLenum pname,GLint64 * params,GLsizei params_size)7866 void GLES2DecoderImpl::DoGetBufferParameteri64v(GLenum target,
7867                                                 GLenum pname,
7868                                                 GLint64* params,
7869                                                 GLsizei params_size) {
7870   // Just delegate it. Some validation is actually done before this.
7871   buffer_manager()->ValidateAndDoGetBufferParameteri64v(
7872       &state_, error_state_.get(), target, pname, params);
7873 }
7874 
DoGetBufferParameteriv(GLenum target,GLenum pname,GLint * params,GLsizei params_size)7875 void GLES2DecoderImpl::DoGetBufferParameteriv(GLenum target,
7876                                               GLenum pname,
7877                                               GLint* params,
7878                                               GLsizei params_size) {
7879   // Just delegate it. Some validation is actually done before this.
7880   buffer_manager()->ValidateAndDoGetBufferParameteriv(
7881       &state_, error_state_.get(), target, pname, params);
7882 }
7883 
DoBindAttribLocation(GLuint program_id,GLuint index,const std::string & name)7884 void GLES2DecoderImpl::DoBindAttribLocation(GLuint program_id,
7885                                             GLuint index,
7886                                             const std::string& name) {
7887   if (!StringIsValidForGLES(name)) {
7888     LOCAL_SET_GL_ERROR(
7889         GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
7890     return;
7891   }
7892   if (ProgramManager::HasBuiltInPrefix(name)) {
7893     LOCAL_SET_GL_ERROR(
7894         GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
7895     return;
7896   }
7897   if (index >= group_->max_vertex_attribs()) {
7898     LOCAL_SET_GL_ERROR(
7899         GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
7900     return;
7901   }
7902   Program* program = GetProgramInfoNotShader(
7903       program_id, "glBindAttribLocation");
7904   if (!program) {
7905     return;
7906   }
7907   // At this point, the program's shaders may not be translated yet,
7908   // therefore, we may not find the hashed attribute name.
7909   // glBindAttribLocation call with original name is useless.
7910   // So instead, we simply cache the binding, and then call
7911   // Program::ExecuteBindAttribLocationCalls() right before link.
7912   program->SetAttribLocationBinding(name, static_cast<GLint>(index));
7913 }
7914 
HandleBindAttribLocationBucket(uint32_t immediate_data_size,const volatile void * cmd_data)7915 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
7916     uint32_t immediate_data_size,
7917     const volatile void* cmd_data) {
7918   const volatile gles2::cmds::BindAttribLocationBucket& c =
7919       *static_cast<const volatile gles2::cmds::BindAttribLocationBucket*>(
7920           cmd_data);
7921   GLuint program = static_cast<GLuint>(c.program);
7922   GLuint index = static_cast<GLuint>(c.index);
7923   Bucket* bucket = GetBucket(c.name_bucket_id);
7924   if (!bucket || bucket->size() == 0) {
7925     return error::kInvalidArguments;
7926   }
7927   std::string name_str;
7928   if (!bucket->GetAsString(&name_str)) {
7929     return error::kInvalidArguments;
7930   }
7931   DoBindAttribLocation(program, index, name_str);
7932   return error::kNoError;
7933 }
7934 
DoBindFragDataLocation(GLuint program_id,GLuint colorName,const std::string & name)7935 error::Error GLES2DecoderImpl::DoBindFragDataLocation(GLuint program_id,
7936                                                       GLuint colorName,
7937                                                       const std::string& name) {
7938   const char kFunctionName[] = "glBindFragDataLocationEXT";
7939   if (!StringIsValidForGLES(name)) {
7940     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character");
7941     return error::kNoError;
7942   }
7943   if (ProgramManager::HasBuiltInPrefix(name)) {
7944     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix");
7945     return error::kNoError;
7946   }
7947   if (colorName >= group_->max_draw_buffers()) {
7948     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
7949                        "colorName out of range");
7950     return error::kNoError;
7951   }
7952   Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
7953   if (!program) {
7954     return error::kNoError;
7955   }
7956   program->SetProgramOutputLocationBinding(name, colorName);
7957   return error::kNoError;
7958 }
7959 
HandleBindFragDataLocationEXTBucket(uint32_t immediate_data_size,const volatile void * cmd_data)7960 error::Error GLES2DecoderImpl::HandleBindFragDataLocationEXTBucket(
7961     uint32_t immediate_data_size,
7962     const volatile void* cmd_data) {
7963   if (!features().ext_blend_func_extended) {
7964     return error::kUnknownCommand;
7965   }
7966   const volatile gles2::cmds::BindFragDataLocationEXTBucket& c =
7967       *static_cast<const volatile gles2::cmds::BindFragDataLocationEXTBucket*>(
7968           cmd_data);
7969   GLuint program = static_cast<GLuint>(c.program);
7970   GLuint colorNumber = static_cast<GLuint>(c.colorNumber);
7971   Bucket* bucket = GetBucket(c.name_bucket_id);
7972   if (!bucket || bucket->size() == 0) {
7973     return error::kInvalidArguments;
7974   }
7975   std::string name_str;
7976   if (!bucket->GetAsString(&name_str)) {
7977     return error::kInvalidArguments;
7978   }
7979   return DoBindFragDataLocation(program, colorNumber, name_str);
7980 }
7981 
DoBindFragDataLocationIndexed(GLuint program_id,GLuint colorName,GLuint index,const std::string & name)7982 error::Error GLES2DecoderImpl::DoBindFragDataLocationIndexed(
7983     GLuint program_id,
7984     GLuint colorName,
7985     GLuint index,
7986     const std::string& name) {
7987   const char kFunctionName[] = "glBindFragDataLocationIndexEXT";
7988   if (!StringIsValidForGLES(name)) {
7989     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character");
7990     return error::kNoError;
7991   }
7992   if (ProgramManager::HasBuiltInPrefix(name)) {
7993     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix");
7994     return error::kNoError;
7995   }
7996   if (index != 0 && index != 1) {
7997     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "index out of range");
7998     return error::kNoError;
7999   }
8000   if ((index == 0 && colorName >= group_->max_draw_buffers()) ||
8001       (index == 1 && colorName >= group_->max_dual_source_draw_buffers())) {
8002     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
8003                        "colorName out of range for the color index");
8004     return error::kNoError;
8005   }
8006   Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
8007   if (!program) {
8008     return error::kNoError;
8009   }
8010   program->SetProgramOutputLocationIndexedBinding(name, colorName, index);
8011   return error::kNoError;
8012 }
8013 
HandleBindFragDataLocationIndexedEXTBucket(uint32_t immediate_data_size,const volatile void * cmd_data)8014 error::Error GLES2DecoderImpl::HandleBindFragDataLocationIndexedEXTBucket(
8015     uint32_t immediate_data_size,
8016     const volatile void* cmd_data) {
8017   if (!features().ext_blend_func_extended) {
8018     return error::kUnknownCommand;
8019   }
8020   const volatile gles2::cmds::BindFragDataLocationIndexedEXTBucket& c =
8021       *static_cast<
8022           const volatile gles2::cmds::BindFragDataLocationIndexedEXTBucket*>(
8023           cmd_data);
8024   GLuint program = static_cast<GLuint>(c.program);
8025   GLuint colorNumber = static_cast<GLuint>(c.colorNumber);
8026   GLuint index = static_cast<GLuint>(c.index);
8027   Bucket* bucket = GetBucket(c.name_bucket_id);
8028   if (!bucket || bucket->size() == 0) {
8029     return error::kInvalidArguments;
8030   }
8031   std::string name_str;
8032   if (!bucket->GetAsString(&name_str)) {
8033     return error::kInvalidArguments;
8034   }
8035   return DoBindFragDataLocationIndexed(program, colorNumber, index, name_str);
8036 }
8037 
DoBindUniformLocationCHROMIUM(GLuint program_id,GLint location,const std::string & name)8038 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(GLuint program_id,
8039                                                      GLint location,
8040                                                      const std::string& name) {
8041   if (!StringIsValidForGLES(name)) {
8042     LOCAL_SET_GL_ERROR(
8043         GL_INVALID_VALUE,
8044         "glBindUniformLocationCHROMIUM", "Invalid character");
8045     return;
8046   }
8047   if (ProgramManager::HasBuiltInPrefix(name)) {
8048     LOCAL_SET_GL_ERROR(
8049         GL_INVALID_OPERATION,
8050         "glBindUniformLocationCHROMIUM", "reserved prefix");
8051     return;
8052   }
8053   if (location < 0 ||
8054       static_cast<uint32_t>(location) >=
8055           (group_->max_fragment_uniform_vectors() +
8056            group_->max_vertex_uniform_vectors()) *
8057               4) {
8058     LOCAL_SET_GL_ERROR(
8059         GL_INVALID_VALUE,
8060         "glBindUniformLocationCHROMIUM", "location out of range");
8061     return;
8062   }
8063   Program* program = GetProgramInfoNotShader(
8064       program_id, "glBindUniformLocationCHROMIUM");
8065   if (!program) {
8066     return;
8067   }
8068   if (!program->SetUniformLocationBinding(name, location)) {
8069     LOCAL_SET_GL_ERROR(
8070         GL_INVALID_VALUE,
8071         "glBindUniformLocationCHROMIUM", "location out of range");
8072   }
8073 }
8074 
HandleBindUniformLocationCHROMIUMBucket(uint32_t immediate_data_size,const volatile void * cmd_data)8075 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
8076     uint32_t immediate_data_size,
8077     const volatile void* cmd_data) {
8078   const volatile gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
8079       *static_cast<
8080           const volatile gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
8081           cmd_data);
8082   GLuint program = static_cast<GLuint>(c.program);
8083   GLint location = static_cast<GLint>(c.location);
8084   Bucket* bucket = GetBucket(c.name_bucket_id);
8085   if (!bucket || bucket->size() == 0) {
8086     return error::kInvalidArguments;
8087   }
8088   std::string name_str;
8089   if (!bucket->GetAsString(&name_str)) {
8090     return error::kInvalidArguments;
8091   }
8092   DoBindUniformLocationCHROMIUM(program, location, name_str);
8093   return error::kNoError;
8094 }
8095 
HandleDeleteShader(uint32_t immediate_data_size,const volatile void * cmd_data)8096 error::Error GLES2DecoderImpl::HandleDeleteShader(
8097     uint32_t immediate_data_size,
8098     const volatile void* cmd_data) {
8099   const volatile gles2::cmds::DeleteShader& c =
8100       *static_cast<const volatile gles2::cmds::DeleteShader*>(cmd_data);
8101   GLuint client_id = c.shader;
8102   if (client_id) {
8103     Shader* shader = GetShader(client_id);
8104     if (shader) {
8105       if (!shader->IsDeleted()) {
8106         shader_manager()->Delete(shader);
8107       }
8108     } else {
8109       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
8110     }
8111   }
8112   return error::kNoError;
8113 }
8114 
HandleDeleteProgram(uint32_t immediate_data_size,const volatile void * cmd_data)8115 error::Error GLES2DecoderImpl::HandleDeleteProgram(
8116     uint32_t immediate_data_size,
8117     const volatile void* cmd_data) {
8118   const volatile gles2::cmds::DeleteProgram& c =
8119       *static_cast<const volatile gles2::cmds::DeleteProgram*>(cmd_data);
8120   GLuint client_id = c.program;
8121   if (client_id) {
8122     Program* program = GetProgram(client_id);
8123     if (program) {
8124       if (!program->IsDeleted()) {
8125         program_manager()->MarkAsDeleted(shader_manager(), program);
8126       }
8127     } else {
8128       LOCAL_SET_GL_ERROR(
8129           GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
8130     }
8131   }
8132   return error::kNoError;
8133 }
8134 
DoClear(GLbitfield mask)8135 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
8136   const char* func_name = "glClear";
8137   DCHECK(!ShouldDeferDraws());
8138   if (mask &
8139       ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
8140     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid mask");
8141     return error::kNoError;
8142   }
8143   if (CheckBoundDrawFramebufferValid(func_name)) {
8144     ApplyDirtyState();
8145     if (workarounds().gl_clear_broken) {
8146       if (!BoundFramebufferHasDepthAttachment())
8147         mask &= ~GL_DEPTH_BUFFER_BIT;
8148       if (!BoundFramebufferHasStencilAttachment())
8149         mask &= ~GL_STENCIL_BUFFER_BIT;
8150       ClearFramebufferForWorkaround(mask);
8151       return error::kNoError;
8152     }
8153     if (mask & GL_COLOR_BUFFER_BIT) {
8154       Framebuffer* framebuffer =
8155           framebuffer_state_.bound_draw_framebuffer.get();
8156       if (framebuffer && framebuffer->ContainsActiveIntegerAttachments()) {
8157         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8158             "can't be called on integer buffers");
8159         return error::kNoError;
8160       }
8161     }
8162     AdjustDrawBuffers();
8163     api()->glClearFn(mask);
8164   }
8165   return error::kNoError;
8166 }
8167 
DoClearBufferiv(GLenum buffer,GLint drawbuffer,const volatile GLint * value)8168 void GLES2DecoderImpl::DoClearBufferiv(GLenum buffer,
8169                                        GLint drawbuffer,
8170                                        const volatile GLint* value) {
8171   const char* func_name = "glClearBufferiv";
8172   if (!CheckBoundDrawFramebufferValid(func_name))
8173     return;
8174   ApplyDirtyState();
8175 
8176   if (buffer == GL_COLOR) {
8177     if (drawbuffer < 0 ||
8178         drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) {
8179       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8180       return;
8181     }
8182     GLenum internal_format =
8183         GetBoundColorDrawBufferInternalFormat(drawbuffer);
8184     if (!GLES2Util::IsSignedIntegerFormat(internal_format)) {
8185       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8186           "can only be called on signed integer buffers");
8187       return;
8188     }
8189   } else {
8190     DCHECK(buffer == GL_STENCIL);
8191     if (drawbuffer != 0) {
8192       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8193       return;
8194     }
8195     if (!BoundFramebufferHasStencilAttachment()) {
8196       return;
8197     }
8198   }
8199   MarkDrawBufferAsCleared(buffer, drawbuffer);
8200   api()->glClearBufferivFn(buffer, drawbuffer, const_cast<const GLint*>(value));
8201 }
8202 
DoClearBufferuiv(GLenum buffer,GLint drawbuffer,const volatile GLuint * value)8203 void GLES2DecoderImpl::DoClearBufferuiv(GLenum buffer,
8204                                         GLint drawbuffer,
8205                                         const volatile GLuint* value) {
8206   const char* func_name = "glClearBufferuiv";
8207   if (!CheckBoundDrawFramebufferValid(func_name))
8208     return;
8209   ApplyDirtyState();
8210 
8211   if (drawbuffer < 0 ||
8212       drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) {
8213     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8214     return;
8215   }
8216   GLenum internal_format =
8217       GetBoundColorDrawBufferInternalFormat(drawbuffer);
8218   if (!GLES2Util::IsUnsignedIntegerFormat(internal_format)) {
8219     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8220         "can only be called on unsigned integer buffers");
8221     return;
8222   }
8223   MarkDrawBufferAsCleared(buffer, drawbuffer);
8224   api()->glClearBufferuivFn(buffer, drawbuffer,
8225                             const_cast<const GLuint*>(value));
8226 }
8227 
DoClearBufferfv(GLenum buffer,GLint drawbuffer,const volatile GLfloat * value)8228 void GLES2DecoderImpl::DoClearBufferfv(GLenum buffer,
8229                                        GLint drawbuffer,
8230                                        const volatile GLfloat* value) {
8231   const char* func_name = "glClearBufferfv";
8232   if (!CheckBoundDrawFramebufferValid(func_name))
8233     return;
8234   ApplyDirtyState();
8235 
8236   if (buffer == GL_COLOR) {
8237     if (drawbuffer < 0 ||
8238         drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) {
8239       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8240       return;
8241     }
8242     GLenum internal_format =
8243         GetBoundColorDrawBufferInternalFormat(drawbuffer);
8244     if (GLES2Util::IsIntegerFormat(internal_format)) {
8245       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8246           "can only be called on float buffers");
8247       return;
8248     }
8249   } else {
8250     DCHECK(buffer == GL_DEPTH);
8251     if (drawbuffer != 0) {
8252       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8253       return;
8254     }
8255     if (!BoundFramebufferHasDepthAttachment()) {
8256       return;
8257     }
8258   }
8259   MarkDrawBufferAsCleared(buffer, drawbuffer);
8260   api()->glClearBufferfvFn(buffer, drawbuffer,
8261                            const_cast<const GLfloat*>(value));
8262 }
8263 
DoClearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)8264 void GLES2DecoderImpl::DoClearBufferfi(
8265     GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
8266   const char* func_name = "glClearBufferfi";
8267   if (!CheckBoundDrawFramebufferValid(func_name))
8268     return;
8269   ApplyDirtyState();
8270 
8271   if (drawbuffer != 0) {
8272     LOCAL_SET_GL_ERROR(
8273         GL_INVALID_VALUE, func_name, "invalid drawBuffer");
8274     return;
8275   }
8276   if (!BoundFramebufferHasDepthAttachment() &&
8277       !BoundFramebufferHasStencilAttachment()) {
8278     return;
8279   }
8280   MarkDrawBufferAsCleared(GL_DEPTH, drawbuffer);
8281   MarkDrawBufferAsCleared(GL_STENCIL, drawbuffer);
8282   api()->glClearBufferfiFn(buffer, drawbuffer, depth, stencil);
8283 }
8284 
DoFramebufferParameteri(GLenum target,GLenum pname,GLint param)8285 void GLES2DecoderImpl::DoFramebufferParameteri(GLenum target,
8286                                                GLenum pname,
8287                                                GLint param) {
8288   const char* func_name = "glFramebufferParameteri";
8289   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
8290   if (!framebuffer) {
8291     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no framebuffer bound");
8292     return;
8293   }
8294   api()->glFramebufferParameteriFn(target, pname, param);
8295 }
8296 
DoFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint client_renderbuffer_id)8297 void GLES2DecoderImpl::DoFramebufferRenderbuffer(
8298     GLenum target, GLenum attachment, GLenum renderbuffertarget,
8299     GLuint client_renderbuffer_id) {
8300   const char* func_name = "glFramebufferRenderbuffer";
8301   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
8302   if (!framebuffer) {
8303     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no framebuffer bound");
8304     return;
8305   }
8306   GLuint service_id = 0;
8307   Renderbuffer* renderbuffer = nullptr;
8308   if (client_renderbuffer_id) {
8309     renderbuffer = GetRenderbuffer(client_renderbuffer_id);
8310     if (!renderbuffer) {
8311       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8312                          "unknown renderbuffer");
8313       return;
8314     }
8315     if (!renderbuffer->IsValid()) {
8316       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8317                          "renderbuffer never bound or deleted");
8318       return;
8319     }
8320     service_id = renderbuffer->service_id();
8321   }
8322   std::vector<GLenum> attachments;
8323   if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
8324     attachments.push_back(GL_DEPTH_ATTACHMENT);
8325     attachments.push_back(GL_STENCIL_ATTACHMENT);
8326   } else {
8327     attachments.push_back(attachment);
8328   }
8329   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
8330   for (GLenum attachment_point : attachments) {
8331     api()->glFramebufferRenderbufferEXTFn(target, attachment_point,
8332                                           renderbuffertarget, service_id);
8333     GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
8334     if (error == GL_NO_ERROR) {
8335       framebuffer->AttachRenderbuffer(attachment_point, renderbuffer);
8336     }
8337   }
8338   if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
8339     framebuffer_state_.clear_state_dirty = true;
8340   }
8341   OnFboChanged();
8342 }
8343 
DoDisable(GLenum cap)8344 void GLES2DecoderImpl::DoDisable(GLenum cap) {
8345   if (SetCapabilityState(cap, false)) {
8346     if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX &&
8347         feature_info_->feature_flags().emulate_primitive_restart_fixed_index) {
8348       // Enable and Disable PRIMITIVE_RESTART only before and after
8349       // DrawElements* for old desktop GL.
8350       return;
8351     }
8352     if (cap == GL_FRAMEBUFFER_SRGB) {
8353       // Enable and Disable GL_FRAMEBUFFER_SRGB is done manually in
8354       // CheckBoundDrawFramebufferValid.
8355       return;
8356     }
8357     api()->glDisableFn(cap);
8358   }
8359 }
8360 
DoEnable(GLenum cap)8361 void GLES2DecoderImpl::DoEnable(GLenum cap) {
8362   if (SetCapabilityState(cap, true)) {
8363     if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX &&
8364         feature_info_->feature_flags().emulate_primitive_restart_fixed_index) {
8365       // Enable and Disable PRIMITIVE_RESTART only before and after
8366       // DrawElements* for old desktop GL.
8367       return;
8368     }
8369     if (cap == GL_FRAMEBUFFER_SRGB) {
8370       // Enable and Disable GL_FRAMEBUFFER_SRGB is done manually in
8371       // CheckBoundDrawFramebufferValid.
8372       return;
8373     }
8374     api()->glEnableFn(cap);
8375   }
8376 }
8377 
DoDepthRangef(GLclampf znear,GLclampf zfar)8378 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
8379   state_.z_near = base::ClampToRange(znear, 0.0f, 1.0f);
8380   state_.z_far = base::ClampToRange(zfar, 0.0f, 1.0f);
8381   api()->glDepthRangeFn(znear, zfar);
8382 }
8383 
DoSampleCoverage(GLclampf value,GLboolean invert)8384 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
8385   state_.sample_coverage_value = base::ClampToRange(value, 0.0f, 1.0f);
8386   state_.sample_coverage_invert = (invert != 0);
8387   api()->glSampleCoverageFn(state_.sample_coverage_value, invert);
8388 }
8389 
8390 // Assumes framebuffer is complete.
ClearUnclearedAttachments(GLenum target,Framebuffer * framebuffer)8391 void GLES2DecoderImpl::ClearUnclearedAttachments(
8392     GLenum target, Framebuffer* framebuffer) {
8393   // Clear textures that we can't use glClear first. These textures will be
8394   // marked as cleared after the call and no longer be part of the following
8395   // code.
8396   framebuffer->ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
8397       this, texture_manager());
8398 
8399   bool cleared_int_renderbuffers = false;
8400   Framebuffer* draw_framebuffer = GetBoundDrawFramebuffer();
8401   if (framebuffer->HasUnclearedIntRenderbufferAttachments()) {
8402     if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
8403       // TODO(zmo): There is no guarantee that an FBO that is complete on the
8404       // READ attachment will be complete as a DRAW attachment.
8405       api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER,
8406                                     framebuffer->service_id());
8407     }
8408     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8409     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
8410     ClearDeviceWindowRectangles();
8411 
8412     // TODO(zmo): Assume DrawBuffers() does not affect ClearBuffer().
8413     framebuffer->ClearUnclearedIntRenderbufferAttachments(
8414         renderbuffer_manager());
8415 
8416     cleared_int_renderbuffers = true;
8417   }
8418 
8419   GLbitfield clear_bits = 0;
8420   bool reset_draw_buffers = false;
8421   if (framebuffer->HasUnclearedColorAttachments()) {
8422     // We should always use alpha == 0 here, because 1) some draw buffers may
8423     // have alpha and some may not; 2) we won't have the same situation as the
8424     // back buffer where alpha channel exists but is not requested.
8425     api()->glClearColorFn(0.0f, 0.0f, 0.0f, 0.0f);
8426     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8427     clear_bits |= GL_COLOR_BUFFER_BIT;
8428 
8429     if (SupportsDrawBuffers()) {
8430       reset_draw_buffers =
8431           framebuffer->PrepareDrawBuffersForClearingUninitializedAttachments();
8432     }
8433   }
8434 
8435   if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)) {
8436     api()->glClearStencilFn(0);
8437     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8438     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
8439     clear_bits |= GL_STENCIL_BUFFER_BIT;
8440   }
8441 
8442   if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)) {
8443     api()->glClearDepthFn(1.0f);
8444     state_.SetDeviceDepthMask(GL_TRUE);
8445     clear_bits |= GL_DEPTH_BUFFER_BIT;
8446   }
8447 
8448   if (clear_bits) {
8449     if (!cleared_int_renderbuffers &&
8450         target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
8451       // TODO(zmo): There is no guarantee that an FBO that is complete on the
8452       // READ attachment will be complete as a DRAW attachment.
8453       api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER,
8454                                     framebuffer->service_id());
8455     }
8456     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
8457     ClearDeviceWindowRectangles();
8458     if (workarounds().gl_clear_broken) {
8459       ClearFramebufferForWorkaround(clear_bits);
8460     } else {
8461       api()->glClearFn(clear_bits);
8462     }
8463   }
8464 
8465   if (cleared_int_renderbuffers || clear_bits) {
8466     if (reset_draw_buffers)
8467       framebuffer->RestoreDrawBuffers();
8468     RestoreClearState();
8469     if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
8470       GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
8471                                              GetBackbufferServiceId();
8472       api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, service_id);
8473     }
8474   }
8475 
8476   framebuffer_manager()->MarkAttachmentsAsCleared(
8477       framebuffer, renderbuffer_manager(), texture_manager());
8478 }
8479 
RestoreClearState()8480 void GLES2DecoderImpl::RestoreClearState() {
8481   framebuffer_state_.clear_state_dirty = true;
8482   api()->glClearColorFn(state_.color_clear_red, state_.color_clear_green,
8483                         state_.color_clear_blue, state_.color_clear_alpha);
8484   api()->glClearStencilFn(state_.stencil_clear);
8485   api()->glClearDepthFn(state_.depth_clear);
8486   state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
8487                                   state_.enable_flags.scissor_test);
8488   RestoreDeviceWindowRectangles();
8489   gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
8490   api()->glScissorFn(state_.scissor_x + scissor_offset.x(),
8491                      state_.scissor_y + scissor_offset.y(),
8492                      state_.scissor_width, state_.scissor_height);
8493 }
8494 
DoCheckFramebufferStatus(GLenum target)8495 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
8496   Framebuffer* framebuffer =
8497       GetFramebufferInfoForTarget(target);
8498   if (!framebuffer) {
8499     return GL_FRAMEBUFFER_COMPLETE;
8500   }
8501   GLenum completeness = framebuffer->IsPossiblyComplete(feature_info_.get());
8502   if (completeness != GL_FRAMEBUFFER_COMPLETE) {
8503     return completeness;
8504   }
8505   return framebuffer->GetStatus(texture_manager(), target);
8506 }
8507 
DoFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level)8508 void GLES2DecoderImpl::DoFramebufferTexture2D(
8509     GLenum target, GLenum attachment, GLenum textarget,
8510     GLuint client_texture_id, GLint level) {
8511   DoFramebufferTexture2DCommon(
8512     "glFramebufferTexture2D", target, attachment,
8513     textarget, client_texture_id, level, 0);
8514 }
8515 
DoFramebufferTexture2DMultisample(GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level,GLsizei samples)8516 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
8517     GLenum target, GLenum attachment, GLenum textarget,
8518     GLuint client_texture_id, GLint level, GLsizei samples) {
8519   DoFramebufferTexture2DCommon(
8520     "glFramebufferTexture2DMultisample", target, attachment,
8521     textarget, client_texture_id, level, samples);
8522 }
8523 
DoFramebufferTexture2DCommon(const char * name,GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level,GLsizei samples)8524 void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
8525     const char* name, GLenum target, GLenum attachment, GLenum textarget,
8526     GLuint client_texture_id, GLint level, GLsizei samples) {
8527   if (samples > renderbuffer_manager()->max_samples()) {
8528     LOCAL_SET_GL_ERROR(
8529         GL_INVALID_VALUE,
8530         "glFramebufferTexture2DMultisample", "samples too large");
8531     return;
8532   }
8533   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
8534   if (!framebuffer) {
8535     LOCAL_SET_GL_ERROR(
8536         GL_INVALID_OPERATION,
8537         name, "no framebuffer bound.");
8538     return;
8539   }
8540   GLuint service_id = 0;
8541   TextureRef* texture_ref = nullptr;
8542   if (client_texture_id) {
8543     texture_ref = GetTexture(client_texture_id);
8544     if (!texture_ref) {
8545       LOCAL_SET_GL_ERROR(
8546           GL_INVALID_OPERATION,
8547           name, "unknown texture_ref");
8548       return;
8549     }
8550     GLenum texture_target = texture_ref->texture()->target();
8551     if (texture_target != GLES2Util::GLFaceTargetToTextureTarget(textarget)) {
8552       LOCAL_SET_GL_ERROR(
8553           GL_INVALID_OPERATION,
8554           name, "Attachment textarget doesn't match texture target");
8555       return;
8556     }
8557     service_id = texture_ref->service_id();
8558   }
8559 
8560   if ((level > 0 && !feature_info_->IsWebGL2OrES3Context() &&
8561        !(fbo_render_mipmap_explicitly_enabled_ &&
8562          feature_info_->feature_flags().oes_fbo_render_mipmap)) ||
8563       !texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
8564     LOCAL_SET_GL_ERROR(
8565         GL_INVALID_VALUE,
8566         name, "level out of range");
8567     return;
8568   }
8569 
8570   if (texture_ref)
8571     DoBindOrCopyTexImageIfNeeded(texture_ref->texture(), textarget, 0);
8572 
8573   std::vector<GLenum> attachments;
8574   if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
8575     attachments.push_back(GL_DEPTH_ATTACHMENT);
8576     attachments.push_back(GL_STENCIL_ATTACHMENT);
8577   } else {
8578     attachments.push_back(attachment);
8579   }
8580   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
8581   for (size_t ii = 0; ii < attachments.size(); ++ii) {
8582     if (0 == samples) {
8583       api()->glFramebufferTexture2DEXTFn(target, attachments[ii], textarget,
8584                                          service_id, level);
8585     } else {
8586       api()->glFramebufferTexture2DMultisampleEXTFn(
8587           target, attachments[ii], textarget, service_id, level, samples);
8588     }
8589     GLenum error = LOCAL_PEEK_GL_ERROR(name);
8590     if (error == GL_NO_ERROR) {
8591       framebuffer->AttachTexture(attachments[ii], texture_ref, textarget, level,
8592                                  samples);
8593     }
8594   }
8595   if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
8596     framebuffer_state_.clear_state_dirty = true;
8597   }
8598 
8599   OnFboChanged();
8600 }
8601 
DoFramebufferTextureLayer(GLenum target,GLenum attachment,GLuint client_texture_id,GLint level,GLint layer)8602 void GLES2DecoderImpl::DoFramebufferTextureLayer(
8603     GLenum target, GLenum attachment, GLuint client_texture_id,
8604     GLint level, GLint layer) {
8605   const char* function_name = "glFramebufferTextureLayer";
8606 
8607   TextureRef* texture_ref = nullptr;
8608   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
8609   if (!framebuffer) {
8610     LOCAL_SET_GL_ERROR(
8611         GL_INVALID_OPERATION, function_name, "no framebuffer bound.");
8612     return;
8613   }
8614   GLuint service_id = 0;
8615   GLenum texture_target = 0;
8616   if (client_texture_id) {
8617     texture_ref = GetTexture(client_texture_id);
8618     if (!texture_ref) {
8619       LOCAL_SET_GL_ERROR(
8620           GL_INVALID_VALUE, function_name, "unknown texture");
8621       return;
8622     }
8623     service_id = texture_ref->service_id();
8624 
8625     texture_target = texture_ref->texture()->target();
8626     switch (texture_target) {
8627       case GL_TEXTURE_3D:
8628       case GL_TEXTURE_2D_ARRAY:
8629         break;
8630       default:
8631         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
8632             "texture is neither TEXTURE_3D nor TEXTURE_2D_ARRAY");
8633         return;
8634     }
8635     if (!texture_manager()->ValidForTarget(texture_target, level,
8636                                            0, 0, layer)) {
8637       LOCAL_SET_GL_ERROR(
8638           GL_INVALID_VALUE, function_name, "invalid level or layer");
8639       return;
8640     }
8641   }
8642   api()->glFramebufferTextureLayerFn(target, attachment, service_id, level,
8643                                      layer);
8644   if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
8645     framebuffer->AttachTextureLayer(
8646         GL_DEPTH_ATTACHMENT, texture_ref, texture_target, level, layer);
8647     framebuffer->AttachTextureLayer(
8648         GL_STENCIL_ATTACHMENT, texture_ref, texture_target, level, layer);
8649   } else {
8650     framebuffer->AttachTextureLayer(
8651         attachment, texture_ref, texture_target, level, layer);
8652   }
8653   if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
8654     framebuffer_state_.clear_state_dirty = true;
8655   }
8656 }
8657 
DoFramebufferTextureMultiviewOVR(GLenum target,GLenum attachment,GLuint client_texture_id,GLint level,GLint base_view_index,GLsizei num_views)8658 void GLES2DecoderImpl::DoFramebufferTextureMultiviewOVR(
8659     GLenum target,
8660     GLenum attachment,
8661     GLuint client_texture_id,
8662     GLint level,
8663     GLint base_view_index,
8664     GLsizei num_views) {
8665   // This is only supported in passthrough command buffer.
8666   NOTREACHED();
8667 }
8668 
DoGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params,GLsizei params_size)8669 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
8670     GLenum target,
8671     GLenum attachment,
8672     GLenum pname,
8673     GLint* params,
8674     GLsizei params_size) {
8675   const char kFunctionName[] = "glGetFramebufferAttachmentParameteriv";
8676   Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
8677   if (!framebuffer) {
8678     if (!feature_info_->IsWebGL2OrES3Context()) {
8679       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
8680           "no framebuffer bound");
8681       return;
8682     }
8683     if (!validators_->backbuffer_attachment.IsValid(attachment)) {
8684       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
8685           "invalid attachment for backbuffer");
8686       return;
8687     }
8688     switch (pname) {
8689       case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
8690         *params = static_cast<GLint>(GL_FRAMEBUFFER_DEFAULT);
8691         return;
8692       case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
8693       case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
8694       case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
8695       case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
8696       case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
8697       case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
8698       case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
8699       case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
8700         // Delegate to underlying driver.
8701         break;
8702       default:
8703         LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, kFunctionName,
8704             "invalid pname for backbuffer");
8705         return;
8706     }
8707     if (GetBackbufferServiceId() != 0) {  // Emulated backbuffer.
8708       switch (attachment) {
8709         case GL_BACK:
8710           attachment = GL_COLOR_ATTACHMENT0;
8711           break;
8712         case GL_DEPTH:
8713           attachment = GL_DEPTH_ATTACHMENT;
8714           break;
8715         case GL_STENCIL:
8716           attachment = GL_STENCIL_ATTACHMENT;
8717           break;
8718         default:
8719           NOTREACHED();
8720           break;
8721       }
8722     }
8723   } else {
8724     if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
8725       const Framebuffer::Attachment* depth =
8726           framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT);
8727       const Framebuffer::Attachment* stencil =
8728           framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT);
8729       if ((!depth && !stencil) ||
8730           (depth && stencil && depth->IsSameAttachment(stencil))) {
8731         attachment = GL_DEPTH_ATTACHMENT;
8732       } else {
8733         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
8734                            "depth and stencil attachment mismatch");
8735         return;
8736       }
8737     }
8738   }
8739   if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
8740       features().use_img_for_multisampled_render_to_texture) {
8741     pname = GL_TEXTURE_SAMPLES_IMG;
8742   }
8743   if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
8744     DCHECK(framebuffer);
8745     // If we query from the driver, it will be service ID; however, we need to
8746     // return the client ID here.
8747     const Framebuffer::Attachment* attachment_object =
8748         framebuffer->GetAttachment(attachment);
8749     *params = attachment_object ? attachment_object->object_name() : 0;
8750     return;
8751   }
8752 
8753   api()->glGetFramebufferAttachmentParameterivEXTFn(target, attachment, pname,
8754                                                     params);
8755   // We didn't perform a full error check before gl call.
8756   LOCAL_PEEK_GL_ERROR(kFunctionName);
8757 }
8758 
DoGetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params,GLsizei params_size)8759 void GLES2DecoderImpl::DoGetRenderbufferParameteriv(GLenum target,
8760                                                     GLenum pname,
8761                                                     GLint* params,
8762                                                     GLsizei params_size) {
8763   Renderbuffer* renderbuffer =
8764       GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
8765   if (!renderbuffer) {
8766     LOCAL_SET_GL_ERROR(
8767         GL_INVALID_OPERATION,
8768         "glGetRenderbufferParameteriv", "no renderbuffer bound");
8769     return;
8770   }
8771 
8772   EnsureRenderbufferBound();
8773   switch (pname) {
8774     case GL_RENDERBUFFER_INTERNAL_FORMAT:
8775       *params = renderbuffer->internal_format();
8776       break;
8777     case GL_RENDERBUFFER_WIDTH:
8778       *params = renderbuffer->width();
8779       break;
8780     case GL_RENDERBUFFER_HEIGHT:
8781       *params = renderbuffer->height();
8782       break;
8783     case GL_RENDERBUFFER_SAMPLES_EXT:
8784       if (features().use_img_for_multisampled_render_to_texture) {
8785         api()->glGetRenderbufferParameterivEXTFn(
8786             target, GL_RENDERBUFFER_SAMPLES_IMG, params);
8787       } else {
8788         api()->glGetRenderbufferParameterivEXTFn(
8789             target, GL_RENDERBUFFER_SAMPLES_EXT, params);
8790       }
8791       break;
8792     default:
8793       api()->glGetRenderbufferParameterivEXTFn(target, pname, params);
8794       break;
8795   }
8796 }
8797 
DoBlitFramebufferCHROMIUM(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)8798 void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
8799     GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
8800     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
8801     GLbitfield mask, GLenum filter) {
8802   const char* func_name = "glBlitFramebufferCHROMIUM";
8803   DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
8804 
8805   if (!CheckFramebufferValid(GetBoundDrawFramebuffer(),
8806                              GetDrawFramebufferTarget(),
8807                              GL_INVALID_FRAMEBUFFER_OPERATION, func_name)) {
8808     return;
8809   }
8810 
8811   // We need to get this before checking if the read framebuffer is valid.
8812   // Checking the read framebuffer may clear attachments which would mark the
8813   // draw framebuffer as incomplete. Framebuffer::GetFramebufferValidSize()
8814   // requires the framebuffer to be complete.
8815   gfx::Size draw_size = GetBoundDrawFramebufferSize();
8816 
8817   if (!CheckFramebufferValid(GetBoundReadFramebuffer(),
8818                              GetReadFramebufferTarget(),
8819                              GL_INVALID_FRAMEBUFFER_OPERATION, func_name)) {
8820     return;
8821   }
8822 
8823   if (GetBoundFramebufferSamples(GL_DRAW_FRAMEBUFFER) > 0) {
8824     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8825                        "destination framebuffer is multisampled");
8826     return;
8827   }
8828 
8829   GLsizei read_buffer_samples = GetBoundFramebufferSamples(GL_READ_FRAMEBUFFER);
8830   if (read_buffer_samples > 0 &&
8831       (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) {
8832     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8833         "src framebuffer is multisampled, but src/dst regions are different");
8834     return;
8835   }
8836 
8837   // If color/depth/stencil buffer have no image, we can remove corresponding
8838   // bitfield from mask and return early if mask equals to 0.
8839   // But validations should be done against the original mask.
8840   GLbitfield mask_blit = mask;
8841 
8842   // Detect that designated read/depth/stencil buffer in read framebuffer miss
8843   // image, and the corresponding buffers in draw framebuffer have image.
8844   bool read_framebuffer_miss_image = false;
8845 
8846   // Check whether read framebuffer and draw framebuffer have identical image
8847   // TODO(yunchao): consider doing something like CheckFramebufferStatus().
8848   // We cache the validation results, and if read_framebuffer doesn't change,
8849   // draw_framebuffer doesn't change, then use the cached status.
8850   enum FeedbackLoopState {
8851     FeedbackLoopTrue,
8852     FeedbackLoopFalse,
8853     FeedbackLoopUnknown
8854   };
8855 
8856   FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown;
8857   Framebuffer* read_framebuffer =
8858       framebuffer_state_.bound_read_framebuffer.get();
8859   Framebuffer* draw_framebuffer =
8860       framebuffer_state_.bound_draw_framebuffer.get();
8861   // If both read framebuffer and draw framebuffer are default framebuffer,
8862   // They always have identical image. Otherwise, if one of read framebuffer
8863   // and draw framebuffe is default framebuffer, but the other is fbo, they
8864   // always have no identical image.
8865   if (!read_framebuffer && !draw_framebuffer) {
8866     is_feedback_loop = FeedbackLoopTrue;
8867   } else if (!read_framebuffer || !draw_framebuffer) {
8868     is_feedback_loop = FeedbackLoopFalse;
8869     if (read_framebuffer) {
8870       if (((mask & GL_COLOR_BUFFER_BIT) != 0 &&
8871           !GetBoundReadFramebufferInternalFormat()) ||
8872           ((mask & GL_DEPTH_BUFFER_BIT) != 0 &&
8873           !read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT) &&
8874           BoundFramebufferHasDepthAttachment()) ||
8875           ((mask & GL_STENCIL_BUFFER_BIT) != 0 &&
8876           !read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT) &&
8877           BoundFramebufferHasStencilAttachment())) {
8878         read_framebuffer_miss_image = true;
8879       }
8880     }
8881   } else {
8882     DCHECK(read_framebuffer && draw_framebuffer);
8883     if ((mask & GL_DEPTH_BUFFER_BIT) != 0) {
8884       const Framebuffer::Attachment* depth_buffer_read =
8885           read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT);
8886       const Framebuffer::Attachment* depth_buffer_draw =
8887           draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT);
8888       if (!depth_buffer_draw || !depth_buffer_read) {
8889         mask_blit &= ~GL_DEPTH_BUFFER_BIT;
8890         if (depth_buffer_draw) {
8891           read_framebuffer_miss_image = true;
8892         }
8893       } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) {
8894         is_feedback_loop = FeedbackLoopTrue;
8895       }
8896     }
8897     if ((mask & GL_STENCIL_BUFFER_BIT) != 0) {
8898       const Framebuffer::Attachment* stencil_buffer_read =
8899           read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT);
8900       const Framebuffer::Attachment* stencil_buffer_draw =
8901           draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT);
8902       if (!stencil_buffer_draw || !stencil_buffer_read) {
8903         mask_blit &= ~GL_STENCIL_BUFFER_BIT;
8904         if (stencil_buffer_draw) {
8905           read_framebuffer_miss_image = true;
8906         }
8907       } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) {
8908         is_feedback_loop = FeedbackLoopTrue;
8909       }
8910     }
8911   }
8912 
8913   GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
8914   GLenum src_type = GetBoundReadFramebufferTextureType();
8915 
8916   bool read_buffer_has_srgb = GLES2Util::GetColorEncodingFromInternalFormat(
8917                                   src_internal_format) == GL_SRGB;
8918   bool draw_buffers_has_srgb = false;
8919   if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
8920     bool is_src_signed_int =
8921         GLES2Util::IsSignedIntegerFormat(src_internal_format);
8922     bool is_src_unsigned_int =
8923         GLES2Util::IsUnsignedIntegerFormat(src_internal_format);
8924     DCHECK(!is_src_signed_int || !is_src_unsigned_int);
8925 
8926     if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) {
8927       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8928                          "invalid filter for integer format");
8929       return;
8930     }
8931 
8932     GLenum src_sized_format =
8933         GLES2Util::ConvertToSizedFormat(src_internal_format, src_type);
8934     DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown));
8935     const Framebuffer::Attachment* read_buffer =
8936         is_feedback_loop == FeedbackLoopUnknown ?
8937         read_framebuffer->GetReadBufferAttachment() : nullptr;
8938     bool draw_buffer_has_image = false;
8939     for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) {
8940       GLenum dst_format = GetBoundColorDrawBufferInternalFormat(
8941           static_cast<GLint>(ii));
8942       GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii));
8943       if (dst_format == 0)
8944         continue;
8945       draw_buffer_has_image = true;
8946       if (!src_internal_format) {
8947         read_framebuffer_miss_image = true;
8948       }
8949       if (GLES2Util::GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB)
8950         draw_buffers_has_srgb = true;
8951       if (read_buffer_samples > 0 &&
8952           (src_sized_format !=
8953            GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) {
8954         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8955                            "src and dst formats differ for color");
8956         return;
8957       }
8958       bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format);
8959       bool is_dst_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(dst_format);
8960       DCHECK(!is_dst_signed_int || !is_dst_unsigned_int);
8961       if (is_src_signed_int != is_dst_signed_int ||
8962           is_src_unsigned_int != is_dst_unsigned_int) {
8963         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8964                            "incompatible src/dst color formats");
8965         return;
8966       }
8967       // Check whether draw buffers have identical color image with read buffer
8968       if (is_feedback_loop == FeedbackLoopUnknown) {
8969         GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + ii);
8970         DCHECK(draw_framebuffer);
8971         const Framebuffer::Attachment* draw_buffer =
8972             draw_framebuffer->GetAttachment(attachment);
8973         if (!draw_buffer || !read_buffer) {
8974           continue;
8975         }
8976         if (draw_buffer->IsSameAttachment(read_buffer)) {
8977           is_feedback_loop = FeedbackLoopTrue;
8978           break;
8979         }
8980       }
8981     }
8982     if (draw_framebuffer && !draw_buffer_has_image)
8983       mask_blit &= ~GL_COLOR_BUFFER_BIT;
8984   }
8985   if (is_feedback_loop == FeedbackLoopTrue) {
8986     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8987         "source buffer and destination buffers are identical");
8988     return;
8989   }
8990   if (read_framebuffer_miss_image == true) {
8991     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8992        "The designated attachment point(s) in read framebuffer miss image");
8993     return;
8994   }
8995 
8996   if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) {
8997     if (filter != GL_NEAREST) {
8998       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8999                          "invalid filter for depth/stencil");
9000       return;
9001     }
9002   }
9003 
9004   mask = mask_blit;
9005   if (!mask)
9006     return;
9007 
9008   if (((mask & GL_DEPTH_BUFFER_BIT) != 0 &&
9009       (GetBoundFramebufferDepthFormat(GL_READ_FRAMEBUFFER) !=
9010       GetBoundFramebufferDepthFormat(GL_DRAW_FRAMEBUFFER))) ||
9011       ((mask & GL_STENCIL_BUFFER_BIT) != 0 &&
9012       ((GetBoundFramebufferStencilFormat(GL_READ_FRAMEBUFFER) !=
9013       GetBoundFramebufferStencilFormat(GL_DRAW_FRAMEBUFFER))))) {
9014     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
9015                        "src and dst formats differ for depth/stencil");
9016     return;
9017   }
9018 
9019   base::CheckedNumeric<GLint> src_width_temp = srcX1;
9020   src_width_temp -= srcX0;
9021   base::CheckedNumeric<GLint> src_height_temp = srcY1;
9022   src_height_temp -= srcY0;
9023   base::CheckedNumeric<GLint> dst_width_temp = dstX1;
9024   dst_width_temp -= dstX0;
9025   base::CheckedNumeric<GLint> dst_height_temp = dstY1;
9026   dst_height_temp -= dstY0;
9027   if (!src_width_temp.Abs().IsValid() || !src_height_temp.Abs().IsValid() ||
9028       !dst_width_temp.Abs().IsValid() || !dst_height_temp.Abs().IsValid()) {
9029     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
9030                        "the width or height of src or dst region overflowed");
9031     return;
9032   }
9033 
9034   if (workarounds().adjust_src_dst_region_for_blitframebuffer) {
9035     gfx::Size read_size = GetBoundReadFramebufferSize();
9036     GLint src_x = srcX1 > srcX0 ? srcX0 : srcX1;
9037     GLint src_y = srcY1 > srcY0 ? srcY0 : srcY1;
9038     unsigned int src_width = base::checked_cast<unsigned int>(
9039         src_width_temp.Abs().ValueOrDefault(0));
9040     unsigned int src_height = base::checked_cast<unsigned int>(
9041         src_height_temp.Abs().ValueOrDefault(0));
9042 
9043     GLint dst_x = dstX1 > dstX0 ? dstX0 : dstX1;
9044     GLint dst_y = dstY1 > dstY0 ? dstY0 : dstY1;
9045     unsigned int dst_width = base::checked_cast<unsigned int>(
9046         dst_width_temp.Abs().ValueOrDefault(0));
9047     unsigned int dst_height = base::checked_cast<unsigned int>(
9048         dst_height_temp.Abs().ValueOrDefault(0));
9049 
9050     if (dst_width == 0 || src_width == 0 || dst_height == 0 ||
9051         src_height == 0) {
9052       return;
9053     }
9054 
9055     gfx::Rect src_bounds(0, 0, read_size.width(), read_size.height());
9056     gfx::Rect src_region(src_x, src_y, src_width, src_height);
9057 
9058     gfx::Rect dst_bounds(0, 0, draw_size.width(), draw_size.height());
9059     gfx::Rect dst_region(dst_x, dst_y, dst_width, dst_height);
9060 
9061     if (gfx::IntersectRects(dst_bounds, dst_region).IsEmpty()) {
9062       return;
9063     }
9064 
9065     bool x_flipped = ((srcX1 > srcX0) && (dstX1 < dstX0)) ||
9066                      ((srcX1 < srcX0) && (dstX1 > dstX0));
9067     bool y_flipped = ((srcY1 > srcY0) && (dstY1 < dstY0)) ||
9068                      ((srcY1 < srcY0) && (dstY1 > dstY0));
9069 
9070     if (!dst_bounds.Contains(dst_region)) {
9071       // dst_region is not within dst_bounds. We want to adjust it to a
9072       // reasonable size. This is done by halving the dst_region until it is at
9073       // most twice the size of the framebuffer. We cut it in half instead
9074       // of arbitrarily shrinking it to fit so that we don't end up with
9075       // non-power-of-two scale factors which could mess up pixel interpolation.
9076       // Naively clipping the dst rect and then proportionally sizing the
9077       // src rect yields incorrect results.
9078 
9079       unsigned int dst_x_halvings = 0;
9080       unsigned int dst_y_halvings = 0;
9081       int dst_origin_x = dst_x;
9082       int dst_origin_y = dst_y;
9083 
9084       int dst_clipped_width = dst_region.width();
9085       while (dst_clipped_width > 2 * dst_bounds.width()) {
9086         dst_clipped_width = dst_clipped_width >> 1;
9087         dst_x_halvings++;
9088       }
9089 
9090       int dst_clipped_height = dst_region.height();
9091       while (dst_clipped_height > 2 * dst_bounds.height()) {
9092         dst_clipped_height = dst_clipped_height >> 1;
9093         dst_y_halvings++;
9094       }
9095 
9096       // Before this block, we check that the two rectangles intersect.
9097       // Now, compute the location of a new region origin such that we use the
9098       // scaled dimensions but the new region has the same intersection as the
9099       // original region.
9100 
9101       int left = dst_region.x();
9102       int right = dst_region.right();
9103       int top = dst_region.y();
9104       int bottom = dst_region.bottom();
9105 
9106       if (left >= 0 && left < dst_bounds.width()) {
9107         // Left edge is in-bounds
9108         dst_origin_x = dst_x;
9109       } else if (right > 0 && right <= dst_bounds.width()) {
9110         // Right edge is in-bounds
9111         dst_origin_x = right - dst_clipped_width;
9112       } else {
9113         // Region completely spans bounds
9114         dst_origin_x = dst_x;
9115       }
9116 
9117       if (top >= 0 && top < dst_bounds.height()) {
9118         // Top edge is in-bounds
9119         dst_origin_y = dst_y;
9120       } else if (bottom > 0 && bottom <= dst_bounds.height()) {
9121         // Bottom edge is in-bounds
9122         dst_origin_y = bottom - dst_clipped_height;
9123       } else {
9124         // Region completely spans bounds
9125         dst_origin_y = dst_y;
9126       }
9127 
9128       dst_region.SetRect(dst_origin_x, dst_origin_y, dst_clipped_width,
9129                          dst_clipped_height);
9130 
9131       // Offsets from the bottom left corner of the original region to
9132       // the bottom left corner of the clipped region.
9133       // This value (after it is scaled) is the respective offset we will apply
9134       // to the src origin.
9135       base::CheckedNumeric<unsigned int> checked_xoffset(dst_region.x() -
9136                                                          dst_x);
9137       base::CheckedNumeric<unsigned int> checked_yoffset(dst_region.y() -
9138                                                          dst_y);
9139 
9140       // if X/Y is reversed, use the top/right out-of-bounds region to compute
9141       // the origin offset instead of the left/bottom out-of-bounds region
9142       if (x_flipped) {
9143         checked_xoffset = (dst_x + dst_width - dst_region.right());
9144       }
9145       if (y_flipped) {
9146         checked_yoffset = (dst_y + dst_height - dst_region.bottom());
9147       }
9148 
9149       // These offsets should never overflow.
9150       unsigned int xoffset, yoffset;
9151       if (!checked_xoffset.AssignIfValid(&xoffset) ||
9152           !checked_yoffset.AssignIfValid(&yoffset)) {
9153         NOTREACHED();
9154         LOCAL_SET_GL_ERROR(
9155             GL_INVALID_VALUE, func_name,
9156             "the width or height of src or dst region overflowed");
9157         return;
9158       }
9159 
9160       // Adjust the src region by the same factor
9161       src_region.SetRect(src_x + (xoffset >> dst_x_halvings),
9162                          src_y + (yoffset >> dst_y_halvings),
9163                          src_region.width() >> dst_x_halvings,
9164                          src_region.height() >> dst_y_halvings);
9165 
9166       // If the src was scaled to 0, set it to 1 so the src is non-empty.
9167       if (src_region.width() == 0) {
9168         src_region.set_width(1);
9169       }
9170       if (src_region.height() == 0) {
9171         src_region.set_height(1);
9172       }
9173     }
9174 
9175     if (!src_bounds.Contains(src_region)) {
9176       // If pixels lying outside the read framebuffer, adjust src region
9177       // and dst region to appropriate in-bounds regions respectively.
9178       src_region.Intersect(src_bounds);
9179       GLuint src_real_width = src_region.width();
9180       GLuint src_real_height = src_region.height();
9181       GLuint xoffset = src_region.x() - src_x;
9182       GLuint yoffset = src_region.y() - src_y;
9183       // if X/Y is reversed, use the top/right out-of-bounds region for mapping
9184       // to dst region, instead of left/bottom out-of-bounds region for mapping.
9185       if (x_flipped) {
9186         xoffset = src_x + src_width - src_region.x() - src_region.width();
9187       }
9188       if (y_flipped) {
9189         yoffset = src_y + src_height - src_region.y() - src_region.height();
9190       }
9191 
9192       GLfloat dst_mapping_width =
9193           static_cast<GLfloat>(src_real_width) * dst_width / src_width;
9194       GLfloat dst_mapping_height =
9195           static_cast<GLfloat>(src_real_height) * dst_height / src_height;
9196       GLfloat dst_mapping_xoffset =
9197           static_cast<GLfloat>(xoffset) * dst_width / src_width;
9198       GLfloat dst_mapping_yoffset =
9199           static_cast<GLfloat>(yoffset) * dst_height / src_height;
9200 
9201       GLuint dst_mapping_x0 =
9202           std::round(dst_x + dst_mapping_xoffset);
9203       GLuint dst_mapping_y0 =
9204           std::round(dst_y + dst_mapping_yoffset);
9205 
9206       GLuint dst_mapping_x1 =
9207           std::round(dst_x + dst_mapping_xoffset + dst_mapping_width);
9208       GLuint dst_mapping_y1 =
9209           std::round(dst_y + dst_mapping_yoffset + dst_mapping_height);
9210 
9211       dst_region.SetRect(dst_mapping_x0, dst_mapping_y0,
9212                          dst_mapping_x1 - dst_mapping_x0,
9213                          dst_mapping_y1 - dst_mapping_y0);
9214     }
9215 
9216     // Set the src and dst endpoints. If they were previously flipped,
9217     // set them as flipped.
9218     srcX0 = srcX0 < srcX1 ? src_region.x() : src_region.right();
9219     srcY0 = srcY0 < srcY1 ? src_region.y() : src_region.bottom();
9220     srcX1 = srcX0 < srcX1 ? src_region.right() : src_region.x();
9221     srcY1 = srcY0 < srcY1 ? src_region.bottom() : src_region.y();
9222 
9223     dstX0 = dstX0 < dstX1 ? dst_region.x() : dst_region.right();
9224     dstY0 = dstY0 < dstY1 ? dst_region.y() : dst_region.bottom();
9225     dstX1 = dstX0 < dstX1 ? dst_region.right() : dst_region.x();
9226     dstY1 = dstY0 < dstY1 ? dst_region.bottom() : dst_region.y();
9227   }
9228 
9229   bool enable_srgb =
9230       (read_buffer_has_srgb || draw_buffers_has_srgb) &&
9231       ((mask & GL_COLOR_BUFFER_BIT) != 0);
9232   bool encode_srgb_only =
9233       (draw_buffers_has_srgb && !read_buffer_has_srgb) &&
9234       ((mask & GL_COLOR_BUFFER_BIT) != 0);
9235   if (!enable_srgb ||
9236       read_buffer_samples > 0 ||
9237       !feature_info_->feature_flags().desktop_srgb_support ||
9238       gl_version_info().IsAtLeastGL(4, 4) ||
9239       (gl_version_info().IsAtLeastGL(4, 2) && encode_srgb_only)) {
9240     if (enable_srgb && feature_info_->feature_flags().ext_srgb_write_control) {
9241       state_.EnableDisableFramebufferSRGB(enable_srgb);
9242     }
9243 
9244     api()->glBlitFramebufferFn(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
9245                                dstY1, mask, filter);
9246     return;
9247   }
9248 
9249   // emulate srgb for desktop core profile when GL version < 4.4
9250   // TODO(yunchao): Need to handle this situation:
9251   // There are multiple draw buffers. Some of them are srgb images.
9252   // The others are not.
9253   state_.EnableDisableFramebufferSRGB(true);
9254   if (!InitializeSRGBConverter(func_name)) {
9255     return;
9256   }
9257   GLenum src_format =
9258       TextureManager::ExtractFormatFromStorageFormat(src_internal_format);
9259   srgb_converter_->Blit(this, srcX0, srcY0, srcX1, srcY1,
9260                         dstX0, dstY0, dstX1, dstY1,
9261                         mask, filter,
9262                         GetBoundReadFramebufferSize(),
9263                         GetBoundReadFramebufferServiceId(),
9264                         src_internal_format, src_format, src_type,
9265                         GetBoundDrawFramebufferServiceId(),
9266                         read_buffer_has_srgb, draw_buffers_has_srgb,
9267                         state_.enable_flags.scissor_test);
9268 }
9269 
InitializeSRGBConverter(const char * function_name)9270 bool GLES2DecoderImpl::InitializeSRGBConverter(
9271     const char* function_name) {
9272   if (!srgb_converter_.get()) {
9273     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
9274     srgb_converter_.reset(
9275         new SRGBConverter(feature_info_.get()));
9276     srgb_converter_->InitializeSRGBConverter(this);
9277     if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) {
9278       return false;
9279     }
9280   }
9281   return true;
9282 }
9283 
UnbindTexture(TextureRef * texture_ref,bool supports_separate_framebuffer_binds)9284 void GLES2DecoderImpl::UnbindTexture(TextureRef* texture_ref,
9285                                      bool supports_separate_framebuffer_binds) {
9286   Texture* texture = texture_ref->texture();
9287   if (texture->IsAttachedToFramebuffer()) {
9288     framebuffer_state_.clear_state_dirty = true;
9289   }
9290   // Unbind texture_ref from texture_ref units.
9291   state_.UnbindTexture(texture_ref);
9292 
9293   // Unbind from current framebuffers.
9294   if (supports_separate_framebuffer_binds) {
9295     if (framebuffer_state_.bound_read_framebuffer.get()) {
9296       framebuffer_state_.bound_read_framebuffer->UnbindTexture(
9297           GL_READ_FRAMEBUFFER_EXT, texture_ref);
9298     }
9299     if (framebuffer_state_.bound_draw_framebuffer.get()) {
9300       framebuffer_state_.bound_draw_framebuffer->UnbindTexture(
9301           GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
9302     }
9303   } else {
9304     if (framebuffer_state_.bound_draw_framebuffer.get()) {
9305       framebuffer_state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER,
9306                                                                texture_ref);
9307     }
9308   }
9309 }
9310 
EnsureRenderbufferBound()9311 void GLES2DecoderImpl::EnsureRenderbufferBound() {
9312   if (!state_.bound_renderbuffer_valid) {
9313     state_.bound_renderbuffer_valid = true;
9314     api()->glBindRenderbufferEXTFn(GL_RENDERBUFFER,
9315                                    state_.bound_renderbuffer.get()
9316                                        ? state_.bound_renderbuffer->service_id()
9317                                        : 0);
9318   }
9319 }
9320 
RenderbufferStorageMultisampleWithWorkaround(GLenum target,GLsizei samples,GLenum internal_format,GLsizei width,GLsizei height,ForcedMultisampleMode mode)9321 void GLES2DecoderImpl::RenderbufferStorageMultisampleWithWorkaround(
9322     GLenum target,
9323     GLsizei samples,
9324     GLenum internal_format,
9325     GLsizei width,
9326     GLsizei height,
9327     ForcedMultisampleMode mode) {
9328   RegenerateRenderbufferIfNeeded(state_.bound_renderbuffer.get());
9329   EnsureRenderbufferBound();
9330   RenderbufferStorageMultisampleHelper(target, samples, internal_format, width,
9331                                        height, mode);
9332 }
9333 
RenderbufferStorageMultisampleHelper(GLenum target,GLsizei samples,GLenum internal_format,GLsizei width,GLsizei height,ForcedMultisampleMode mode)9334 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
9335     GLenum target,
9336     GLsizei samples,
9337     GLenum internal_format,
9338     GLsizei width,
9339     GLsizei height,
9340     ForcedMultisampleMode mode) {
9341   if (samples == 0) {
9342     api()->glRenderbufferStorageEXTFn(target, internal_format, width, height);
9343     return;
9344   }
9345 
9346   // TODO(sievers): This could be resolved at the GL binding level, but the
9347   // binding process is currently a bit too 'brute force'.
9348 
9349   // Note that when this is called via the
9350   // RenderbufferStorageMultisampleEXT handler,
9351   // kForceExtMultisampledRenderToTexture is passed in order to
9352   // prevent the core ES 3.0 multisampling code path from being used.
9353   if (mode == kForceExtMultisampledRenderToTexture) {
9354     api()->glRenderbufferStorageMultisampleEXTFn(
9355         target, samples, internal_format, width, height);
9356   } else {
9357     api()->glRenderbufferStorageMultisampleFn(target, samples, internal_format,
9358                                               width, height);
9359   }
9360 }
9361 
RenderbufferStorageMultisampleHelperAMD(GLenum target,GLsizei samples,GLsizei storageSamples,GLenum internal_format,GLsizei width,GLsizei height,ForcedMultisampleMode mode)9362 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelperAMD(
9363     GLenum target,
9364     GLsizei samples,
9365     GLsizei storageSamples,
9366     GLenum internal_format,
9367     GLsizei width,
9368     GLsizei height,
9369     ForcedMultisampleMode mode) {
9370   api()->glRenderbufferStorageMultisampleAdvancedAMDFn(
9371       target, samples, storageSamples, internal_format, width, height);
9372 }
9373 
RegenerateRenderbufferIfNeeded(Renderbuffer * renderbuffer)9374 bool GLES2DecoderImpl::RegenerateRenderbufferIfNeeded(
9375     Renderbuffer* renderbuffer) {
9376   if (!renderbuffer->RegenerateAndBindBackingObjectIfNeeded(workarounds())) {
9377     return false;
9378   }
9379 
9380   if (renderbuffer != state_.bound_renderbuffer.get()) {
9381     // The renderbuffer bound in the driver has changed to the new
9382     // renderbuffer->service_id(). If that isn't state_.bound_renderbuffer,
9383     // then state_.bound_renderbuffer is no longer bound in the driver.
9384     state_.bound_renderbuffer_valid = false;
9385   }
9386 
9387   return true;
9388 }
9389 
ValidateRenderbufferStorageMultisample(GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)9390 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
9391     GLsizei samples,
9392     GLenum internalformat,
9393     GLsizei width,
9394     GLsizei height) {
9395   if (samples > renderbuffer_manager()->max_samples()) {
9396     LOCAL_SET_GL_ERROR(
9397         GL_INVALID_VALUE,
9398         "glRenderbufferStorageMultisample", "samples too large");
9399     return false;
9400   }
9401 
9402   if (width > renderbuffer_manager()->max_renderbuffer_size() ||
9403       height > renderbuffer_manager()->max_renderbuffer_size()) {
9404     LOCAL_SET_GL_ERROR(
9405         GL_INVALID_VALUE,
9406         "glRenderbufferStorageMultisample", "dimensions too large");
9407     return false;
9408   }
9409 
9410   uint32_t estimated_size = 0;
9411   if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
9412            width, height, samples, internalformat, &estimated_size)) {
9413     LOCAL_SET_GL_ERROR(
9414         GL_OUT_OF_MEMORY,
9415         "glRenderbufferStorageMultisample", "dimensions too large");
9416     return false;
9417   }
9418 
9419   return true;
9420 }
9421 
ValidateRenderbufferStorageMultisampleAMD(GLsizei samples,GLsizei storageSamples,GLenum internalformat,GLsizei width,GLsizei height)9422 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisampleAMD(
9423     GLsizei samples,
9424     GLsizei storageSamples,
9425     GLenum internalformat,
9426     GLsizei width,
9427     GLsizei height) {
9428   if (samples > renderbuffer_manager()->max_samples()) {
9429     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRenderbufferStorageMultisample",
9430                        "samples too large");
9431     return false;
9432   }
9433 
9434   if (width > renderbuffer_manager()->max_renderbuffer_size() ||
9435       height > renderbuffer_manager()->max_renderbuffer_size()) {
9436     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRenderbufferStorageMultisample",
9437                        "dimensions too large");
9438     return false;
9439   }
9440 
9441   uint32_t estimated_size = 0;
9442   if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
9443           width, height, samples, internalformat, &estimated_size)) {
9444     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glRenderbufferStorageMultisample",
9445                        "dimensions too large");
9446     return false;
9447   }
9448 
9449   return true;
9450 }
9451 
DoRenderbufferStorageMultisampleCHROMIUM(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)9452 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
9453     GLenum target, GLsizei samples, GLenum internalformat,
9454     GLsizei width, GLsizei height) {
9455   Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
9456   if (!renderbuffer) {
9457     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9458                        "glRenderbufferStorageMultisampleCHROMIUM",
9459                        "no renderbuffer bound");
9460     return;
9461   }
9462 
9463   if (!ValidateRenderbufferStorageMultisample(
9464       samples, internalformat, width, height)) {
9465     return;
9466   }
9467 
9468   GLenum impl_format =
9469       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
9470           internalformat);
9471   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
9472       "glRenderbufferStorageMultisampleCHROMIUM");
9473   RenderbufferStorageMultisampleWithWorkaround(target, samples, impl_format,
9474                                                width, height, kDoNotForce);
9475   GLenum error =
9476       LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
9477   if (error == GL_NO_ERROR) {
9478     if (workarounds().validate_multisample_buffer_allocation) {
9479       if (!VerifyMultisampleRenderbufferIntegrity(
9480           renderbuffer->service_id(), impl_format)) {
9481         LOCAL_SET_GL_ERROR(
9482             GL_OUT_OF_MEMORY,
9483             "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
9484         return;
9485       }
9486     }
9487 
9488     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples,
9489                                                  internalformat, width, height);
9490   }
9491 }
9492 
DoRenderbufferStorageMultisampleAdvancedAMD(GLenum target,GLsizei samples,GLsizei storageSamples,GLenum internalformat,GLsizei width,GLsizei height)9493 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleAdvancedAMD(
9494     GLenum target,
9495     GLsizei samples,
9496     GLsizei storageSamples,
9497     GLenum internalformat,
9498     GLsizei width,
9499     GLsizei height) {
9500   Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
9501   if (!renderbuffer) {
9502     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9503                        "glRenderbufferStorageMultisampleAdvancedAMD",
9504                        "no renderbuffer bound");
9505     return;
9506   }
9507 
9508   if (!ValidateRenderbufferStorageMultisampleAMD(
9509           samples, storageSamples, internalformat, width, height)) {
9510     return;
9511   }
9512 
9513   GLenum impl_format =
9514       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
9515           internalformat);
9516   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
9517       "glRenderbufferStorageMultisampleAdvancedAMD");
9518   RenderbufferStorageMultisampleHelperAMD(
9519       target, samples, storageSamples, impl_format, width, height, kDoNotForce);
9520   GLenum error =
9521       LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleAdvancedAMD");
9522   if (error == GL_NO_ERROR) {
9523     if (workarounds().validate_multisample_buffer_allocation) {
9524       if (!VerifyMultisampleRenderbufferIntegrity(renderbuffer->service_id(),
9525                                                   impl_format)) {
9526         LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY,
9527                            "glRenderbufferStorageMultisampleAdvancedAMD",
9528                            "out of memory");
9529         return;
9530       }
9531     }
9532 
9533     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples,
9534                                                  internalformat, width, height);
9535   }
9536 }
9537 
9538 // This is the handler for multisampled_render_to_texture extensions.
DoRenderbufferStorageMultisampleEXT(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)9539 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
9540     GLenum target, GLsizei samples, GLenum internalformat,
9541     GLsizei width, GLsizei height) {
9542   Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
9543   if (!renderbuffer) {
9544     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9545                        "glRenderbufferStorageMultisampleEXT",
9546                        "no renderbuffer bound");
9547     return;
9548   }
9549 
9550   if (!ValidateRenderbufferStorageMultisample(
9551       samples, internalformat, width, height)) {
9552     return;
9553   }
9554 
9555   GLenum impl_format =
9556       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
9557           internalformat);
9558   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
9559   RenderbufferStorageMultisampleWithWorkaround(
9560       target, samples, impl_format, width, height,
9561       kForceExtMultisampledRenderToTexture);
9562   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
9563   if (error == GL_NO_ERROR) {
9564     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples,
9565                                                  internalformat, width, height);
9566   }
9567 }
9568 
9569 // This function validates the allocation of a multisampled renderbuffer
9570 // by clearing it to a key color, blitting the contents to a texture, and
9571 // reading back the color to ensure it matches the key.
VerifyMultisampleRenderbufferIntegrity(GLuint renderbuffer,GLenum format)9572 bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
9573     GLuint renderbuffer, GLenum format) {
9574 
9575   // Only validate color buffers.
9576   // These formats have been selected because they are very common or are known
9577   // to be used by the WebGL backbuffer. If problems are observed with other
9578   // color formats they can be added here.
9579   GLenum pixel_format = GL_RGBA;
9580   GLenum pixel_type = GL_UNSIGNED_BYTE;
9581   switch (format) {
9582     case GL_RGB8:
9583       pixel_format = GL_RGB;
9584       break;
9585     case GL_RGBA8:
9586       break;
9587     default:
9588       return true;
9589   }
9590 
9591   GLint draw_framebuffer, read_framebuffer;
9592 
9593   // Cache framebuffer and texture bindings.
9594   api()->glGetIntegervFn(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
9595   api()->glGetIntegervFn(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
9596 
9597   if (!validation_fbo_) {
9598     api()->glGenFramebuffersEXTFn(1, &validation_fbo_multisample_);
9599     api()->glGenFramebuffersEXTFn(1, &validation_fbo_);
9600   }
9601 
9602   GLint bound_texture;
9603   api()->glGetIntegervFn(GL_TEXTURE_BINDING_2D, &bound_texture);
9604   GLuint validation_texture;
9605   TextureMap::iterator iter = validation_textures_.find(format);
9606   if (iter == validation_textures_.end()) {
9607     // Create additional resources needed for the verification.
9608     api()->glGenTexturesFn(1, &validation_texture);
9609     validation_textures_.insert(std::make_pair(format, validation_texture));
9610 
9611     // Texture only needs to be 1x1.
9612     api()->glBindTextureFn(GL_TEXTURE_2D, validation_texture);
9613     api()->glTexImage2DFn(GL_TEXTURE_2D, 0, format, 1, 1, 0, pixel_format,
9614                           pixel_type, nullptr);
9615   } else {
9616     validation_texture = iter->second;
9617   }
9618   api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, validation_fbo_);
9619   api()->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9620                                      GL_TEXTURE_2D, validation_texture, 0);
9621   api()->glBindTextureFn(GL_TEXTURE_2D, bound_texture);
9622 
9623   api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, validation_fbo_multisample_);
9624   api()->glFramebufferRenderbufferEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9625                                         GL_RENDERBUFFER, renderbuffer);
9626 
9627   // Cache current state and reset it to the values we require.
9628   GLboolean scissor_enabled = false;
9629   api()->glGetBooleanvFn(GL_SCISSOR_TEST, &scissor_enabled);
9630   if (scissor_enabled)
9631     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
9632   ClearDeviceWindowRectangles();
9633 
9634   GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
9635   api()->glGetBooleanvFn(GL_COLOR_WRITEMASK, color_mask);
9636   state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9637 
9638   GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
9639   api()->glGetFloatvFn(GL_COLOR_CLEAR_VALUE, clear_color);
9640   api()->glClearColorFn(1.0f, 0.0f, 1.0f, 1.0f);
9641 
9642   // Clear the buffer to the desired key color.
9643   api()->glClearFn(GL_COLOR_BUFFER_BIT);
9644 
9645   // Blit from the multisample buffer to a standard texture.
9646   api()->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER,
9647                                 validation_fbo_multisample_);
9648   api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, validation_fbo_);
9649 
9650   api()->glBlitFramebufferFn(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT,
9651                              GL_NEAREST);
9652 
9653   // Read a pixel from the buffer.
9654   api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, validation_fbo_);
9655 
9656   unsigned char pixel[3] = {0, 0, 0};
9657   api()->glReadPixelsFn(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
9658 
9659   // Detach the renderbuffer.
9660   api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, validation_fbo_multisample_);
9661   api()->glFramebufferRenderbufferEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9662                                         GL_RENDERBUFFER, 0);
9663 
9664   // Restore cached state.
9665   if (scissor_enabled)
9666     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
9667   RestoreDeviceWindowRectangles();
9668 
9669   state_.SetDeviceColorMask(
9670       color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
9671   api()->glClearColorFn(clear_color[0], clear_color[1], clear_color[2],
9672                         clear_color[3]);
9673   api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
9674   api()->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER, read_framebuffer);
9675 
9676   // Return true if the pixel matched the desired key color.
9677   return (pixel[0] == 0xFF &&
9678       pixel[1] == 0x00 &&
9679       pixel[2] == 0xFF);
9680 }
9681 
DoReleaseShaderCompiler()9682 void GLES2DecoderImpl::DoReleaseShaderCompiler() {
9683   DestroyShaderTranslator();
9684 }
9685 
DoRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)9686 void GLES2DecoderImpl::DoRenderbufferStorage(
9687   GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
9688   Renderbuffer* renderbuffer =
9689       GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
9690   if (!renderbuffer) {
9691     LOCAL_SET_GL_ERROR(
9692         GL_INVALID_OPERATION,
9693         "glRenderbufferStorage", "no renderbuffer bound");
9694     return;
9695   }
9696 
9697   if (width > renderbuffer_manager()->max_renderbuffer_size() ||
9698       height > renderbuffer_manager()->max_renderbuffer_size()) {
9699     LOCAL_SET_GL_ERROR(
9700         GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
9701     return;
9702   }
9703 
9704   uint32_t estimated_size = 0;
9705   if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
9706            width, height, 1, internalformat, &estimated_size)) {
9707     LOCAL_SET_GL_ERROR(
9708         GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
9709     return;
9710   }
9711 
9712   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
9713   RenderbufferStorageMultisampleWithWorkaround(
9714       target, 0,
9715       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
9716           internalformat),
9717       width, height, kDoNotForce);
9718   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
9719   if (error == GL_NO_ERROR) {
9720     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, 0,
9721                                                  internalformat, width, height);
9722   }
9723 }
9724 
DoLineWidth(GLfloat width)9725 void GLES2DecoderImpl::DoLineWidth(GLfloat width) {
9726   api()->glLineWidthFn(
9727       base::ClampToRange(width, line_width_range_[0], line_width_range_[1]));
9728 }
9729 
DoLinkProgram(GLuint program_id)9730 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
9731   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
9732   SCOPED_UMA_HISTOGRAM_TIMER("GPU.DoLinkProgramTime");
9733   Program* program = GetProgramInfoNotShader(
9734       program_id, "glLinkProgram");
9735   if (!program) {
9736     return;
9737   }
9738 
9739   LogClientServiceForInfo(program, program_id, "glLinkProgram");
9740   if (program->Link(shader_manager(),
9741                     workarounds().count_all_in_varyings_packing
9742                         ? Program::kCountAll
9743                         : Program::kCountOnlyStaticallyUsed,
9744                     client())) {
9745     if (program == state_.current_program.get()) {
9746       if (workarounds().clear_uniforms_before_first_program_use)
9747         program_manager()->ClearUniforms(program);
9748     }
9749     if (features().webgl_multi_draw)
9750       program_manager()->UpdateDrawIDUniformLocation(program);
9751     if (features().webgl_draw_instanced_base_vertex_base_instance ||
9752         features().webgl_multi_draw_instanced_base_vertex_base_instance) {
9753       program_manager()->UpdateBaseVertexUniformLocation(program);
9754       program_manager()->UpdateBaseInstanceUniformLocation(program);
9755     }
9756   }
9757 
9758   // LinkProgram can be very slow.  Exit command processing to allow for
9759   // context preemption and GPU watchdog checks.
9760   ExitCommandProcessingEarly();
9761 }
9762 
DoOverlayPromotionHintCHROMIUM(GLuint client_id,GLboolean promotion_hint,GLint display_x,GLint display_y,GLint display_width,GLint display_height)9763 void GLES2DecoderImpl::DoOverlayPromotionHintCHROMIUM(GLuint client_id,
9764                                                       GLboolean promotion_hint,
9765                                                       GLint display_x,
9766                                                       GLint display_y,
9767                                                       GLint display_width,
9768                                                       GLint display_height) {
9769   if (client_id == 0)
9770     return;
9771 
9772   TextureRef* texture_ref = GetTexture(client_id);
9773   if (!texture_ref) {
9774     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glOverlayPromotionHintCHROMIUM",
9775                        "invalid texture id");
9776     return;
9777   }
9778   GLStreamTextureImage* image =
9779       texture_ref->texture()->GetLevelStreamTextureImage(
9780           GL_TEXTURE_EXTERNAL_OES, 0);
9781   if (!image) {
9782     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glOverlayPromotionHintCHROMIUM",
9783                        "texture has no StreamTextureImage");
9784     return;
9785   }
9786 
9787   image->NotifyPromotionHint(promotion_hint != GL_FALSE, display_x, display_y,
9788                              display_width, display_height);
9789 }
9790 
DoSetDrawRectangleCHROMIUM(GLint x,GLint y,GLint width,GLint height)9791 void GLES2DecoderImpl::DoSetDrawRectangleCHROMIUM(GLint x,
9792                                                   GLint y,
9793                                                   GLint width,
9794                                                   GLint height) {
9795   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
9796   if (framebuffer) {
9797     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
9798                        "framebuffer must not be bound");
9799     return;
9800   }
9801   if (!supports_dc_layers_) {
9802     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
9803                        "surface doesn't support SetDrawRectangle");
9804     return;
9805   }
9806   gfx::Rect rect(x, y, width, height);
9807   if (!surface_->SetDrawRectangle(rect)) {
9808     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
9809                        "failed on surface");
9810     // If SetDrawRectangle failed, we may not have a current context any
9811     // more, make sure to report lost context.
9812     LOG(ERROR) << "Context lost because SetDrawRectangleCHROMIUM failed.";
9813     MarkContextLost(error::kUnknown);
9814     group_->LoseContexts(error::kUnknown);
9815     return;
9816   }
9817   OnFboChanged();
9818 }
9819 
DoSetEnableDCLayersCHROMIUM(GLboolean enable)9820 void GLES2DecoderImpl::DoSetEnableDCLayersCHROMIUM(GLboolean enable) {
9821   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
9822   if (framebuffer) {
9823     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetEnableDCLayersCHROMIUM",
9824                        "framebuffer must not be bound");
9825     return;
9826   }
9827   if (!supports_dc_layers_) {
9828     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetEnableDCLayersCHROMIUM",
9829                        "surface doesn't support SetDrawRectangle");
9830     return;
9831   }
9832   if (!surface_->SetEnableDCLayers(!!enable)) {
9833     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetEnableDCLayersCHROMIUM",
9834                        "failed on surface");
9835     // If SetEnableDCLayers failed, we may not have a current context any
9836     // more, make sure to report lost context.
9837     LOG(ERROR) << "Context lost because SetEnableDCLayers failed.";
9838     MarkContextLost(error::kUnknown);
9839     group_->LoseContexts(error::kUnknown);
9840   }
9841 }
9842 
DoReadBuffer(GLenum src)9843 void GLES2DecoderImpl::DoReadBuffer(GLenum src) {
9844   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
9845   if (framebuffer) {
9846     if (src == GL_BACK) {
9847       LOCAL_SET_GL_ERROR(
9848           GL_INVALID_ENUM, "glReadBuffer",
9849           "invalid src for a named framebuffer");
9850       return;
9851     }
9852     framebuffer->set_read_buffer(src);
9853   } else {
9854     if (src != GL_NONE && src != GL_BACK) {
9855       LOCAL_SET_GL_ERROR(
9856           GL_INVALID_ENUM, "glReadBuffer",
9857           "invalid src for the default framebuffer");
9858       return;
9859     }
9860     back_buffer_read_buffer_ = src;
9861     if (GetBackbufferServiceId() && src == GL_BACK)
9862       src = GL_COLOR_ATTACHMENT0;
9863   }
9864   api()->glReadBufferFn(src);
9865 }
9866 
DoSamplerParameterf(GLuint client_id,GLenum pname,GLfloat param)9867 void GLES2DecoderImpl::DoSamplerParameterf(
9868     GLuint client_id, GLenum pname, GLfloat param) {
9869   Sampler* sampler = GetSampler(client_id);
9870   if (!sampler) {
9871     LOCAL_SET_GL_ERROR(
9872         GL_INVALID_VALUE, "glSamplerParameterf", "unknown sampler");
9873     return;
9874   }
9875   sampler_manager()->SetParameterf("glSamplerParameterf", error_state_.get(),
9876                                    sampler, pname, param);
9877 }
9878 
DoSamplerParameteri(GLuint client_id,GLenum pname,GLint param)9879 void GLES2DecoderImpl::DoSamplerParameteri(
9880     GLuint client_id, GLenum pname, GLint param) {
9881   Sampler* sampler = GetSampler(client_id);
9882   if (!sampler) {
9883     LOCAL_SET_GL_ERROR(
9884         GL_INVALID_VALUE, "glSamplerParameteri", "unknown sampler");
9885     return;
9886   }
9887   sampler_manager()->SetParameteri("glSamplerParameteri", error_state_.get(),
9888                                    sampler, pname, param);
9889 }
9890 
DoSamplerParameterfv(GLuint client_id,GLenum pname,const volatile GLfloat * params)9891 void GLES2DecoderImpl::DoSamplerParameterfv(GLuint client_id,
9892                                             GLenum pname,
9893                                             const volatile GLfloat* params) {
9894   DCHECK(params);
9895   Sampler* sampler = GetSampler(client_id);
9896   if (!sampler) {
9897     LOCAL_SET_GL_ERROR(
9898         GL_INVALID_VALUE, "glSamplerParameterfv", "unknown sampler");
9899     return;
9900   }
9901   sampler_manager()->SetParameterf("glSamplerParameterfv", error_state_.get(),
9902                                    sampler, pname, params[0]);
9903 }
9904 
DoSamplerParameteriv(GLuint client_id,GLenum pname,const volatile GLint * params)9905 void GLES2DecoderImpl::DoSamplerParameteriv(GLuint client_id,
9906                                             GLenum pname,
9907                                             const volatile GLint* params) {
9908   DCHECK(params);
9909   Sampler* sampler = GetSampler(client_id);
9910   if (!sampler) {
9911     LOCAL_SET_GL_ERROR(
9912         GL_INVALID_VALUE, "glSamplerParameteriv", "unknown sampler");
9913     return;
9914   }
9915   sampler_manager()->SetParameteri("glSamplerParameteriv", error_state_.get(),
9916                                    sampler, pname, params[0]);
9917 }
9918 
DoTexParameterf(GLenum target,GLenum pname,GLfloat param)9919 void GLES2DecoderImpl::DoTexParameterf(
9920     GLenum target, GLenum pname, GLfloat param) {
9921   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
9922       &state_, target);
9923   if (!texture) {
9924     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
9925     return;
9926   }
9927 
9928   texture_manager()->SetParameterf("glTexParameterf", error_state_.get(),
9929                                    texture, pname, param);
9930 }
9931 
DoTexParameteri(GLenum target,GLenum pname,GLint param)9932 void GLES2DecoderImpl::DoTexParameteri(
9933     GLenum target, GLenum pname, GLint param) {
9934   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
9935       &state_, target);
9936   if (!texture) {
9937     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
9938     return;
9939   }
9940 
9941   texture_manager()->SetParameteri("glTexParameteri", error_state_.get(),
9942                                    texture, pname, param);
9943 }
9944 
DoTexParameterfv(GLenum target,GLenum pname,const volatile GLfloat * params)9945 void GLES2DecoderImpl::DoTexParameterfv(GLenum target,
9946                                         GLenum pname,
9947                                         const volatile GLfloat* params) {
9948   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
9949       &state_, target);
9950   if (!texture) {
9951     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
9952     return;
9953   }
9954 
9955   texture_manager()->SetParameterf("glTexParameterfv", error_state_.get(),
9956                                    texture, pname, *params);
9957 }
9958 
DoTexParameteriv(GLenum target,GLenum pname,const volatile GLint * params)9959 void GLES2DecoderImpl::DoTexParameteriv(GLenum target,
9960                                         GLenum pname,
9961                                         const volatile GLint* params) {
9962   TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
9963       &state_, target);
9964   if (!texture) {
9965     LOCAL_SET_GL_ERROR(
9966         GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
9967     return;
9968   }
9969 
9970   texture_manager()->SetParameteri("glTexParameteriv", error_state_.get(),
9971                                    texture, pname, *params);
9972 }
9973 
CheckCurrentProgram(const char * function_name)9974 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
9975   if (!state_.current_program.get()) {
9976     // The program does not exist.
9977     LOCAL_SET_GL_ERROR(
9978         GL_INVALID_OPERATION, function_name, "no program in use");
9979     return false;
9980   }
9981   if (!state_.current_program->InUse()) {
9982     LOCAL_SET_GL_ERROR(
9983         GL_INVALID_OPERATION, function_name, "program not linked");
9984     return false;
9985   }
9986   return true;
9987 }
9988 
CheckCurrentProgramForUniform(GLint location,const char * function_name)9989 bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
9990     GLint location, const char* function_name) {
9991   if (!CheckCurrentProgram(function_name)) {
9992     return false;
9993   }
9994   return !state_.current_program->IsInactiveUniformLocationByFakeLocation(
9995       location);
9996 }
9997 
CheckDrawingFeedbackLoopsHelper(const Framebuffer::Attachment * attachment,TextureRef * texture_ref,const char * function_name)9998 bool GLES2DecoderImpl::CheckDrawingFeedbackLoopsHelper(
9999     const Framebuffer::Attachment* attachment,
10000     TextureRef* texture_ref,
10001     const char* function_name) {
10002   if (attachment && attachment->IsTexture(texture_ref)) {
10003     LOCAL_SET_GL_ERROR(
10004         GL_INVALID_OPERATION, function_name,
10005         "Source and destination textures of the draw are the same.");
10006     return true;
10007   }
10008   return false;
10009 }
10010 
SupportsDrawBuffers() const10011 bool GLES2DecoderImpl::SupportsDrawBuffers() const {
10012   return feature_info_->IsWebGL1OrES2Context() ?
10013       feature_info_->feature_flags().ext_draw_buffers : true;
10014 }
10015 
ValidateAndAdjustDrawBuffers(const char * func_name)10016 bool GLES2DecoderImpl::ValidateAndAdjustDrawBuffers(const char* func_name) {
10017   if (state_.GetEnabled(GL_RASTERIZER_DISCARD)) {
10018     return true;
10019   }
10020   if (!SupportsDrawBuffers()) {
10021     return true;
10022   }
10023   Framebuffer* framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
10024   if (!state_.current_program.get() || !framebuffer) {
10025     return true;
10026   }
10027   if (!state_.color_mask_red && !state_.color_mask_green &&
10028       !state_.color_mask_blue && !state_.color_mask_alpha) {
10029     return true;
10030   }
10031   uint32_t fragment_output_type_mask =
10032       state_.current_program->fragment_output_type_mask();
10033   uint32_t fragment_output_written_mask =
10034       state_.current_program->fragment_output_written_mask();
10035   if (!framebuffer->ValidateAndAdjustDrawBuffers(
10036       fragment_output_type_mask, fragment_output_written_mask)) {
10037       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
10038           "buffer format and fragment output variable type incompatible");
10039       return false;
10040   }
10041   return true;
10042 }
10043 
AdjustDrawBuffers()10044 void GLES2DecoderImpl::AdjustDrawBuffers() {
10045   if (!SupportsDrawBuffers()) {
10046     return;
10047   }
10048   Framebuffer* framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
10049   if (framebuffer) {
10050     framebuffer->AdjustDrawBuffers();
10051   }
10052 }
10053 
ValidateUniformBlockBackings(const char * func_name)10054 bool GLES2DecoderImpl::ValidateUniformBlockBackings(const char* func_name) {
10055   DCHECK(feature_info_->IsWebGL2OrES3Context());
10056   if (!state_.current_program.get())
10057     return true;
10058   int32_t max_index = -1;
10059   for (auto info : state_.current_program->uniform_block_size_info()) {
10060     int32_t index = static_cast<int32_t>(info.binding);
10061     if (index > max_index)
10062       max_index = index;
10063   }
10064   if (max_index < 0)
10065     return true;
10066   std::vector<GLsizeiptr> uniform_block_sizes(max_index + 1);
10067   for (int32_t ii = 0; ii <= max_index; ++ii)
10068     uniform_block_sizes[ii] = 0;
10069   for (auto info : state_.current_program->uniform_block_size_info()) {
10070     uint32_t index = info.binding;
10071     uniform_block_sizes[index] = static_cast<GLsizeiptr>(info.data_size);
10072   }
10073   return buffer_manager()->RequestBuffersAccess(
10074       error_state_.get(), state_.indexed_uniform_buffer_bindings.get(),
10075       uniform_block_sizes, 1, func_name, "uniform buffers");
10076 }
10077 
CheckUniformForApiType(const Program::UniformInfo * info,const char * function_name,UniformApiType api_type)10078 bool GLES2DecoderImpl::CheckUniformForApiType(const Program::UniformInfo* info,
10079                                               const char* function_name,
10080                                               UniformApiType api_type) {
10081   DCHECK(info);
10082   if ((api_type & info->accepts_api_type) == UniformApiType::kUniformNone) {
10083     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
10084                        "wrong uniform function for type");
10085     return false;
10086   }
10087   return true;
10088 }
10089 
PrepForSetUniformByLocation(GLint fake_location,const char * function_name,UniformApiType api_type,GLint * real_location,GLenum * type,GLsizei * count)10090 bool GLES2DecoderImpl::PrepForSetUniformByLocation(GLint fake_location,
10091                                                    const char* function_name,
10092                                                    UniformApiType api_type,
10093                                                    GLint* real_location,
10094                                                    GLenum* type,
10095                                                    GLsizei* count) {
10096   DCHECK(type);
10097   DCHECK(count);
10098   DCHECK(real_location);
10099 
10100   if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
10101     return false;
10102   }
10103   GLint array_index = -1;
10104   const Program::UniformInfo* info =
10105       state_.current_program->GetUniformInfoByFakeLocation(
10106           fake_location, real_location, &array_index);
10107   if (!info) {
10108     LOCAL_SET_GL_ERROR(
10109         GL_INVALID_OPERATION, function_name, "unknown location");
10110     return false;
10111   }
10112   if (!CheckUniformForApiType(info, function_name, api_type)) {
10113     return false;
10114   }
10115   if (*count > 1 && !info->is_array) {
10116     LOCAL_SET_GL_ERROR(
10117         GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
10118     return false;
10119   }
10120   *count = std::min(info->size - array_index, *count);
10121   if (*count <= 0) {
10122     return false;
10123   }
10124   *type = info->type;
10125   return true;
10126 }
10127 
DoUniform1i(GLint fake_location,GLint v0)10128 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
10129   GLenum type = 0;
10130   GLsizei count = 1;
10131   GLint real_location = -1;
10132   if (!PrepForSetUniformByLocation(fake_location, "glUniform1i",
10133                                    UniformApiType::kUniform1i, &real_location,
10134                                    &type, &count)) {
10135     return;
10136   }
10137   if (!state_.current_program->SetSamplers(
10138       state_.texture_units.size(), fake_location, 1, &v0)) {
10139     LOCAL_SET_GL_ERROR(
10140         GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
10141     return;
10142   }
10143   api()->glUniform1iFn(real_location, v0);
10144 }
10145 
DoUniform1iv(GLint fake_location,GLsizei count,const volatile GLint * values)10146 void GLES2DecoderImpl::DoUniform1iv(GLint fake_location,
10147                                     GLsizei count,
10148                                     const volatile GLint* values) {
10149   GLenum type = 0;
10150   GLint real_location = -1;
10151   if (!PrepForSetUniformByLocation(fake_location, "glUniform1iv",
10152                                    UniformApiType::kUniform1i, &real_location,
10153                                    &type, &count)) {
10154     return;
10155   }
10156   auto values_copy = std::make_unique<GLint[]>(count);
10157   GLint* safe_values = values_copy.get();
10158   std::copy(values, values + count, safe_values);
10159   if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
10160       type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
10161     if (!state_.current_program->SetSamplers(
10162             state_.texture_units.size(), fake_location, count, safe_values)) {
10163       LOCAL_SET_GL_ERROR(
10164           GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
10165       return;
10166     }
10167   }
10168   api()->glUniform1ivFn(real_location, count, safe_values);
10169 }
10170 
DoUniform1uiv(GLint fake_location,GLsizei count,const volatile GLuint * value)10171 void GLES2DecoderImpl::DoUniform1uiv(GLint fake_location,
10172                                      GLsizei count,
10173                                      const volatile GLuint* value) {
10174   GLenum type = 0;
10175   GLint real_location = -1;
10176   if (!PrepForSetUniformByLocation(fake_location, "glUniform1uiv",
10177                                    UniformApiType::kUniform1ui, &real_location,
10178                                    &type, &count)) {
10179     return;
10180   }
10181   api()->glUniform1uivFn(real_location, count,
10182                          const_cast<const GLuint*>(value));
10183 }
10184 
DoUniform1fv(GLint fake_location,GLsizei count,const volatile GLfloat * value)10185 void GLES2DecoderImpl::DoUniform1fv(GLint fake_location,
10186                                     GLsizei count,
10187                                     const volatile GLfloat* value) {
10188   GLenum type = 0;
10189   GLint real_location = -1;
10190   if (!PrepForSetUniformByLocation(fake_location, "glUniform1fv",
10191                                    UniformApiType::kUniform1f, &real_location,
10192                                    &type, &count)) {
10193     return;
10194   }
10195   if (type == GL_BOOL) {
10196     std::unique_ptr<GLint[]> temp(new GLint[count]);
10197     for (GLsizei ii = 0; ii < count; ++ii) {
10198       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
10199     }
10200     api()->glUniform1ivFn(real_location, count, temp.get());
10201   } else {
10202     api()->glUniform1fvFn(real_location, count,
10203                           const_cast<const GLfloat*>(value));
10204   }
10205 }
10206 
DoUniform2fv(GLint fake_location,GLsizei count,const volatile GLfloat * value)10207 void GLES2DecoderImpl::DoUniform2fv(GLint fake_location,
10208                                     GLsizei count,
10209                                     const volatile GLfloat* value) {
10210   GLenum type = 0;
10211   GLint real_location = -1;
10212   if (!PrepForSetUniformByLocation(fake_location, "glUniform2fv",
10213                                    UniformApiType::kUniform2f, &real_location,
10214                                    &type, &count)) {
10215     return;
10216   }
10217   if (type == GL_BOOL_VEC2) {
10218     GLsizei num_values = count * 2;
10219     std::unique_ptr<GLint[]> temp(new GLint[num_values]);
10220     for (GLsizei ii = 0; ii < num_values; ++ii) {
10221       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
10222     }
10223     api()->glUniform2ivFn(real_location, count, temp.get());
10224   } else {
10225     api()->glUniform2fvFn(real_location, count,
10226                           const_cast<const GLfloat*>(value));
10227   }
10228 }
10229 
DoUniform3fv(GLint fake_location,GLsizei count,const volatile GLfloat * value)10230 void GLES2DecoderImpl::DoUniform3fv(GLint fake_location,
10231                                     GLsizei count,
10232                                     const volatile GLfloat* value) {
10233   GLenum type = 0;
10234   GLint real_location = -1;
10235   if (!PrepForSetUniformByLocation(fake_location, "glUniform3fv",
10236                                    UniformApiType::kUniform3f, &real_location,
10237                                    &type, &count)) {
10238     return;
10239   }
10240   if (type == GL_BOOL_VEC3) {
10241     GLsizei num_values = count * 3;
10242     std::unique_ptr<GLint[]> temp(new GLint[num_values]);
10243     for (GLsizei ii = 0; ii < num_values; ++ii) {
10244       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
10245     }
10246     api()->glUniform3ivFn(real_location, count, temp.get());
10247   } else {
10248     api()->glUniform3fvFn(real_location, count,
10249                           const_cast<const GLfloat*>(value));
10250   }
10251 }
10252 
DoUniform4fv(GLint fake_location,GLsizei count,const volatile GLfloat * value)10253 void GLES2DecoderImpl::DoUniform4fv(GLint fake_location,
10254                                     GLsizei count,
10255                                     const volatile GLfloat* value) {
10256   GLenum type = 0;
10257   GLint real_location = -1;
10258   if (!PrepForSetUniformByLocation(fake_location, "glUniform4fv",
10259                                    UniformApiType::kUniform4f, &real_location,
10260                                    &type, &count)) {
10261     return;
10262   }
10263   if (type == GL_BOOL_VEC4) {
10264     GLsizei num_values = count * 4;
10265     std::unique_ptr<GLint[]> temp(new GLint[num_values]);
10266     for (GLsizei ii = 0; ii < num_values; ++ii) {
10267       temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
10268     }
10269     api()->glUniform4ivFn(real_location, count, temp.get());
10270   } else {
10271     api()->glUniform4fvFn(real_location, count,
10272                           const_cast<const GLfloat*>(value));
10273   }
10274 }
10275 
DoUniform2iv(GLint fake_location,GLsizei count,const volatile GLint * value)10276 void GLES2DecoderImpl::DoUniform2iv(GLint fake_location,
10277                                     GLsizei count,
10278                                     const volatile GLint* value) {
10279   GLenum type = 0;
10280   GLint real_location = -1;
10281   if (!PrepForSetUniformByLocation(fake_location, "glUniform2iv",
10282                                    UniformApiType::kUniform2i, &real_location,
10283                                    &type, &count)) {
10284     return;
10285   }
10286   api()->glUniform2ivFn(real_location, count, const_cast<const GLint*>(value));
10287 }
10288 
DoUniform2uiv(GLint fake_location,GLsizei count,const volatile GLuint * value)10289 void GLES2DecoderImpl::DoUniform2uiv(GLint fake_location,
10290                                      GLsizei count,
10291                                      const volatile GLuint* value) {
10292   GLenum type = 0;
10293   GLint real_location = -1;
10294   if (!PrepForSetUniformByLocation(fake_location, "glUniform2uiv",
10295                                    UniformApiType::kUniform2ui, &real_location,
10296                                    &type, &count)) {
10297     return;
10298   }
10299   api()->glUniform2uivFn(real_location, count,
10300                          const_cast<const GLuint*>(value));
10301 }
10302 
DoUniform3iv(GLint fake_location,GLsizei count,const volatile GLint * value)10303 void GLES2DecoderImpl::DoUniform3iv(GLint fake_location,
10304                                     GLsizei count,
10305                                     const volatile GLint* value) {
10306   GLenum type = 0;
10307   GLint real_location = -1;
10308   if (!PrepForSetUniformByLocation(fake_location, "glUniform3iv",
10309                                    UniformApiType::kUniform3i, &real_location,
10310                                    &type, &count)) {
10311     return;
10312   }
10313   api()->glUniform3ivFn(real_location, count, const_cast<const GLint*>(value));
10314 }
10315 
DoUniform3uiv(GLint fake_location,GLsizei count,const volatile GLuint * value)10316 void GLES2DecoderImpl::DoUniform3uiv(GLint fake_location,
10317                                      GLsizei count,
10318                                      const volatile GLuint* value) {
10319   GLenum type = 0;
10320   GLint real_location = -1;
10321   if (!PrepForSetUniformByLocation(fake_location, "glUniform3uiv",
10322                                    UniformApiType::kUniform3ui, &real_location,
10323                                    &type, &count)) {
10324     return;
10325   }
10326   api()->glUniform3uivFn(real_location, count,
10327                          const_cast<const GLuint*>(value));
10328 }
10329 
DoUniform4iv(GLint fake_location,GLsizei count,const volatile GLint * value)10330 void GLES2DecoderImpl::DoUniform4iv(GLint fake_location,
10331                                     GLsizei count,
10332                                     const volatile GLint* value) {
10333   GLenum type = 0;
10334   GLint real_location = -1;
10335   if (!PrepForSetUniformByLocation(fake_location, "glUniform4iv",
10336                                    UniformApiType::kUniform4i, &real_location,
10337                                    &type, &count)) {
10338     return;
10339   }
10340   api()->glUniform4ivFn(real_location, count, const_cast<const GLint*>(value));
10341 }
10342 
DoUniform4uiv(GLint fake_location,GLsizei count,const volatile GLuint * value)10343 void GLES2DecoderImpl::DoUniform4uiv(GLint fake_location,
10344                                      GLsizei count,
10345                                      const volatile GLuint* value) {
10346   GLenum type = 0;
10347   GLint real_location = -1;
10348   if (!PrepForSetUniformByLocation(fake_location, "glUniform4uiv",
10349                                    UniformApiType::kUniform4ui, &real_location,
10350                                    &type, &count)) {
10351     return;
10352   }
10353   api()->glUniform4uivFn(real_location, count,
10354                          const_cast<const GLuint*>(value));
10355 }
10356 
DoUniformMatrix2fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10357 void GLES2DecoderImpl::DoUniformMatrix2fv(GLint fake_location,
10358                                           GLsizei count,
10359                                           GLboolean transpose,
10360                                           const volatile GLfloat* value) {
10361   GLenum type = 0;
10362   GLint real_location = -1;
10363   if (transpose && !feature_info_->IsWebGL2OrES3Context()) {
10364     LOCAL_SET_GL_ERROR(
10365         GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose not FALSE");
10366     return;
10367   }
10368   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2fv",
10369                                    UniformApiType::kUniformMatrix2f,
10370                                    &real_location, &type, &count)) {
10371     return;
10372   }
10373   api()->glUniformMatrix2fvFn(real_location, count, transpose,
10374                               const_cast<const GLfloat*>(value));
10375 }
10376 
DoUniformMatrix3fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10377 void GLES2DecoderImpl::DoUniformMatrix3fv(GLint fake_location,
10378                                           GLsizei count,
10379                                           GLboolean transpose,
10380                                           const volatile GLfloat* value) {
10381   GLenum type = 0;
10382   GLint real_location = -1;
10383   if (transpose && !feature_info_->IsWebGL2OrES3Context()) {
10384     LOCAL_SET_GL_ERROR(
10385         GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose not FALSE");
10386     return;
10387   }
10388   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3fv",
10389                                    UniformApiType::kUniformMatrix3f,
10390                                    &real_location, &type, &count)) {
10391     return;
10392   }
10393   api()->glUniformMatrix3fvFn(real_location, count, transpose,
10394                               const_cast<const GLfloat*>(value));
10395 }
10396 
DoUniformMatrix4fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10397 void GLES2DecoderImpl::DoUniformMatrix4fv(GLint fake_location,
10398                                           GLsizei count,
10399                                           GLboolean transpose,
10400                                           const volatile GLfloat* value) {
10401   GLenum type = 0;
10402   GLint real_location = -1;
10403   if (transpose && !feature_info_->IsWebGL2OrES3Context()) {
10404     LOCAL_SET_GL_ERROR(
10405         GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose not FALSE");
10406     return;
10407   }
10408   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4fv",
10409                                    UniformApiType::kUniformMatrix4f,
10410                                    &real_location, &type, &count)) {
10411     return;
10412   }
10413   api()->glUniformMatrix4fvFn(real_location, count, transpose,
10414                               const_cast<const GLfloat*>(value));
10415 }
10416 
DoUniformMatrix4fvStreamTextureMatrixCHROMIUM(GLint fake_location,GLboolean transpose,const volatile GLfloat * transform)10417 void GLES2DecoderImpl::DoUniformMatrix4fvStreamTextureMatrixCHROMIUM(
10418     GLint fake_location,
10419     GLboolean transpose,
10420     const volatile GLfloat* transform) {
10421   float gl_matrix[16];
10422 
10423   // This refers to the bound external texture on the active unit.
10424   TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10425   if (TextureRef* texture_ref = unit.bound_texture_external_oes.get()) {
10426     if (GLStreamTextureImage* image =
10427             texture_ref->texture()->GetLevelStreamTextureImage(
10428                 GL_TEXTURE_EXTERNAL_OES, 0)) {
10429       gfx::Transform st_transform(gfx::Transform::kSkipInitialization);
10430       gfx::Transform pre_transform(gfx::Transform::kSkipInitialization);
10431       image->GetTextureMatrix(gl_matrix);
10432       st_transform.matrix().setColMajorf(gl_matrix);
10433       // const_cast is safe, because setColMajorf only does a memcpy.
10434       // TODO(piman): can we remove this assumption without having to introduce
10435       // an extra copy?
10436       pre_transform.matrix().setColMajorf(
10437           const_cast<const GLfloat*>(transform));
10438       gfx::Transform(pre_transform, st_transform)
10439           .matrix()
10440           .asColMajorf(gl_matrix);
10441     } else {
10442       // Missing stream texture. Treat matrix as identity.
10443       memcpy(gl_matrix, const_cast<const GLfloat*>(transform),
10444              sizeof(gl_matrix));
10445     }
10446   } else {
10447     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10448                        "DoUniformMatrix4vStreamTextureMatrix",
10449                        "no texture bound");
10450     return;
10451   }
10452 
10453   GLenum type = 0;
10454   GLint real_location = -1;
10455   GLsizei count = 1;
10456   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4fv",
10457                                    UniformApiType::kUniformMatrix4f,
10458                                    &real_location, &type, &count)) {
10459     return;
10460   }
10461 
10462   api()->glUniformMatrix4fvFn(real_location, count, transpose, gl_matrix);
10463 }
10464 
DoUniformMatrix2x3fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10465 void GLES2DecoderImpl::DoUniformMatrix2x3fv(GLint fake_location,
10466                                             GLsizei count,
10467                                             GLboolean transpose,
10468                                             const volatile GLfloat* value) {
10469   GLenum type = 0;
10470   GLint real_location = -1;
10471   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2x3fv",
10472                                    UniformApiType::kUniformMatrix2x3f,
10473                                    &real_location, &type, &count)) {
10474     return;
10475   }
10476   api()->glUniformMatrix2x3fvFn(real_location, count, transpose,
10477                                 const_cast<const GLfloat*>(value));
10478 }
10479 
DoUniformMatrix2x4fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10480 void GLES2DecoderImpl::DoUniformMatrix2x4fv(GLint fake_location,
10481                                             GLsizei count,
10482                                             GLboolean transpose,
10483                                             const volatile GLfloat* value) {
10484   GLenum type = 0;
10485   GLint real_location = -1;
10486   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix2x4fv",
10487                                    UniformApiType::kUniformMatrix2x4f,
10488                                    &real_location, &type, &count)) {
10489     return;
10490   }
10491   api()->glUniformMatrix2x4fvFn(real_location, count, transpose,
10492                                 const_cast<const GLfloat*>(value));
10493 }
10494 
DoUniformMatrix3x2fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10495 void GLES2DecoderImpl::DoUniformMatrix3x2fv(GLint fake_location,
10496                                             GLsizei count,
10497                                             GLboolean transpose,
10498                                             const volatile GLfloat* value) {
10499   GLenum type = 0;
10500   GLint real_location = -1;
10501   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3x2fv",
10502                                    UniformApiType::kUniformMatrix3x2f,
10503                                    &real_location, &type, &count)) {
10504     return;
10505   }
10506   api()->glUniformMatrix3x2fvFn(real_location, count, transpose,
10507                                 const_cast<const GLfloat*>(value));
10508 }
10509 
DoUniformMatrix3x4fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10510 void GLES2DecoderImpl::DoUniformMatrix3x4fv(GLint fake_location,
10511                                             GLsizei count,
10512                                             GLboolean transpose,
10513                                             const volatile GLfloat* value) {
10514   GLenum type = 0;
10515   GLint real_location = -1;
10516   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix3x4fv",
10517                                    UniformApiType::kUniformMatrix3x4f,
10518                                    &real_location, &type, &count)) {
10519     return;
10520   }
10521   api()->glUniformMatrix3x4fvFn(real_location, count, transpose,
10522                                 const_cast<const GLfloat*>(value));
10523 }
10524 
DoUniformMatrix4x2fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10525 void GLES2DecoderImpl::DoUniformMatrix4x2fv(GLint fake_location,
10526                                             GLsizei count,
10527                                             GLboolean transpose,
10528                                             const volatile GLfloat* value) {
10529   GLenum type = 0;
10530   GLint real_location = -1;
10531   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4x2fv",
10532                                    UniformApiType::kUniformMatrix4x2f,
10533                                    &real_location, &type, &count)) {
10534     return;
10535   }
10536   api()->glUniformMatrix4x2fvFn(real_location, count, transpose,
10537                                 const_cast<const GLfloat*>(value));
10538 }
10539 
DoUniformMatrix4x3fv(GLint fake_location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)10540 void GLES2DecoderImpl::DoUniformMatrix4x3fv(GLint fake_location,
10541                                             GLsizei count,
10542                                             GLboolean transpose,
10543                                             const volatile GLfloat* value) {
10544   GLenum type = 0;
10545   GLint real_location = -1;
10546   if (!PrepForSetUniformByLocation(fake_location, "glUniformMatrix4x3fv",
10547                                    UniformApiType::kUniformMatrix4x3f,
10548                                    &real_location, &type, &count)) {
10549     return;
10550   }
10551   api()->glUniformMatrix4x3fvFn(real_location, count, transpose,
10552                                 const_cast<const GLfloat*>(value));
10553 }
10554 
DoUseProgram(GLuint program_id)10555 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
10556   const char* function_name = "glUseProgram";
10557   GLuint service_id = 0;
10558   Program* program = nullptr;
10559   if (program_id) {
10560     program = GetProgramInfoNotShader(program_id, function_name);
10561     if (!program) {
10562       return;
10563     }
10564     if (!program->IsValid()) {
10565       // Program was not linked successfully. (ie, glLinkProgram)
10566       LOCAL_SET_GL_ERROR(
10567           GL_INVALID_OPERATION, function_name, "program not linked");
10568       return;
10569     }
10570     service_id = program->service_id();
10571   }
10572   if (state_.bound_transform_feedback.get() &&
10573       state_.bound_transform_feedback->active() &&
10574       !state_.bound_transform_feedback->paused()) {
10575     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
10576         "transformfeedback is active and not paused");
10577     return;
10578   }
10579   if (program == state_.current_program.get())
10580     return;
10581   if (state_.current_program.get()) {
10582     program_manager()->UnuseProgram(shader_manager(),
10583                                     state_.current_program.get());
10584   }
10585   state_.current_program = program;
10586   LogClientServiceMapping(function_name, program_id, service_id);
10587   api()->glUseProgramFn(service_id);
10588   if (state_.current_program.get()) {
10589     program_manager()->UseProgram(state_.current_program.get());
10590     if (workarounds().clear_uniforms_before_first_program_use)
10591       program_manager()->ClearUniforms(program);
10592   }
10593 }
10594 
RenderWarning(const char * filename,int line,const std::string & msg)10595 void GLES2DecoderImpl::RenderWarning(
10596     const char* filename, int line, const std::string& msg) {
10597   logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
10598 }
10599 
PerformanceWarning(const char * filename,int line,const std::string & msg)10600 void GLES2DecoderImpl::PerformanceWarning(
10601     const char* filename, int line, const std::string& msg) {
10602   logger_.LogMessage(filename, line,
10603                      std::string("PERFORMANCE WARNING: ") + msg);
10604 }
10605 
DoCopyTexImage(Texture * texture,GLenum textarget,gl::GLImage * image)10606 void GLES2DecoderImpl::DoCopyTexImage(Texture* texture,
10607                                       GLenum textarget,
10608                                       gl::GLImage* image) {
10609   // Note: We update the state to COPIED prior to calling CopyTexImage()
10610   // as that allows the GLImage implemenatation to set it back to UNBOUND
10611   // and ensure that CopyTexImage() is called each time the texture is
10612   // used.
10613   texture->SetLevelImageState(textarget, 0, Texture::COPIED);
10614   bool rv = image->CopyTexImage(textarget);
10615   DCHECK(rv) << "CopyTexImage() failed";
10616 }
10617 
DoBindOrCopyTexImageIfNeeded(Texture * texture,GLenum textarget,GLuint texture_unit)10618 bool GLES2DecoderImpl::DoBindOrCopyTexImageIfNeeded(Texture* texture,
10619                                                     GLenum textarget,
10620                                                     GLuint texture_unit) {
10621   // Image is already in use if texture is attached to a framebuffer.
10622   if (texture && !texture->IsAttachedToFramebuffer()) {
10623     Texture::ImageState image_state;
10624     gl::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
10625     if (image && image_state == Texture::UNBOUND) {
10626       ScopedGLErrorSuppressor suppressor(
10627           "GLES2DecoderImpl::DoBindOrCopyTexImageIfNeeded", error_state_.get());
10628       if (texture_unit)
10629         api()->glActiveTextureFn(texture_unit);
10630       api()->glBindTextureFn(textarget, texture->service_id());
10631       if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
10632         bool rv = image->BindTexImage(textarget);
10633         DCHECK(rv) << "BindTexImage() failed";
10634         image_state = Texture::BOUND;
10635       } else {
10636         DoCopyTexImage(texture, textarget, image);
10637       }
10638       if (!texture_unit) {
10639         RestoreCurrentTextureBindings(&state_, textarget,
10640                                       state_.active_texture_unit);
10641         return false;
10642       }
10643       return true;
10644     }
10645   }
10646   return false;
10647 }
10648 
DoCopyBufferSubData(GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)10649 void GLES2DecoderImpl::DoCopyBufferSubData(GLenum readtarget,
10650                                            GLenum writetarget,
10651                                            GLintptr readoffset,
10652                                            GLintptr writeoffset,
10653                                            GLsizeiptr size) {
10654   // Just delegate it. Some validation is actually done before this.
10655   buffer_manager()->ValidateAndDoCopyBufferSubData(
10656       &state_, error_state_.get(), readtarget, writetarget, readoffset,
10657       writeoffset, size);
10658 }
10659 
PrepareTexturesForRender(bool * textures_set,const char * function_name)10660 bool GLES2DecoderImpl::PrepareTexturesForRender(bool* textures_set,
10661                                                 const char* function_name) {
10662   DCHECK(state_.current_program.get());
10663   *textures_set = false;
10664   const Program::SamplerIndices& sampler_indices =
10665      state_.current_program->sampler_indices();
10666   for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
10667     const Program::UniformInfo* uniform_info =
10668         state_.current_program->GetUniformInfo(sampler_indices[ii]);
10669     DCHECK(uniform_info);
10670     for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
10671       GLuint texture_unit_index = uniform_info->texture_units[jj];
10672       if (texture_unit_index < state_.texture_units.size()) {
10673         TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
10674         TextureRef* texture_ref =
10675             texture_unit.GetInfoForSamplerType(uniform_info->type);
10676 
10677         // Find if the texture is also a depth or stencil attachment
10678         // Regardless of whether depth/stencil writes and masks are enabled
10679         // If so, there's a drawing feedback loop.
10680 
10681         Framebuffer* framebuffer =
10682             GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
10683         if (framebuffer) {
10684           if (CheckDrawingFeedbackLoopsHelper(
10685                   framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT), texture_ref,
10686                   function_name)) {
10687             return false;
10688           }
10689 
10690           if (CheckDrawingFeedbackLoopsHelper(
10691                   framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT),
10692                   texture_ref, function_name)) {
10693             return false;
10694           }
10695         }
10696 
10697         GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
10698         const SamplerState& sampler_state = GetSamplerStateForTextureUnit(
10699             uniform_info->type, texture_unit_index);
10700         if (!texture_ref ||
10701             !texture_manager()->CanRenderWithSampler(
10702                 texture_ref, sampler_state)) {
10703           *textures_set = true;
10704           api()->glActiveTextureFn(GL_TEXTURE0 + texture_unit_index);
10705           api()->glBindTextureFn(textarget, texture_manager()->black_texture_id(
10706                                                 uniform_info->type));
10707           if (!texture_ref) {
10708             LOCAL_RENDER_WARNING(
10709                 std::string("there is no texture bound to the unit ") +
10710                 base::NumberToString(texture_unit_index));
10711           } else {
10712             LOCAL_RENDER_WARNING(
10713                 std::string("texture bound to texture unit ") +
10714                 base::NumberToString(texture_unit_index) +
10715                 " is not renderable. It might be non-power-of-2 or have"
10716                 " incompatible texture filtering (maybe)?");
10717           }
10718           continue;
10719         } else if (!texture_ref->texture()->CompatibleWithSamplerUniformType(
10720                        uniform_info->type, sampler_state)) {
10721           LOCAL_SET_GL_ERROR(
10722               GL_INVALID_OPERATION, function_name,
10723               (std::string("Texture bound to texture unit ") +
10724                base::NumberToString(texture_unit_index) +
10725                " with internal format " +
10726                GLES2Util::GetStringEnum(
10727                    texture_ref->texture()->GetInternalFormatOfBaseLevel()) +
10728                " is not compatible with sampler type " +
10729                GLES2Util::GetStringEnum(uniform_info->type))
10730                   .c_str());
10731           return false;
10732         }
10733 
10734         // Find if the texture is also a color attachment
10735         // If so, there's a drawing feedback loop.
10736 
10737         if (framebuffer) {
10738           for (GLsizei kk = 0; kk <= framebuffer->last_color_attachment_id();
10739                ++kk) {
10740             GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + kk);
10741             if (CheckDrawingFeedbackLoopsHelper(
10742                     framebuffer->GetAttachment(attachment), texture_ref,
10743                     function_name)) {
10744               return false;
10745             }
10746           }
10747         }
10748 
10749         if (textarget != GL_TEXTURE_CUBE_MAP) {
10750           Texture* texture = texture_ref->texture();
10751           if (DoBindOrCopyTexImageIfNeeded(texture, textarget,
10752                                            GL_TEXTURE0 + texture_unit_index)) {
10753             *textures_set = true;
10754             continue;
10755           }
10756         }
10757       }
10758       // else: should this be an error?
10759     }
10760   }
10761   return true;
10762 }
10763 
RestoreStateForTextures()10764 void GLES2DecoderImpl::RestoreStateForTextures() {
10765   DCHECK(state_.current_program.get());
10766   const Program::SamplerIndices& sampler_indices =
10767       state_.current_program->sampler_indices();
10768   for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
10769     const Program::UniformInfo* uniform_info =
10770         state_.current_program->GetUniformInfo(sampler_indices[ii]);
10771     DCHECK(uniform_info);
10772     for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
10773       GLuint texture_unit_index = uniform_info->texture_units[jj];
10774       if (texture_unit_index < state_.texture_units.size()) {
10775         TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
10776         TextureRef* texture_ref =
10777             texture_unit.GetInfoForSamplerType(uniform_info->type);
10778         const SamplerState& sampler_state = GetSamplerStateForTextureUnit(
10779             uniform_info->type, texture_unit_index);
10780         if (!texture_ref ||
10781             !texture_manager()->CanRenderWithSampler(
10782                 texture_ref, sampler_state)) {
10783           api()->glActiveTextureFn(GL_TEXTURE0 + texture_unit_index);
10784           // Get the texture_ref info that was previously bound here.
10785           texture_ref =
10786               texture_unit.GetInfoForTarget(texture_unit.bind_target);
10787           api()->glBindTextureFn(texture_unit.bind_target,
10788                                  texture_ref ? texture_ref->service_id() : 0);
10789           continue;
10790         }
10791       }
10792     }
10793   }
10794   // Set the active texture back to whatever the user had it as.
10795   api()->glActiveTextureFn(GL_TEXTURE0 + state_.active_texture_unit);
10796 }
10797 
ClearUnclearedTextures()10798 bool GLES2DecoderImpl::ClearUnclearedTextures() {
10799   // Only check if there are some uncleared textures.
10800   if (!texture_manager()->HaveUnsafeTextures()) {
10801     return true;
10802   }
10803 
10804   // 1: Check all textures we are about to render with.
10805   if (state_.current_program.get()) {
10806     const Program::SamplerIndices& sampler_indices =
10807         state_.current_program->sampler_indices();
10808     for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
10809       const Program::UniformInfo* uniform_info =
10810           state_.current_program->GetUniformInfo(sampler_indices[ii]);
10811       DCHECK(uniform_info);
10812       for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
10813         GLuint texture_unit_index = uniform_info->texture_units[jj];
10814         if (texture_unit_index < state_.texture_units.size()) {
10815           TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
10816           TextureRef* texture_ref =
10817               texture_unit.GetInfoForSamplerType(uniform_info->type);
10818           if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
10819             if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
10820               return false;
10821             }
10822           }
10823         }
10824       }
10825     }
10826   }
10827   return true;
10828 }
10829 
ValidateStencilStateForDraw(const char * function_name)10830 bool GLES2DecoderImpl::ValidateStencilStateForDraw(const char* function_name) {
10831   if (!state_.stencil_state_changed_since_validation) {
10832     return true;
10833   }
10834 
10835   GLenum stencil_format = GetBoundFramebufferStencilFormat(GL_DRAW_FRAMEBUFFER);
10836   uint8_t stencil_bits = GLES2Util::StencilBitsPerPixel(stencil_format);
10837 
10838   if (state_.enable_flags.stencil_test && stencil_bits > 0) {
10839     DCHECK_LE(stencil_bits, 8U);
10840 
10841     GLuint max_stencil_value = (1 << stencil_bits) - 1;
10842     GLint max_stencil_ref = static_cast<GLint>(max_stencil_value);
10843     bool different_refs =
10844         base::ClampToRange(state_.stencil_front_ref, 0, max_stencil_ref) !=
10845         base::ClampToRange(state_.stencil_back_ref, 0, max_stencil_ref);
10846     bool different_writemasks =
10847         (state_.stencil_front_writemask & max_stencil_value) !=
10848         (state_.stencil_back_writemask & max_stencil_value);
10849     bool different_value_masks =
10850         (state_.stencil_front_mask & max_stencil_value) !=
10851         (state_.stencil_back_mask & max_stencil_value);
10852     if (different_refs || different_writemasks || different_value_masks) {
10853       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
10854                          "Front/back stencil settings do not match.");
10855       return false;
10856     }
10857   }
10858 
10859   state_.stencil_state_changed_since_validation = false;
10860   return true;
10861 }
10862 
IsDrawValid(const char * function_name,GLuint max_vertex_accessed,bool instanced,GLsizei primcount,GLint basevertex,GLuint baseinstance)10863 bool GLES2DecoderImpl::IsDrawValid(const char* function_name,
10864                                    GLuint max_vertex_accessed,
10865                                    bool instanced,
10866                                    GLsizei primcount,
10867                                    GLint basevertex,
10868                                    GLuint baseinstance) {
10869   DCHECK(instanced || primcount == 1);
10870 
10871   // NOTE: We specifically do not check current_program->IsValid() because
10872   // it could never be invalid since glUseProgram would have failed. While
10873   // glLinkProgram could later mark the program as invalid the previous
10874   // valid program will still function if it is still the current program.
10875   if (!state_.current_program.get()) {
10876     // The program does not exist.
10877     // But GL says no ERROR.
10878     LOCAL_RENDER_WARNING("Drawing with no current shader program.");
10879     return false;
10880   }
10881 
10882   // Perform extra stencil validation on ANGLE/D3D, and for all WebGL contexts.
10883   if (!feature_info_->feature_flags().separate_stencil_ref_mask_writemask) {
10884     if (!ValidateStencilStateForDraw(function_name)) {
10885       return false;
10886     }
10887   }
10888 
10889   if (!state_.vertex_attrib_manager->ValidateBindings(
10890           function_name, this, feature_info_.get(), buffer_manager(),
10891           state_.current_program.get(), max_vertex_accessed, instanced,
10892           primcount, basevertex, baseinstance)) {
10893     return false;
10894   }
10895 
10896   if (workarounds().disallow_large_instanced_draw) {
10897     const GLsizei kMaxInstancedDrawPrimitiveCount = 0x4000000;
10898     if (primcount > kMaxInstancedDrawPrimitiveCount) {
10899       LOCAL_SET_GL_ERROR(
10900           GL_OUT_OF_MEMORY, function_name,
10901           "Instanced draw primcount too large for this platform");
10902       return false;
10903     }
10904   }
10905 
10906   return true;
10907 }
10908 
SimulateAttrib0(const char * function_name,GLuint max_vertex_accessed,bool * simulated)10909 bool GLES2DecoderImpl::SimulateAttrib0(
10910     const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
10911   DCHECK(simulated);
10912   *simulated = false;
10913 
10914   if (gl_version_info().BehavesLikeGLES())
10915     return true;
10916 
10917   const VertexAttrib* attrib =
10918       state_.vertex_attrib_manager->GetVertexAttrib(0);
10919   // If it's enabled or it's not used then we don't need to do anything.
10920   bool attrib_0_used =
10921       state_.current_program->GetAttribInfoByLocation(0) != nullptr;
10922   if (attrib->enabled() && attrib_0_used) {
10923     return true;
10924   }
10925 
10926   // Make a buffer with a single repeated vec4 value enough to
10927   // simulate the constant value that is supposed to be here.
10928   // This is required to emulate GLES2 on GL.
10929   GLuint num_vertices = max_vertex_accessed + 1;
10930   uint32_t size_needed = 0;
10931 
10932   if (num_vertices == 0 ||
10933       !base::CheckMul(num_vertices, sizeof(Vec4f))
10934            .AssignIfValid(&size_needed) ||
10935       size_needed > 0x7FFFFFFFU) {
10936     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
10937     return false;
10938   }
10939 
10940   LOCAL_PERFORMANCE_WARNING(
10941       "Attribute 0 is disabled. This has significant performance penalty");
10942 
10943   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
10944   api()->glBindBufferFn(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
10945 
10946   bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
10947   if (new_buffer) {
10948     api()->glBufferDataFn(GL_ARRAY_BUFFER, size_needed, nullptr,
10949                           GL_DYNAMIC_DRAW);
10950     GLenum error = api()->glGetErrorFn();
10951     if (error != GL_NO_ERROR) {
10952       LOCAL_SET_GL_ERROR(
10953           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
10954       return false;
10955     }
10956   }
10957 
10958   const Vec4& value = state_.attrib_values[0];
10959   if (new_buffer || (attrib_0_used && (!attrib_0_buffer_matches_value_ ||
10960                                        !value.Equal(attrib_0_value_)))) {
10961     // TODO(zmo): This is not 100% correct because we might lose data when
10962     // casting to float type, but it is a corner case and once we migrate to
10963     // core profiles on desktop GL, it is no longer relevant.
10964     Vec4f fvalue(value);
10965     constexpr GLuint kMaxVerticesPerLoop = 32u << 10;
10966     const GLuint vertices_per_loop =
10967         std::min(num_vertices, kMaxVerticesPerLoop);
10968     std::vector<Vec4f> temp(vertices_per_loop, fvalue);
10969     for (GLuint offset = 0; offset < num_vertices;) {
10970       GLuint count = std::min(num_vertices - offset, vertices_per_loop);
10971       api()->glBufferSubDataFn(GL_ARRAY_BUFFER, offset * sizeof(Vec4f),
10972                                count * sizeof(Vec4f), temp.data());
10973       offset += count;
10974     }
10975     attrib_0_buffer_matches_value_ = true;
10976     attrib_0_value_ = value;
10977     attrib_0_size_ = size_needed;
10978   }
10979 
10980   api()->glVertexAttribPointerFn(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
10981 
10982   if (feature_info_->feature_flags().angle_instanced_arrays)
10983     api()->glVertexAttribDivisorANGLEFn(0, 0);
10984 
10985   *simulated = true;
10986   return true;
10987 }
10988 
RestoreStateForAttrib(GLuint attrib_index,bool restore_array_binding)10989 void GLES2DecoderImpl::RestoreStateForAttrib(
10990     GLuint attrib_index, bool restore_array_binding) {
10991   const VertexAttrib* attrib =
10992       state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
10993   if (restore_array_binding) {
10994     const void* ptr = reinterpret_cast<const void*>(attrib->offset());
10995     Buffer* buffer = attrib->buffer();
10996     api()->glBindBufferFn(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
10997     api()->glVertexAttribPointerFn(attrib_index, attrib->size(), attrib->type(),
10998                                    attrib->normalized(), attrib->gl_stride(),
10999                                    ptr);
11000   }
11001 
11002   // Attrib divisors should only be non-zero when the ANGLE_instanced_arrays
11003   // extension is available
11004   DCHECK(attrib->divisor() == 0 ||
11005       feature_info_->feature_flags().angle_instanced_arrays);
11006 
11007   if (feature_info_->feature_flags().angle_instanced_arrays)
11008     api()->glVertexAttribDivisorANGLEFn(attrib_index, attrib->divisor());
11009   api()->glBindBufferFn(GL_ARRAY_BUFFER,
11010                         state_.bound_array_buffer.get()
11011                             ? state_.bound_array_buffer->service_id()
11012                             : 0);
11013 
11014   // Never touch vertex attribute 0's state (in particular, never disable it)
11015   // when running on desktop GL with compatibility profile because it will
11016   // never be re-enabled.
11017   if (attrib_index != 0 || gl_version_info().BehavesLikeGLES()) {
11018     // Restore the vertex attrib array enable-state according to
11019     // the VertexAttrib enabled_in_driver value (which really represents the
11020     // state of the virtual context - not the driver - notably, above the
11021     // vertex array object emulation layer).
11022     if (attrib->enabled_in_driver()) {
11023       api()->glEnableVertexAttribArrayFn(attrib_index);
11024     } else {
11025       api()->glDisableVertexAttribArrayFn(attrib_index);
11026     }
11027   }
11028 }
11029 
SimulateFixedAttribs(const char * function_name,GLuint max_vertex_accessed,bool * simulated,GLsizei primcount)11030 bool GLES2DecoderImpl::SimulateFixedAttribs(const char* function_name,
11031                                             GLuint max_vertex_accessed,
11032                                             bool* simulated,
11033                                             GLsizei primcount) {
11034   DCHECK(simulated);
11035   *simulated = false;
11036   if (gl_version_info().SupportsFixedType())
11037     return true;
11038 
11039   if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
11040     return true;
11041   }
11042 
11043   LOCAL_PERFORMANCE_WARNING(
11044       "GL_FIXED attributes have a significant performance penalty");
11045 
11046   // NOTE: we could be smart and try to check if a buffer is used
11047   // twice in 2 different attribs, find the overlapping parts and therefore
11048   // duplicate the minimum amount of data but this whole code path is not meant
11049   // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
11050   // tests so we just add to the buffer attrib used.
11051 
11052   base::CheckedNumeric<uint32_t> elements_needed = 0;
11053   const VertexAttribManager::VertexAttribList& enabled_attribs =
11054       state_.vertex_attrib_manager->GetEnabledVertexAttribs();
11055   for (VertexAttribManager::VertexAttribList::const_iterator it =
11056        enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
11057     const VertexAttrib* attrib = *it;
11058     const Program::VertexAttrib* attrib_info =
11059         state_.current_program->GetAttribInfoByLocation(attrib->index());
11060     GLuint max_accessed =
11061         attrib->MaxVertexAccessed(primcount, max_vertex_accessed);
11062     GLuint num_vertices = max_accessed + 1;
11063     if (num_vertices == 0) {
11064       LOCAL_SET_GL_ERROR(
11065           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
11066       return false;
11067     }
11068     if (attrib_info &&
11069         attrib->CanAccess(max_accessed) &&
11070         attrib->type() == GL_FIXED) {
11071       elements_needed += base::CheckMul(num_vertices, attrib->size());
11072     }
11073   }
11074 
11075   const uint32_t kSizeOfFloat = sizeof(float);  // NOLINT
11076   uint32_t size_needed = 0;
11077   if (!base::CheckMul(elements_needed, kSizeOfFloat)
11078            .AssignIfValid(&size_needed) ||
11079       size_needed > 0x7FFFFFFFU) {
11080     LOCAL_SET_GL_ERROR(
11081         GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
11082     return false;
11083   }
11084 
11085   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
11086 
11087   api()->glBindBufferFn(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
11088   if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
11089     api()->glBufferDataFn(GL_ARRAY_BUFFER, size_needed, nullptr,
11090                           GL_DYNAMIC_DRAW);
11091     GLenum error = api()->glGetErrorFn();
11092     if (error != GL_NO_ERROR) {
11093       LOCAL_SET_GL_ERROR(
11094           GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
11095       return false;
11096     }
11097   }
11098 
11099   // Copy the elements and convert to float
11100   GLintptr offset = 0;
11101   for (VertexAttribManager::VertexAttribList::const_iterator it =
11102        enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
11103     const VertexAttrib* attrib = *it;
11104     const Program::VertexAttrib* attrib_info =
11105         state_.current_program->GetAttribInfoByLocation(attrib->index());
11106     GLuint max_accessed =
11107         attrib->MaxVertexAccessed(primcount, max_vertex_accessed);
11108     GLuint num_vertices = max_accessed + 1;
11109     if (num_vertices == 0) {
11110       LOCAL_SET_GL_ERROR(
11111           GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
11112       return false;
11113     }
11114     if (attrib_info &&
11115         attrib->CanAccess(max_accessed) &&
11116         attrib->type() == GL_FIXED) {
11117       int num_elements = attrib->size() * num_vertices;
11118       const int src_size = num_elements * sizeof(int32_t);
11119       const int dst_size = num_elements * sizeof(float);
11120       std::unique_ptr<float[]> data(new float[num_elements]);
11121       const int32_t* src = reinterpret_cast<const int32_t*>(
11122           attrib->buffer()->GetRange(attrib->offset(), src_size));
11123       const int32_t* end = src + num_elements;
11124       float* dst = data.get();
11125       while (src != end) {
11126         *dst++ = static_cast<float>(*src++) / 65536.0f;
11127       }
11128       api()->glBufferSubDataFn(GL_ARRAY_BUFFER, offset, dst_size, data.get());
11129       api()->glVertexAttribPointerFn(attrib->index(), attrib->size(), GL_FLOAT,
11130                                      false, 0,
11131                                      reinterpret_cast<GLvoid*>(offset));
11132       offset += dst_size;
11133     }
11134   }
11135   *simulated = true;
11136   return true;
11137 }
11138 
RestoreStateForSimulatedFixedAttribs()11139 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
11140   // There's no need to call glVertexAttribPointer because we shadow all the
11141   // settings and passing GL_FIXED to it will not work.
11142   api()->glBindBufferFn(GL_ARRAY_BUFFER,
11143                         state_.bound_array_buffer.get()
11144                             ? state_.bound_array_buffer->service_id()
11145                             : 0);
11146 }
11147 
AttribsTypeMatch()11148 bool GLES2DecoderImpl::AttribsTypeMatch() {
11149   if (!state_.current_program.get())
11150     return true;
11151   const std::vector<uint32_t>& shader_attrib_active_mask =
11152       state_.current_program->vertex_input_active_mask();
11153   const std::vector<uint32_t>& shader_attrib_type_mask =
11154       state_.current_program->vertex_input_base_type_mask();
11155   const std::vector<uint32_t>& generic_vertex_attrib_type_mask =
11156       state_.generic_attrib_base_type_mask();
11157   const std::vector<uint32_t>& vertex_attrib_array_enabled_mask =
11158       state_.vertex_attrib_manager->attrib_enabled_mask();
11159   const std::vector<uint32_t>& vertex_attrib_array_type_mask =
11160       state_.vertex_attrib_manager->attrib_base_type_mask();
11161   DCHECK_EQ(shader_attrib_active_mask.size(),
11162             shader_attrib_type_mask.size());
11163   DCHECK_EQ(shader_attrib_active_mask.size(),
11164             generic_vertex_attrib_type_mask.size());
11165   DCHECK_EQ(shader_attrib_active_mask.size(),
11166             vertex_attrib_array_enabled_mask.size());
11167   DCHECK_EQ(shader_attrib_active_mask.size(),
11168             vertex_attrib_array_type_mask.size());
11169   for (size_t ii = 0; ii < shader_attrib_active_mask.size(); ++ii) {
11170     uint32_t vertex_attrib_source_type_mask =
11171         (~vertex_attrib_array_enabled_mask[ii] &
11172          generic_vertex_attrib_type_mask[ii]) |
11173         (vertex_attrib_array_enabled_mask[ii] &
11174          vertex_attrib_array_type_mask[ii]);
11175     if ((shader_attrib_type_mask[ii] & shader_attrib_active_mask[ii]) !=
11176         (vertex_attrib_source_type_mask & shader_attrib_active_mask[ii])) {
11177       return false;
11178     }
11179   }
11180   return true;
11181 }
11182 
11183 template <GLES2DecoderImpl::DrawArraysOption option>
CheckMultiDrawArraysVertices(const char * function_name,bool instanced,const GLint * firsts,const GLsizei * counts,const GLsizei * primcounts,const GLuint * baseinstances,GLsizei drawcount,GLuint * total_max_vertex_accessed,GLsizei * total_max_primcount)11184 ALWAYS_INLINE bool GLES2DecoderImpl::CheckMultiDrawArraysVertices(
11185     const char* function_name,
11186     bool instanced,
11187     const GLint* firsts,
11188     const GLsizei* counts,
11189     const GLsizei* primcounts,
11190     const GLuint* baseinstances,
11191     GLsizei drawcount,
11192     GLuint* total_max_vertex_accessed,
11193     GLsizei* total_max_primcount) {
11194   if (option == DrawArraysOption::Default) {
11195     DCHECK_EQ(baseinstances, nullptr);
11196   }
11197   DCHECK_GE(drawcount, 0);
11198   for (GLsizei draw_id = 0; draw_id < drawcount; ++draw_id) {
11199     GLint first = firsts[draw_id];
11200     GLsizei count = counts[draw_id];
11201     GLsizei primcount = instanced ? primcounts[draw_id] : 1;
11202     GLuint baseinstance = (option == DrawArraysOption::UseBaseInstance)
11203                               ? baseinstances[draw_id]
11204                               : 0;
11205     // We have to check this here because the prototype for glDrawArrays
11206     // is GLint not GLsizei.
11207     if (first < 0) {
11208       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
11209       return false;
11210     }
11211     if (count < 0) {
11212       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
11213       return false;
11214     }
11215     if (primcount < 0) {
11216       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
11217       return false;
11218     }
11219     if (count == 0 || primcount == 0) {
11220       LOCAL_RENDER_WARNING("Render count or primcount is 0.");
11221       continue;
11222     }
11223 
11224     base::CheckedNumeric<GLuint> checked_max_vertex = first;
11225     checked_max_vertex += count - 1;
11226     // first and count-1 are both a non-negative int, so their sum fits an
11227     // unsigned int.
11228     GLuint max_vertex_accessed = 0;
11229     if (!checked_max_vertex.AssignIfValid(&max_vertex_accessed)) {
11230       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11231                          "first + count overflow");
11232       return false;
11233     }
11234     if (!IsDrawValid(function_name, max_vertex_accessed, instanced, primcount,
11235                      0, baseinstance)) {
11236       return false;
11237     }
11238     *total_max_vertex_accessed =
11239         std::max(*total_max_vertex_accessed, max_vertex_accessed);
11240     *total_max_primcount = std::max(*total_max_primcount, primcount);
11241   }
11242   return true;
11243 }
11244 
CheckTransformFeedback(const char * function_name,bool instanced,GLenum mode,const GLsizei * counts,const GLsizei * primcounts,GLsizei drawcount,GLsizei * vertices_drawn)11245 ALWAYS_INLINE bool GLES2DecoderImpl::CheckTransformFeedback(
11246     const char* function_name,
11247     bool instanced,
11248     GLenum mode,
11249     const GLsizei* counts,
11250     const GLsizei* primcounts,
11251     GLsizei drawcount,
11252     GLsizei* vertices_drawn) {
11253   DCHECK(state_.bound_transform_feedback.get());
11254   if (state_.bound_transform_feedback->active() &&
11255       !state_.bound_transform_feedback->paused()) {
11256     if (mode != state_.bound_transform_feedback->primitive_mode()) {
11257       LOCAL_SET_GL_ERROR(
11258           GL_INVALID_OPERATION, function_name,
11259           "mode differs from active transformfeedback's primitiveMode");
11260       return false;
11261     }
11262     for (GLsizei draw_id = 0; draw_id < drawcount; ++draw_id) {
11263       GLsizei count = counts[draw_id];
11264       GLsizei primcount = instanced ? primcounts[draw_id] : 1;
11265 
11266       bool valid = state_.bound_transform_feedback->GetVerticesNeededForDraw(
11267           mode, count, primcount, *vertices_drawn, vertices_drawn);
11268       if (!valid) {
11269         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11270                            "integer overflow calculating number of vertices "
11271                            "for transform feedback");
11272         return false;
11273       }
11274     }
11275 
11276     if (!buffer_manager()->RequestBuffersAccess(
11277             error_state_.get(), state_.bound_transform_feedback.get(),
11278             state_.current_program->GetTransformFeedbackVaryingSizes(),
11279             *vertices_drawn, function_name, "transformfeedback buffers")) {
11280       return false;
11281     }
11282   }
11283   return true;
11284 }
11285 
11286 template <GLES2DecoderImpl::DrawArraysOption option>
DoMultiDrawArrays(const char * function_name,bool instanced,GLenum mode,const GLint * firsts,const GLsizei * counts,const GLsizei * primcounts,const GLuint * baseinstances,GLsizei drawcount)11287 ALWAYS_INLINE error::Error GLES2DecoderImpl::DoMultiDrawArrays(
11288     const char* function_name,
11289     bool instanced,
11290     GLenum mode,
11291     const GLint* firsts,
11292     const GLsizei* counts,
11293     const GLsizei* primcounts,
11294     const GLuint* baseinstances,
11295     GLsizei drawcount) {
11296   if (option == DrawArraysOption::Default) {
11297     DCHECK_EQ(baseinstances, nullptr);
11298   }
11299   error::Error error = WillAccessBoundFramebufferForDraw();
11300   if (error != error::kNoError)
11301     return error;
11302 
11303   if (!validators_->draw_mode.IsValid(mode)) {
11304     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
11305     return error::kNoError;
11306   }
11307 
11308   if (drawcount < 0) {
11309     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "drawcount < 0");
11310     return error::kNoError;
11311   }
11312 
11313   if (!CheckBoundDrawFramebufferValid(function_name, true)) {
11314     return error::kNoError;
11315   }
11316 
11317   GLuint total_max_vertex_accessed = 0;
11318   GLsizei total_max_primcount = 0;
11319   if (!CheckMultiDrawArraysVertices<option>(
11320           function_name, instanced, firsts, counts, primcounts, baseinstances,
11321           drawcount, &total_max_vertex_accessed, &total_max_primcount)) {
11322     return error::kNoError;
11323   }
11324 
11325   if (total_max_primcount == 0) {
11326     return error::kNoError;
11327   }
11328 
11329   GLsizei transform_feedback_vertices = 0;
11330   if (feature_info_->IsWebGL2OrES3Context()) {
11331     if (!AttribsTypeMatch()) {
11332       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11333                          "vertexAttrib function must match shader attrib type");
11334       return error::kNoError;
11335     }
11336 
11337     if (!CheckTransformFeedback(function_name, instanced, mode, counts,
11338                                 primcounts, drawcount,
11339                                 &transform_feedback_vertices)) {
11340       return error::kNoError;
11341     }
11342 
11343     if (!ValidateUniformBlockBackings(function_name)) {
11344       return error::kNoError;
11345     }
11346   }
11347 
11348   if (!ClearUnclearedTextures()) {
11349     // TODO(enga): Can this be GL_OUT_OF_MEMORY?
11350     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
11351     return error::kNoError;
11352   }
11353 
11354   bool simulated_attrib_0 = false;
11355   if (!SimulateAttrib0(function_name, total_max_vertex_accessed,
11356                        &simulated_attrib_0)) {
11357     return error::kNoError;
11358   }
11359   bool simulated_fixed_attribs = false;
11360   // The branch with fixed attrib is not meant to be used
11361   // normally but just to pass OpenGL ES 2 conformance where there's no
11362   // basevertex and baseinstance support.
11363   if (SimulateFixedAttribs(function_name, total_max_vertex_accessed,
11364                            &simulated_fixed_attribs, total_max_primcount)) {
11365     bool textures_set;
11366     if (!PrepareTexturesForRender(&textures_set, function_name)) {
11367       return error::kNoError;
11368     }
11369     ApplyDirtyState();
11370     if (!ValidateAndAdjustDrawBuffers(function_name)) {
11371       return error::kNoError;
11372     }
11373 
11374     GLint draw_id_location = state_.current_program->draw_id_uniform_location();
11375     GLint base_instance_location =
11376         state_.current_program->base_instance_uniform_location();
11377     for (GLsizei draw_id = 0; draw_id < drawcount; ++draw_id) {
11378       GLint first = firsts[draw_id];
11379       GLsizei count = counts[draw_id];
11380       GLsizei primcount = instanced ? primcounts[draw_id] : 1;
11381       if (count == 0 || primcount == 0) {
11382         continue;
11383       }
11384       if (draw_id_location >= 0) {
11385         api()->glUniform1iFn(draw_id_location, draw_id);
11386       }
11387       if (!instanced) {
11388         api()->glDrawArraysFn(mode, first, count);
11389       } else {
11390         if (option != DrawArraysOption::UseBaseInstance) {
11391           api()->glDrawArraysInstancedANGLEFn(mode, first, count, primcount);
11392         } else {
11393           GLuint baseinstance = baseinstances[draw_id];
11394           if (base_instance_location >= 0) {
11395             api()->glUniform1iFn(base_instance_location, baseinstance);
11396           }
11397           api()->glDrawArraysInstancedBaseInstanceANGLEFn(
11398               mode, first, count, primcount, baseinstance);
11399         }
11400       }
11401     }
11402     if (state_.bound_transform_feedback.get()) {
11403       state_.bound_transform_feedback->OnVerticesDrawn(
11404           transform_feedback_vertices);
11405     }
11406 
11407     if (textures_set) {
11408       RestoreStateForTextures();
11409     }
11410     if (simulated_fixed_attribs) {
11411       RestoreStateForSimulatedFixedAttribs();
11412     }
11413     // only reset base vertex and base instance shader variable when it's
11414     // possibly non-zero
11415     if (option == DrawArraysOption::UseBaseInstance) {
11416       if (base_instance_location >= 0) {
11417         api()->glUniform1iFn(base_instance_location, 0);
11418       }
11419     }
11420   }
11421   if (simulated_attrib_0) {
11422     // We don't have to restore attrib 0 generic data at the end of this
11423     // function even if it is simulated. This is because we will simulate
11424     // it in each draw call, and attrib 0 generic data queries use cached
11425     // values instead of passing down to the underlying driver.
11426     RestoreStateForAttrib(0, false);
11427   }
11428   return error::kNoError;
11429 }
11430 
HandleDrawArrays(uint32_t immediate_data_size,const volatile void * cmd_data)11431 error::Error GLES2DecoderImpl::HandleDrawArrays(uint32_t immediate_data_size,
11432                                                 const volatile void* cmd_data) {
11433   const volatile cmds::DrawArrays& c =
11434       *static_cast<const volatile cmds::DrawArrays*>(cmd_data);
11435   GLint first = static_cast<GLint>(c.first);
11436   GLsizei count = static_cast<GLsizei>(c.count);
11437   return DoMultiDrawArrays<DrawArraysOption::Default>(
11438       "glDrawArrays", false, static_cast<GLenum>(c.mode), &first, &count,
11439       nullptr, nullptr, 1);
11440 }
11441 
HandleDrawArraysInstancedANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)11442 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
11443     uint32_t immediate_data_size,
11444     const volatile void* cmd_data) {
11445   const volatile gles2::cmds::DrawArraysInstancedANGLE& c =
11446       *static_cast<const volatile gles2::cmds::DrawArraysInstancedANGLE*>(
11447           cmd_data);
11448   if (!features().angle_instanced_arrays)
11449     return error::kUnknownCommand;
11450 
11451   GLint first = static_cast<GLint>(c.first);
11452   GLsizei count = static_cast<GLsizei>(c.count);
11453   GLsizei primcount = static_cast<GLsizei>(c.primcount);
11454   return DoMultiDrawArrays<DrawArraysOption::Default>(
11455       "glDrawArraysInstancedANGLE", true, static_cast<GLenum>(c.mode), &first,
11456       &count, &primcount, nullptr, 1);
11457 }
11458 
HandleDrawArraysInstancedBaseInstanceANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)11459 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedBaseInstanceANGLE(
11460     uint32_t immediate_data_size,
11461     const volatile void* cmd_data) {
11462   const volatile gles2::cmds::DrawArraysInstancedBaseInstanceANGLE& c =
11463       *static_cast<
11464           const volatile gles2::cmds::DrawArraysInstancedBaseInstanceANGLE*>(
11465           cmd_data);
11466   if (!features().angle_instanced_arrays)
11467     return error::kUnknownCommand;
11468   if (!features().webgl_draw_instanced_base_vertex_base_instance &&
11469       !features().webgl_multi_draw_instanced_base_vertex_base_instance)
11470     return error::kUnknownCommand;
11471 
11472   GLint first = static_cast<GLint>(c.first);
11473   GLsizei count = static_cast<GLsizei>(c.count);
11474   GLsizei primcount = static_cast<GLsizei>(c.primcount);
11475   GLuint baseInstances = static_cast<GLuint>(c.baseinstance);
11476   return DoMultiDrawArrays<DrawArraysOption::UseBaseInstance>(
11477       "glDrawArraysInstancedBaseInstanceANGLE", true,
11478       static_cast<GLenum>(c.mode), &first, &count, &primcount, &baseInstances,
11479       1);
11480 }
11481 
11482 template <GLES2DecoderImpl::DrawElementsOption option>
CheckMultiDrawElementsVertices(const char * function_name,bool instanced,const GLsizei * counts,GLenum type,const int32_t * offsets,const GLsizei * primcounts,const GLint * basevertices,const GLuint * baseinstances,GLsizei drawcount,Buffer * element_array_buffer,GLuint * total_max_vertex_accessed,GLsizei * total_max_primcount)11483 ALWAYS_INLINE bool GLES2DecoderImpl::CheckMultiDrawElementsVertices(
11484     const char* function_name,
11485     bool instanced,
11486     const GLsizei* counts,
11487     GLenum type,
11488     const int32_t* offsets,
11489     const GLsizei* primcounts,
11490     const GLint* basevertices,
11491     const GLuint* baseinstances,
11492     GLsizei drawcount,
11493     Buffer* element_array_buffer,
11494     GLuint* total_max_vertex_accessed,
11495     GLsizei* total_max_primcount) {
11496   if (option == DrawElementsOption::Default) {
11497     DCHECK_EQ(basevertices, nullptr);
11498     DCHECK_EQ(baseinstances, nullptr);
11499   }
11500   DCHECK_GE(drawcount, 0);
11501   for (GLsizei draw_id = 0; draw_id < drawcount; ++draw_id) {
11502     GLsizei count = counts[draw_id];
11503     GLsizei offset = offsets[draw_id];
11504     GLsizei primcount = instanced ? primcounts[draw_id] : 1;
11505     GLint basevertex = (option == DrawElementsOption::UseBaseVertexBaseInstance)
11506                            ? basevertices[draw_id]
11507                            : 0;
11508     GLint baseinstance =
11509         (option == DrawElementsOption::UseBaseVertexBaseInstance)
11510             ? baseinstances[draw_id]
11511             : 0;
11512 
11513     if (count < 0) {
11514       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
11515       return false;
11516     }
11517     if (offset < 0) {
11518       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
11519       return false;
11520     }
11521     if (primcount < 0) {
11522       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
11523       return false;
11524     }
11525     if (count == 0 || primcount == 0) {
11526       continue;
11527     }
11528 
11529     GLuint max_vertex_accessed;
11530     if (!element_array_buffer->GetMaxValueForRange(
11531             offset, count, type,
11532             state_.enable_flags.primitive_restart_fixed_index,
11533             &max_vertex_accessed)) {
11534       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11535                          "range out of bounds for buffer");
11536       return false;
11537     }
11538 
11539     if (!IsDrawValid(function_name, max_vertex_accessed, instanced, primcount,
11540                      basevertex, baseinstance)) {
11541       return false;
11542     }
11543 
11544     *total_max_vertex_accessed =
11545         std::max(*total_max_vertex_accessed, max_vertex_accessed + basevertex);
11546     *total_max_primcount = std::max(*total_max_primcount, primcount);
11547   }
11548   return true;
11549 }
11550 
11551 template <GLES2DecoderImpl::DrawElementsOption option>
DoMultiDrawElements(const char * function_name,bool instanced,GLenum mode,const GLsizei * counts,GLenum type,const int32_t * offsets,const GLsizei * primcounts,const GLint * basevertices,const GLuint * baseinstances,GLsizei drawcount)11552 ALWAYS_INLINE error::Error GLES2DecoderImpl::DoMultiDrawElements(
11553     const char* function_name,
11554     bool instanced,
11555     GLenum mode,
11556     const GLsizei* counts,
11557     GLenum type,
11558     const int32_t* offsets,
11559     const GLsizei* primcounts,
11560     const GLint* basevertices,
11561     const GLuint* baseinstances,
11562     GLsizei drawcount) {
11563   if (option == DrawElementsOption::Default) {
11564     DCHECK_EQ(basevertices, nullptr);
11565     DCHECK_EQ(baseinstances, nullptr);
11566   }
11567 
11568   error::Error error = WillAccessBoundFramebufferForDraw();
11569   if (error != error::kNoError)
11570     return error;
11571 
11572   if (!validators_->draw_mode.IsValid(mode)) {
11573     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
11574     return error::kNoError;
11575   }
11576 
11577   if (!validators_->index_type.IsValid(type)) {
11578     LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
11579     return error::kNoError;
11580   }
11581 
11582   if (drawcount < 0) {
11583     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "drawcount < 0");
11584     return error::kNoError;
11585   }
11586 
11587   if (!CheckBoundDrawFramebufferValid(function_name, true)) {
11588     return error::kNoError;
11589   }
11590 
11591   Buffer* element_array_buffer = buffer_manager()->RequestBufferAccess(
11592       &state_, error_state_.get(), GL_ELEMENT_ARRAY_BUFFER, function_name);
11593   if (!element_array_buffer) {
11594     return error::kNoError;
11595   }
11596 
11597   if (state_.bound_transform_feedback.get() &&
11598       state_.bound_transform_feedback->active() &&
11599       !state_.bound_transform_feedback->paused()) {
11600     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11601                        "transformfeedback is active and not paused");
11602     return error::kNoError;
11603   }
11604 
11605   GLuint total_max_vertex_accessed = 0;
11606   GLsizei total_max_primcount = 0;
11607   if (!CheckMultiDrawElementsVertices<option>(
11608           function_name, instanced, counts, type, offsets, primcounts,
11609           basevertices, baseinstances, drawcount, element_array_buffer,
11610           &total_max_vertex_accessed, &total_max_primcount)) {
11611     return error::kNoError;
11612   }
11613 
11614   if (total_max_primcount == 0) {
11615     return error::kNoError;
11616   }
11617 
11618   if (feature_info_->IsWebGL2OrES3Context()) {
11619     if (!AttribsTypeMatch()) {
11620       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11621                          "vertexAttrib function must match shader attrib type");
11622       return error::kNoError;
11623     }
11624     if (!ValidateUniformBlockBackings(function_name)) {
11625       return error::kNoError;
11626     }
11627   }
11628 
11629   if (!ClearUnclearedTextures()) {
11630     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
11631     return error::kNoError;
11632   }
11633 
11634   bool simulated_attrib_0 = false;
11635   if (!SimulateAttrib0(function_name, total_max_vertex_accessed,
11636                        &simulated_attrib_0)) {
11637     return error::kNoError;
11638   }
11639   bool simulated_fixed_attribs = false;
11640   // The branch with fixed attrib is not meant to be used
11641   // normally But just to pass OpenGL ES 2 conformance where there's no
11642   // basevertex and baseinstance support.
11643   if (SimulateFixedAttribs(function_name, total_max_vertex_accessed,
11644                            &simulated_fixed_attribs, total_max_primcount)) {
11645     bool textures_set;
11646     if (!PrepareTexturesForRender(&textures_set, function_name)) {
11647       return error::kNoError;
11648     }
11649     ApplyDirtyState();
11650     // TODO(gman): Refactor to hide these details in BufferManager or
11651     // VertexAttribManager.
11652     bool used_client_side_array = false;
11653     if (element_array_buffer->IsClientSideArray()) {
11654       used_client_side_array = true;
11655       api()->glBindBufferFn(GL_ELEMENT_ARRAY_BUFFER, 0);
11656     }
11657     if (!ValidateAndAdjustDrawBuffers(function_name)) {
11658       return error::kNoError;
11659     }
11660     if (state_.enable_flags.primitive_restart_fixed_index &&
11661         feature_info_->feature_flags().emulate_primitive_restart_fixed_index) {
11662       api()->glEnableFn(GL_PRIMITIVE_RESTART);
11663       buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type);
11664     }
11665 
11666     GLint draw_id_location = state_.current_program->draw_id_uniform_location();
11667     GLint base_vertex_location =
11668         state_.current_program->base_vertex_uniform_location();
11669     GLint base_instance_location =
11670         state_.current_program->base_instance_uniform_location();
11671     for (GLsizei draw_id = 0; draw_id < drawcount; ++draw_id) {
11672       GLsizei count = counts[draw_id];
11673       GLsizei offset = offsets[draw_id];
11674       GLsizei primcount = instanced ? primcounts[draw_id] : 1;
11675       if (count == 0 || primcount == 0) {
11676         continue;
11677       }
11678       const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
11679       if (used_client_side_array) {
11680         indices = element_array_buffer->GetRange(offset, 0);
11681       }
11682       if (draw_id_location >= 0) {
11683         api()->glUniform1iFn(draw_id_location, draw_id);
11684       }
11685       if (!instanced) {
11686         api()->glDrawElementsFn(mode, count, type, indices);
11687       } else {
11688         if (option == DrawElementsOption::Default) {
11689           api()->glDrawElementsInstancedANGLEFn(mode, count, type, indices,
11690                                                 primcount);
11691         } else {
11692           GLint basevertex = basevertices[draw_id];
11693           GLuint baseinstance = baseinstances[draw_id];
11694           if (base_vertex_location >= 0) {
11695             api()->glUniform1iFn(base_vertex_location, basevertex);
11696           }
11697           if (base_instance_location >= 0) {
11698             api()->glUniform1iFn(base_instance_location, baseinstance);
11699           }
11700           api()->glDrawElementsInstancedBaseVertexBaseInstanceANGLEFn(
11701               mode, count, type, indices, primcount, basevertex, baseinstance);
11702         }
11703       }
11704     }
11705     if (state_.enable_flags.primitive_restart_fixed_index &&
11706         feature_info_->feature_flags().emulate_primitive_restart_fixed_index) {
11707       api()->glDisableFn(GL_PRIMITIVE_RESTART);
11708     }
11709     if (used_client_side_array) {
11710       api()->glBindBufferFn(GL_ELEMENT_ARRAY_BUFFER,
11711                             element_array_buffer->service_id());
11712     }
11713     if (textures_set) {
11714       RestoreStateForTextures();
11715     }
11716     if (simulated_fixed_attribs) {
11717       RestoreStateForSimulatedFixedAttribs();
11718     }
11719     // only reset base vertex and base instance shader variable when it's
11720     // possibly non-zero
11721     if (option == DrawElementsOption::UseBaseVertexBaseInstance) {
11722       if (base_vertex_location >= 0) {
11723         api()->glUniform1iFn(base_vertex_location, 0);
11724       }
11725       if (base_instance_location >= 0) {
11726         api()->glUniform1iFn(base_instance_location, 0);
11727       }
11728     }
11729   }
11730   if (simulated_attrib_0) {
11731     // We don't have to restore attrib 0 generic data at the end of this
11732     // function even if it is simulated. This is because we will simulate
11733     // it in each draw call, and attrib 0 generic data queries use cached
11734     // values instead of passing down to the underlying driver.
11735     RestoreStateForAttrib(0, false);
11736   }
11737   return error::kNoError;
11738 }
11739 
HandleDrawElements(uint32_t immediate_data_size,const volatile void * cmd_data)11740 error::Error GLES2DecoderImpl::HandleDrawElements(
11741     uint32_t immediate_data_size,
11742     const volatile void* cmd_data) {
11743   const volatile gles2::cmds::DrawElements& c =
11744       *static_cast<const volatile gles2::cmds::DrawElements*>(cmd_data);
11745   GLsizei count = static_cast<GLsizei>(c.count);
11746   int32_t offset = static_cast<int32_t>(c.index_offset);
11747   return DoMultiDrawElements<DrawElementsOption::Default>(
11748       "glDrawElements", false, static_cast<GLenum>(c.mode), &count,
11749       static_cast<GLenum>(c.type), &offset, nullptr, nullptr, nullptr, 1);
11750 }
11751 
HandleDrawElementsInstancedANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)11752 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
11753     uint32_t immediate_data_size,
11754     const volatile void* cmd_data) {
11755   const volatile gles2::cmds::DrawElementsInstancedANGLE& c =
11756       *static_cast<const volatile gles2::cmds::DrawElementsInstancedANGLE*>(
11757           cmd_data);
11758   if (!features().angle_instanced_arrays)
11759     return error::kUnknownCommand;
11760 
11761   GLsizei count = static_cast<GLsizei>(c.count);
11762   int32_t offset = static_cast<int32_t>(c.index_offset);
11763   GLsizei primcount = static_cast<GLsizei>(c.primcount);
11764 
11765   return DoMultiDrawElements<DrawElementsOption::Default>(
11766       "glDrawElementsInstancedANGLE", true, static_cast<GLenum>(c.mode), &count,
11767       static_cast<GLenum>(c.type), &offset, &primcount, nullptr, nullptr, 1);
11768 }
11769 
11770 error::Error
HandleDrawElementsInstancedBaseVertexBaseInstanceANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)11771 GLES2DecoderImpl::HandleDrawElementsInstancedBaseVertexBaseInstanceANGLE(
11772     uint32_t immediate_data_size,
11773     const volatile void* cmd_data) {
11774   const volatile gles2::cmds::DrawElementsInstancedBaseVertexBaseInstanceANGLE&
11775       c = *static_cast<const volatile gles2::cmds::
11776                            DrawElementsInstancedBaseVertexBaseInstanceANGLE*>(
11777           cmd_data);
11778   if (!features().angle_instanced_arrays)
11779     return error::kUnknownCommand;
11780 
11781   GLsizei count = static_cast<GLsizei>(c.count);
11782   int32_t offset = static_cast<int32_t>(c.index_offset);
11783   GLsizei primcount = static_cast<GLsizei>(c.primcount);
11784   GLint basevertex = static_cast<GLsizei>(c.basevertex);
11785   GLuint baseinstance = static_cast<GLsizei>(c.baseinstance);
11786   return DoMultiDrawElements<DrawElementsOption::UseBaseVertexBaseInstance>(
11787       "glDrawElementsInstancedBaseVertexBaseInstanceANGLE", true,
11788       static_cast<GLenum>(c.mode), &count, static_cast<GLenum>(c.type), &offset,
11789       &primcount, &basevertex, &baseinstance, 1);
11790 }
11791 
DoMultiDrawBeginCHROMIUM(GLsizei drawcount)11792 void GLES2DecoderImpl::DoMultiDrawBeginCHROMIUM(GLsizei drawcount) {
11793   if (!multi_draw_manager_->Begin(drawcount)) {
11794     MarkContextLost(error::kGuilty);
11795     group_->LoseContexts(error::kInnocent);
11796   }
11797 }
11798 
DoMultiDrawEndCHROMIUM()11799 void GLES2DecoderImpl::DoMultiDrawEndCHROMIUM() {
11800   MultiDrawManager::ResultData result;
11801   if (!multi_draw_manager_->End(&result)) {
11802     MarkContextLost(error::kGuilty);
11803     group_->LoseContexts(error::kInnocent);
11804     return;
11805   }
11806   switch (result.draw_function) {
11807     case MultiDrawManager::DrawFunction::DrawArrays:
11808       DoMultiDrawArrays<DrawArraysOption::Default>(
11809           "glMultiDrawArraysWEBGL", false, result.mode, result.firsts.data(),
11810           result.counts.data(), nullptr, nullptr, result.drawcount);
11811       break;
11812     case MultiDrawManager::DrawFunction::DrawArraysInstanced:
11813       DoMultiDrawArrays<DrawArraysOption::Default>(
11814           "glMultiDrawArraysInstancedWEBGL", true, result.mode,
11815           result.firsts.data(), result.counts.data(),
11816           result.instance_counts.data(), nullptr, result.drawcount);
11817       break;
11818     case MultiDrawManager::DrawFunction::DrawArraysInstancedBaseInstance:
11819       DoMultiDrawArrays<DrawArraysOption::UseBaseInstance>(
11820           "glMultiDrawArraysInstancedBaseInstanceWEBGL", true, result.mode,
11821           result.firsts.data(), result.counts.data(),
11822           result.instance_counts.data(), result.baseinstances.data(),
11823           result.drawcount);
11824       break;
11825     case MultiDrawManager::DrawFunction::DrawElements:
11826       DoMultiDrawElements<DrawElementsOption::Default>(
11827           "glMultiDrawElementsWEBGL", false, result.mode, result.counts.data(),
11828           result.type, result.offsets.data(), nullptr, nullptr, nullptr,
11829           result.drawcount);
11830       break;
11831     case MultiDrawManager::DrawFunction::DrawElementsInstanced:
11832       DoMultiDrawElements<DrawElementsOption::Default>(
11833           "glMultiDrawElementsInstancedWEBGL", true, result.mode,
11834           result.counts.data(), result.type, result.offsets.data(),
11835           result.instance_counts.data(), nullptr, nullptr, result.drawcount);
11836       break;
11837     case MultiDrawManager::DrawFunction::
11838         DrawElementsInstancedBaseVertexBaseInstance:
11839       DoMultiDrawElements<DrawElementsOption::UseBaseVertexBaseInstance>(
11840           "glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL", true,
11841           result.mode, result.counts.data(), result.type, result.offsets.data(),
11842           result.instance_counts.data(), result.basevertices.data(),
11843           result.baseinstances.data(), result.drawcount);
11844       break;
11845     default:
11846       NOTREACHED();
11847       MarkContextLost(error::kGuilty);
11848       group_->LoseContexts(error::kInnocent);
11849   }
11850 }
11851 
HandleMultiDrawArraysCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)11852 error::Error GLES2DecoderImpl::HandleMultiDrawArraysCHROMIUM(
11853     uint32_t immediate_data_size,
11854     const volatile void* cmd_data) {
11855   const volatile gles2::cmds::MultiDrawArraysCHROMIUM& c =
11856       *static_cast<const volatile gles2::cmds::MultiDrawArraysCHROMIUM*>(
11857           cmd_data);
11858   if (!features().webgl_multi_draw) {
11859     return error::kUnknownCommand;
11860   }
11861 
11862   GLenum mode = static_cast<GLenum>(c.mode);
11863   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
11864 
11865   uint32_t firsts_size, counts_size;
11866   base::CheckedNumeric<uint32_t> checked_size(drawcount);
11867   if (!(checked_size * sizeof(GLint)).AssignIfValid(&firsts_size)) {
11868     return error::kOutOfBounds;
11869   }
11870   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
11871     return error::kOutOfBounds;
11872   }
11873   const GLint* firsts = GetSharedMemoryAs<const GLint*>(
11874       c.firsts_shm_id, c.firsts_shm_offset, firsts_size);
11875   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
11876       c.counts_shm_id, c.counts_shm_offset, counts_size);
11877   if (firsts == nullptr) {
11878     return error::kOutOfBounds;
11879   }
11880   if (counts == nullptr) {
11881     return error::kOutOfBounds;
11882   }
11883   if (!multi_draw_manager_->MultiDrawArrays(mode, firsts, counts, drawcount)) {
11884     return error::kInvalidArguments;
11885   }
11886   return error::kNoError;
11887 }
11888 
HandleMultiDrawArraysInstancedCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)11889 error::Error GLES2DecoderImpl::HandleMultiDrawArraysInstancedCHROMIUM(
11890     uint32_t immediate_data_size,
11891     const volatile void* cmd_data) {
11892   const volatile gles2::cmds::MultiDrawArraysInstancedCHROMIUM& c =
11893       *static_cast<
11894           const volatile gles2::cmds::MultiDrawArraysInstancedCHROMIUM*>(
11895           cmd_data);
11896   if (!features().webgl_multi_draw) {
11897     return error::kUnknownCommand;
11898   }
11899 
11900   GLenum mode = static_cast<GLenum>(c.mode);
11901   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
11902 
11903   uint32_t firsts_size, counts_size, instance_counts_size;
11904   base::CheckedNumeric<uint32_t> checked_size(drawcount);
11905   if (!(checked_size * sizeof(GLint)).AssignIfValid(&firsts_size)) {
11906     return error::kOutOfBounds;
11907   }
11908   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
11909     return error::kOutOfBounds;
11910   }
11911   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&instance_counts_size)) {
11912     return error::kOutOfBounds;
11913   }
11914   const GLint* firsts = GetSharedMemoryAs<const GLint*>(
11915       c.firsts_shm_id, c.firsts_shm_offset, firsts_size);
11916   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
11917       c.counts_shm_id, c.counts_shm_offset, counts_size);
11918   const GLsizei* instance_counts = GetSharedMemoryAs<const GLsizei*>(
11919       c.instance_counts_shm_id, c.instance_counts_shm_offset,
11920       instance_counts_size);
11921   if (firsts == nullptr) {
11922     return error::kOutOfBounds;
11923   }
11924   if (counts == nullptr) {
11925     return error::kOutOfBounds;
11926   }
11927   if (instance_counts == nullptr) {
11928     return error::kOutOfBounds;
11929   }
11930   if (!multi_draw_manager_->MultiDrawArraysInstanced(
11931           mode, firsts, counts, instance_counts, drawcount)) {
11932     return error::kInvalidArguments;
11933   }
11934   return error::kNoError;
11935 }
11936 
11937 error::Error
HandleMultiDrawArraysInstancedBaseInstanceCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)11938 GLES2DecoderImpl::HandleMultiDrawArraysInstancedBaseInstanceCHROMIUM(
11939     uint32_t immediate_data_size,
11940     const volatile void* cmd_data) {
11941   const volatile gles2::cmds::MultiDrawArraysInstancedBaseInstanceCHROMIUM& c =
11942       *static_cast<const volatile gles2::cmds::
11943                        MultiDrawArraysInstancedBaseInstanceCHROMIUM*>(cmd_data);
11944   if (!features().webgl_multi_draw_instanced_base_vertex_base_instance) {
11945     return error::kUnknownCommand;
11946   }
11947 
11948   GLenum mode = static_cast<GLenum>(c.mode);
11949   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
11950 
11951   uint32_t firsts_size, counts_size, instance_counts_size, baseinstances_size;
11952   base::CheckedNumeric<uint32_t> checked_size(drawcount);
11953   if (!(checked_size * sizeof(GLint)).AssignIfValid(&firsts_size)) {
11954     return error::kOutOfBounds;
11955   }
11956   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
11957     return error::kOutOfBounds;
11958   }
11959   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&instance_counts_size)) {
11960     return error::kOutOfBounds;
11961   }
11962   if (!(checked_size * sizeof(GLuint)).AssignIfValid(&baseinstances_size)) {
11963     return error::kOutOfBounds;
11964   }
11965   const GLint* firsts = GetSharedMemoryAs<const GLint*>(
11966       c.firsts_shm_id, c.firsts_shm_offset, firsts_size);
11967   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
11968       c.counts_shm_id, c.counts_shm_offset, counts_size);
11969   const GLsizei* instance_counts = GetSharedMemoryAs<const GLsizei*>(
11970       c.instance_counts_shm_id, c.instance_counts_shm_offset,
11971       instance_counts_size);
11972   const GLuint* baseinstances_counts = GetSharedMemoryAs<const GLuint*>(
11973       c.baseinstances_shm_id, c.baseinstances_shm_offset, baseinstances_size);
11974   if (firsts == nullptr) {
11975     return error::kOutOfBounds;
11976   }
11977   if (counts == nullptr) {
11978     return error::kOutOfBounds;
11979   }
11980   if (instance_counts == nullptr) {
11981     return error::kOutOfBounds;
11982   }
11983   if (baseinstances_counts == nullptr) {
11984     return error::kOutOfBounds;
11985   }
11986   if (!multi_draw_manager_->MultiDrawArraysInstancedBaseInstance(
11987           mode, firsts, counts, instance_counts, baseinstances_counts,
11988           drawcount)) {
11989     return error::kInvalidArguments;
11990   }
11991   return error::kNoError;
11992 }
11993 
HandleMultiDrawElementsCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)11994 error::Error GLES2DecoderImpl::HandleMultiDrawElementsCHROMIUM(
11995     uint32_t immediate_data_size,
11996     const volatile void* cmd_data) {
11997   const volatile gles2::cmds::MultiDrawElementsCHROMIUM& c =
11998       *static_cast<const volatile gles2::cmds::MultiDrawElementsCHROMIUM*>(
11999           cmd_data);
12000   if (!features().webgl_multi_draw) {
12001     return error::kUnknownCommand;
12002   }
12003 
12004   GLenum mode = static_cast<GLenum>(c.mode);
12005   GLenum type = static_cast<GLenum>(c.type);
12006   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
12007 
12008   uint32_t counts_size, offsets_size;
12009   base::CheckedNumeric<uint32_t> checked_size(drawcount);
12010   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
12011     return error::kOutOfBounds;
12012   }
12013   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&offsets_size)) {
12014     return error::kOutOfBounds;
12015   }
12016   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
12017       c.counts_shm_id, c.counts_shm_offset, counts_size);
12018   const GLsizei* offsets = GetSharedMemoryAs<const GLsizei*>(
12019       c.offsets_shm_id, c.offsets_shm_offset, offsets_size);
12020   if (counts == nullptr) {
12021     return error::kOutOfBounds;
12022   }
12023   if (offsets == nullptr) {
12024     return error::kOutOfBounds;
12025   }
12026   if (!multi_draw_manager_->MultiDrawElements(mode, counts, type, offsets,
12027                                               drawcount)) {
12028     return error::kInvalidArguments;
12029   }
12030   return error::kNoError;
12031 }
12032 
HandleMultiDrawElementsInstancedCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)12033 error::Error GLES2DecoderImpl::HandleMultiDrawElementsInstancedCHROMIUM(
12034     uint32_t immediate_data_size,
12035     const volatile void* cmd_data) {
12036   const volatile gles2::cmds::MultiDrawElementsInstancedCHROMIUM& c =
12037       *static_cast<
12038           const volatile gles2::cmds::MultiDrawElementsInstancedCHROMIUM*>(
12039           cmd_data);
12040   if (!features().webgl_multi_draw) {
12041     return error::kUnknownCommand;
12042   }
12043 
12044   GLenum mode = static_cast<GLenum>(c.mode);
12045   GLenum type = static_cast<GLenum>(c.type);
12046   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
12047 
12048   uint32_t counts_size, offsets_size, instance_counts_size;
12049   base::CheckedNumeric<uint32_t> checked_size(drawcount);
12050   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
12051     return error::kOutOfBounds;
12052   }
12053   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&offsets_size)) {
12054     return error::kOutOfBounds;
12055   }
12056   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&instance_counts_size)) {
12057     return error::kOutOfBounds;
12058   }
12059   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
12060       c.counts_shm_id, c.counts_shm_offset, counts_size);
12061   const GLsizei* offsets = GetSharedMemoryAs<const GLsizei*>(
12062       c.offsets_shm_id, c.offsets_shm_offset, offsets_size);
12063   const GLsizei* instance_counts = GetSharedMemoryAs<const GLsizei*>(
12064       c.instance_counts_shm_id, c.instance_counts_shm_offset,
12065       instance_counts_size);
12066   if (counts == nullptr) {
12067     return error::kOutOfBounds;
12068   }
12069   if (offsets == nullptr) {
12070     return error::kOutOfBounds;
12071   }
12072   if (instance_counts == nullptr) {
12073     return error::kOutOfBounds;
12074   }
12075   if (!multi_draw_manager_->MultiDrawElementsInstanced(
12076           mode, counts, type, offsets, instance_counts, drawcount)) {
12077     return error::kInvalidArguments;
12078   }
12079   return error::kNoError;
12080 }
12081 
12082 error::Error GLES2DecoderImpl::
HandleMultiDrawElementsInstancedBaseVertexBaseInstanceCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)12083     HandleMultiDrawElementsInstancedBaseVertexBaseInstanceCHROMIUM(
12084         uint32_t immediate_data_size,
12085         const volatile void* cmd_data) {
12086   const volatile gles2::cmds::
12087       MultiDrawElementsInstancedBaseVertexBaseInstanceCHROMIUM& c =
12088           *static_cast<
12089               const volatile gles2::cmds::
12090                   MultiDrawElementsInstancedBaseVertexBaseInstanceCHROMIUM*>(
12091               cmd_data);
12092   if (!features().webgl_multi_draw_instanced_base_vertex_base_instance) {
12093     return error::kUnknownCommand;
12094   }
12095 
12096   GLenum mode = static_cast<GLenum>(c.mode);
12097   GLenum type = static_cast<GLenum>(c.type);
12098   GLsizei drawcount = static_cast<GLsizei>(c.drawcount);
12099 
12100   uint32_t counts_size, offsets_size, instance_counts_size, basevertices_size,
12101       baseinstances_size;
12102   base::CheckedNumeric<uint32_t> checked_size(drawcount);
12103   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&counts_size)) {
12104     return error::kOutOfBounds;
12105   }
12106   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&offsets_size)) {
12107     return error::kOutOfBounds;
12108   }
12109   if (!(checked_size * sizeof(GLsizei)).AssignIfValid(&instance_counts_size)) {
12110     return error::kOutOfBounds;
12111   }
12112   if (!(checked_size * sizeof(GLint)).AssignIfValid(&basevertices_size)) {
12113     return error::kOutOfBounds;
12114   }
12115   if (!(checked_size * sizeof(GLuint)).AssignIfValid(&baseinstances_size)) {
12116     return error::kOutOfBounds;
12117   }
12118   const GLsizei* counts = GetSharedMemoryAs<const GLsizei*>(
12119       c.counts_shm_id, c.counts_shm_offset, counts_size);
12120   const GLsizei* offsets = GetSharedMemoryAs<const GLsizei*>(
12121       c.offsets_shm_id, c.offsets_shm_offset, offsets_size);
12122   const GLsizei* instance_counts = GetSharedMemoryAs<const GLsizei*>(
12123       c.instance_counts_shm_id, c.instance_counts_shm_offset,
12124       instance_counts_size);
12125   const GLint* basevertices = GetSharedMemoryAs<const GLint*>(
12126       c.basevertices_shm_id, c.basevertices_shm_offset, basevertices_size);
12127   const GLuint* baseinstances = GetSharedMemoryAs<const GLuint*>(
12128       c.baseinstances_shm_id, c.baseinstances_shm_offset, baseinstances_size);
12129   if (counts == nullptr) {
12130     return error::kOutOfBounds;
12131   }
12132   if (offsets == nullptr) {
12133     return error::kOutOfBounds;
12134   }
12135   if (instance_counts == nullptr) {
12136     return error::kOutOfBounds;
12137   }
12138   if (basevertices == nullptr) {
12139     return error::kOutOfBounds;
12140   }
12141   if (baseinstances == nullptr) {
12142     return error::kOutOfBounds;
12143   }
12144   if (!multi_draw_manager_->MultiDrawElementsInstancedBaseVertexBaseInstance(
12145           mode, counts, type, offsets, instance_counts, basevertices,
12146           baseinstances, drawcount)) {
12147     return error::kInvalidArguments;
12148   }
12149   return error::kNoError;
12150 }
12151 
DoGetMaxValueInBufferCHROMIUM(GLuint buffer_id,GLsizei count,GLenum type,GLuint offset)12152 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
12153     GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
12154   GLuint max_vertex_accessed = 0;
12155   Buffer* buffer = GetBuffer(buffer_id);
12156   if (!buffer) {
12157     // TODO(gman): Should this be a GL error or a command buffer error?
12158     LOCAL_SET_GL_ERROR(
12159         GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
12160   } else {
12161     // The max value is used here to emulate client-side vertex
12162     // arrays, by uploading enough vertices into buffer objects to
12163     // cover the DrawElements call. Baking the primitive restart bit
12164     // into this result isn't strictly correct in all cases; the
12165     // client side code should pass down the bit and decide how to use
12166     // the result. However, the only caller makes the draw call
12167     // immediately afterward, so the state won't change between this
12168     // query and the draw call.
12169     if (!buffer->GetMaxValueForRange(
12170             offset, count, type,
12171             state_.enable_flags.primitive_restart_fixed_index,
12172             &max_vertex_accessed)) {
12173       // TODO(gman): Should this be a GL error or a command buffer error?
12174       LOCAL_SET_GL_ERROR(
12175           GL_INVALID_OPERATION,
12176           "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
12177     }
12178   }
12179   return max_vertex_accessed;
12180 }
12181 
DoShaderSource(GLuint client_id,GLsizei count,const char ** data,const GLint * length)12182 void GLES2DecoderImpl::DoShaderSource(
12183     GLuint client_id, GLsizei count, const char** data, const GLint* length) {
12184   std::string str;
12185   for (GLsizei ii = 0; ii < count; ++ii) {
12186     if (length && length[ii] > 0)
12187       str.append(data[ii], length[ii]);
12188     else
12189       str.append(data[ii]);
12190   }
12191   Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
12192   if (!shader) {
12193     return;
12194   }
12195   // Note: We don't actually call glShaderSource here. We wait until
12196   // we actually compile the shader.
12197   shader->set_source(str);
12198 }
12199 
DoTransformFeedbackVaryings(GLuint client_program_id,GLsizei count,const char * const * varyings,GLenum buffer_mode)12200 void GLES2DecoderImpl::DoTransformFeedbackVaryings(
12201     GLuint client_program_id, GLsizei count, const char* const* varyings,
12202     GLenum buffer_mode) {
12203   Program* program = GetProgramInfoNotShader(
12204       client_program_id, "glTransformFeedbackVaryings");
12205   if (!program) {
12206     return;
12207   }
12208   program->TransformFeedbackVaryings(count, varyings, buffer_mode);
12209 }
12210 
GetTranslator(GLenum type)12211 scoped_refptr<ShaderTranslatorInterface> GLES2DecoderImpl::GetTranslator(
12212     GLenum type) {
12213   return type == GL_VERTEX_SHADER ? vertex_translator_ : fragment_translator_;
12214 }
12215 
12216 scoped_refptr<ShaderTranslatorInterface>
GetOrCreateTranslator(GLenum type)12217 GLES2DecoderImpl::GetOrCreateTranslator(GLenum type) {
12218   if (!InitializeShaderTranslator()) {
12219     return nullptr;
12220   }
12221   return GetTranslator(type);
12222 }
12223 
DoCompileShader(GLuint client_id)12224 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
12225   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
12226   Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
12227   if (!shader) {
12228     return;
12229   }
12230 
12231   scoped_refptr<ShaderTranslatorInterface> translator;
12232   if (!feature_info_->disable_shader_translator())
12233     translator = GetOrCreateTranslator(shader->shader_type());
12234 
12235   const Shader::TranslatedShaderSourceType source_type =
12236       feature_info_->feature_flags().angle_translated_shader_source ?
12237       Shader::kANGLE : Shader::kGL;
12238   shader->RequestCompile(translator, source_type);
12239 }
12240 
DoGetShaderiv(GLuint shader_id,GLenum pname,GLint * params,GLsizei params_size)12241 void GLES2DecoderImpl::DoGetShaderiv(GLuint shader_id,
12242                                      GLenum pname,
12243                                      GLint* params,
12244                                      GLsizei params_size) {
12245   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
12246   if (!shader) {
12247     return;
12248   }
12249 
12250   if (pname == GL_COMPILE_STATUS) {
12251     if (shader->HasCompiled()) {
12252       *params = compile_shader_always_succeeds_ ? true : shader->valid();
12253       return;
12254     }
12255     // Lookup if there is compiled shader cache
12256     if (program_manager()->HasCachedCompileStatus(shader)) {
12257       // Only successful compile is cached
12258       // Fail-to-compile shader is not cached as needs compiling
12259       // to get log info
12260       *params = true;
12261       return;
12262     }
12263   }
12264 
12265   // Compile now for statuses that require it.
12266   switch (pname) {
12267     case GL_COMPILE_STATUS:
12268     case GL_INFO_LOG_LENGTH:
12269     case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
12270       CompileShaderAndExitCommandProcessingEarly(shader);
12271       break;
12272 
12273     default:
12274     break;
12275   }
12276 
12277   switch (pname) {
12278     case GL_SHADER_SOURCE_LENGTH:
12279       *params = shader->source().size();
12280       if (*params)
12281         ++(*params);
12282       return;
12283     case GL_COMPILE_STATUS:
12284       *params = compile_shader_always_succeeds_ ? true : shader->valid();
12285       return;
12286     case GL_INFO_LOG_LENGTH:
12287       *params = shader->log_info().size();
12288       if (*params)
12289         ++(*params);
12290       return;
12291     case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
12292       *params = shader->translated_source().size();
12293       if (*params)
12294         ++(*params);
12295       return;
12296     default:
12297       break;
12298   }
12299   api()->glGetShaderivFn(shader->service_id(), pname, params);
12300 }
12301 
HandleGetShaderSource(uint32_t immediate_data_size,const volatile void * cmd_data)12302 error::Error GLES2DecoderImpl::HandleGetShaderSource(
12303     uint32_t immediate_data_size,
12304     const volatile void* cmd_data) {
12305   const volatile gles2::cmds::GetShaderSource& c =
12306       *static_cast<const volatile gles2::cmds::GetShaderSource*>(cmd_data);
12307   GLuint shader_id = c.shader;
12308   uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
12309   Bucket* bucket = CreateBucket(bucket_id);
12310   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
12311   if (!shader || shader->source().empty()) {
12312     bucket->SetSize(0);
12313     return error::kNoError;
12314   }
12315   bucket->SetFromString(shader->source().c_str());
12316   return error::kNoError;
12317 }
12318 
HandleGetTranslatedShaderSourceANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)12319 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
12320     uint32_t immediate_data_size,
12321     const volatile void* cmd_data) {
12322   const volatile gles2::cmds::GetTranslatedShaderSourceANGLE& c =
12323       *static_cast<const volatile gles2::cmds::GetTranslatedShaderSourceANGLE*>(
12324           cmd_data);
12325   GLuint shader_id = c.shader;
12326   uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
12327   Bucket* bucket = CreateBucket(bucket_id);
12328   Shader* shader = GetShaderInfoNotProgram(
12329       shader_id, "glGetTranslatedShaderSourceANGLE");
12330   if (!shader) {
12331     bucket->SetSize(0);
12332     return error::kNoError;
12333   }
12334 
12335   // Make sure translator has been utilized in compile.
12336   CompileShaderAndExitCommandProcessingEarly(shader);
12337 
12338   bucket->SetFromString(shader->translated_source().c_str());
12339   return error::kNoError;
12340 }
12341 
HandleGetProgramInfoLog(uint32_t immediate_data_size,const volatile void * cmd_data)12342 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
12343     uint32_t immediate_data_size,
12344     const volatile void* cmd_data) {
12345   const volatile gles2::cmds::GetProgramInfoLog& c =
12346       *static_cast<const volatile gles2::cmds::GetProgramInfoLog*>(cmd_data);
12347   GLuint program_id = c.program;
12348   uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
12349   Bucket* bucket = CreateBucket(bucket_id);
12350   Program* program = GetProgramInfoNotShader(
12351       program_id, "glGetProgramInfoLog");
12352   if (!program || !program->log_info()) {
12353     bucket->SetFromString("");
12354     return error::kNoError;
12355   }
12356   bucket->SetFromString(program->log_info()->c_str());
12357   return error::kNoError;
12358 }
12359 
HandleGetShaderInfoLog(uint32_t immediate_data_size,const volatile void * cmd_data)12360 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
12361     uint32_t immediate_data_size,
12362     const volatile void* cmd_data) {
12363   const volatile gles2::cmds::GetShaderInfoLog& c =
12364       *static_cast<const volatile gles2::cmds::GetShaderInfoLog*>(cmd_data);
12365   GLuint shader_id = c.shader;
12366   uint32_t bucket_id = static_cast<uint32_t>(c.bucket_id);
12367   Bucket* bucket = CreateBucket(bucket_id);
12368   Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
12369   if (!shader) {
12370     bucket->SetFromString("");
12371     return error::kNoError;
12372   }
12373 
12374   // Shader must be compiled in order to get the info log.
12375   CompileShaderAndExitCommandProcessingEarly(shader);
12376 
12377   bucket->SetFromString(shader->log_info().c_str());
12378   return error::kNoError;
12379 }
12380 
DoIsEnabled(GLenum cap)12381 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
12382   return state_.GetEnabled(cap);
12383 }
12384 
DoIsBuffer(GLuint client_id)12385 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
12386   const Buffer* buffer = GetBuffer(client_id);
12387   return buffer && buffer->IsValid() && !buffer->IsDeleted();
12388 }
12389 
DoIsFramebuffer(GLuint client_id)12390 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
12391   const Framebuffer* framebuffer =
12392       GetFramebuffer(client_id);
12393   return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
12394 }
12395 
DoIsProgram(GLuint client_id)12396 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
12397   // IsProgram is true for programs as soon as they are created, until they are
12398   // deleted and no longer in use.
12399   const Program* program = GetProgram(client_id);
12400   return program != nullptr && !program->IsDeleted();
12401 }
12402 
DoIsRenderbuffer(GLuint client_id)12403 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
12404   const Renderbuffer* renderbuffer =
12405       GetRenderbuffer(client_id);
12406   return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
12407 }
12408 
DoIsShader(GLuint client_id)12409 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
12410   // IsShader is true for shaders as soon as they are created, until they
12411   // are deleted and not attached to any programs.
12412   const Shader* shader = GetShader(client_id);
12413   return shader != nullptr && !shader->IsDeleted();
12414 }
12415 
DoIsTexture(GLuint client_id)12416 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
12417   const TextureRef* texture_ref = GetTexture(client_id);
12418   return texture_ref && texture_ref->texture()->IsValid();
12419 }
12420 
DoIsSampler(GLuint client_id)12421 bool GLES2DecoderImpl::DoIsSampler(GLuint client_id) {
12422   const Sampler* sampler = GetSampler(client_id);
12423   return sampler && !sampler->IsDeleted();
12424 }
12425 
DoIsTransformFeedback(GLuint client_id)12426 bool GLES2DecoderImpl::DoIsTransformFeedback(GLuint client_id) {
12427   const TransformFeedback* transform_feedback =
12428       GetTransformFeedback(client_id);
12429   return transform_feedback && transform_feedback->has_been_bound();
12430 }
12431 
DoAttachShader(GLuint program_client_id,GLint shader_client_id)12432 void GLES2DecoderImpl::DoAttachShader(
12433     GLuint program_client_id, GLint shader_client_id) {
12434   Program* program = GetProgramInfoNotShader(
12435       program_client_id, "glAttachShader");
12436   if (!program) {
12437     return;
12438   }
12439   Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
12440   if (!shader) {
12441     return;
12442   }
12443   if (!program->AttachShader(shader_manager(), shader)) {
12444     LOCAL_SET_GL_ERROR(
12445         GL_INVALID_OPERATION,
12446         "glAttachShader",
12447         "can not attach more than one shader of the same type.");
12448     return;
12449   }
12450   api()->glAttachShaderFn(program->service_id(), shader->service_id());
12451 }
12452 
DoDetachShader(GLuint program_client_id,GLint shader_client_id)12453 void GLES2DecoderImpl::DoDetachShader(
12454     GLuint program_client_id, GLint shader_client_id) {
12455   Program* program = GetProgramInfoNotShader(
12456       program_client_id, "glDetachShader");
12457   if (!program) {
12458     return;
12459   }
12460   Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
12461   if (!shader) {
12462     return;
12463   }
12464   if (!program->IsShaderAttached(shader)) {
12465     LOCAL_SET_GL_ERROR(
12466         GL_INVALID_OPERATION,
12467         "glDetachShader", "shader not attached to program");
12468     return;
12469   }
12470   api()->glDetachShaderFn(program->service_id(), shader->service_id());
12471   program->DetachShader(shader_manager(), shader);
12472 }
12473 
DoValidateProgram(GLuint program_client_id)12474 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
12475   Program* program = GetProgramInfoNotShader(
12476       program_client_id, "glValidateProgram");
12477   if (!program) {
12478     return;
12479   }
12480   program->Validate();
12481 }
12482 
GetVertexAttribHelper(const VertexAttrib * attrib,GLenum pname,GLint * params)12483 void GLES2DecoderImpl::GetVertexAttribHelper(
12484     const VertexAttrib* attrib, GLenum pname, GLint* params) {
12485   switch (pname) {
12486     case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
12487       {
12488         Buffer* buffer = attrib->buffer();
12489         if (buffer && !buffer->IsDeleted()) {
12490           GLuint client_id;
12491           buffer_manager()->GetClientId(buffer->service_id(), &client_id);
12492           *params = client_id;
12493         }
12494         break;
12495       }
12496     case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
12497       *params = attrib->enabled();
12498       break;
12499     case GL_VERTEX_ATTRIB_ARRAY_SIZE:
12500       *params = attrib->size();
12501       break;
12502     case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
12503       *params = attrib->gl_stride();
12504       break;
12505     case GL_VERTEX_ATTRIB_ARRAY_TYPE:
12506       *params = attrib->type();
12507       break;
12508     case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
12509       *params = attrib->normalized();
12510       break;
12511     case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
12512       *params = attrib->divisor();
12513       break;
12514     case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
12515       *params = attrib->integer();
12516       break;
12517     default:
12518       NOTREACHED();
12519       break;
12520   }
12521 }
12522 
DoGetSamplerParameterfv(GLuint client_id,GLenum pname,GLfloat * params,GLsizei params_size)12523 void GLES2DecoderImpl::DoGetSamplerParameterfv(GLuint client_id,
12524                                                GLenum pname,
12525                                                GLfloat* params,
12526                                                GLsizei params_size) {
12527   Sampler* sampler = GetSampler(client_id);
12528   if (!sampler) {
12529     LOCAL_SET_GL_ERROR(
12530         GL_INVALID_OPERATION, "glGetSamplerParamterfv", "unknown sampler");
12531     return;
12532   }
12533   api()->glGetSamplerParameterfvFn(sampler->service_id(), pname, params);
12534 }
12535 
DoGetSamplerParameteriv(GLuint client_id,GLenum pname,GLint * params,GLsizei params_size)12536 void GLES2DecoderImpl::DoGetSamplerParameteriv(GLuint client_id,
12537                                                GLenum pname,
12538                                                GLint* params,
12539                                                GLsizei params_size) {
12540   Sampler* sampler = GetSampler(client_id);
12541   if (!sampler) {
12542     LOCAL_SET_GL_ERROR(
12543         GL_INVALID_OPERATION, "glGetSamplerParamteriv", "unknown sampler");
12544     return;
12545   }
12546   api()->glGetSamplerParameterivFn(sampler->service_id(), pname, params);
12547 }
12548 
GetTexParameterImpl(GLenum target,GLenum pname,GLfloat * fparams,GLint * iparams,const char * function_name)12549 void GLES2DecoderImpl::GetTexParameterImpl(
12550     GLenum target, GLenum pname, GLfloat* fparams, GLint* iparams,
12551     const char* function_name) {
12552   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12553       &state_, target);
12554   if (!texture_ref) {
12555     LOCAL_SET_GL_ERROR(
12556         GL_INVALID_OPERATION, function_name, "unknown texture for target");
12557     return;
12558   }
12559   Texture* texture = texture_ref->texture();
12560   switch (pname) {
12561     case GL_TEXTURE_MAX_ANISOTROPY_EXT:
12562       if (workarounds().init_texture_max_anisotropy) {
12563         texture->InitTextureMaxAnisotropyIfNeeded(target);
12564       }
12565       break;
12566     case GL_TEXTURE_IMMUTABLE_LEVELS:
12567       if (gl_version_info().IsLowerThanGL(4, 2)) {
12568         GLint levels = texture->GetImmutableLevels();
12569         if (fparams) {
12570           fparams[0] = static_cast<GLfloat>(levels);
12571         } else {
12572           iparams[0] = levels;
12573         }
12574         return;
12575       }
12576       break;
12577     case GL_TEXTURE_BASE_LEVEL:
12578       // Use shadowed value in case it's clamped; also because older MacOSX
12579       // stores the value on int16_t (see https://crbug.com/610153).
12580       if (fparams) {
12581         fparams[0] = static_cast<GLfloat>(texture->unclamped_base_level());
12582       } else {
12583         iparams[0] = texture->unclamped_base_level();
12584       }
12585       return;
12586     case GL_TEXTURE_MAX_LEVEL:
12587       // Use shadowed value in case it's clamped; also because older MacOSX
12588       // stores the value on int16_t (see https://crbug.com/610153).
12589       if (fparams) {
12590         fparams[0] = static_cast<GLfloat>(texture->unclamped_max_level());
12591       } else {
12592         iparams[0] = texture->unclamped_max_level();
12593       }
12594       return;
12595     case GL_TEXTURE_SWIZZLE_R:
12596       if (fparams) {
12597         fparams[0] = static_cast<GLfloat>(texture->swizzle_r());
12598       } else {
12599         iparams[0] = texture->swizzle_r();
12600       }
12601       return;
12602     case GL_TEXTURE_SWIZZLE_G:
12603       if (fparams) {
12604         fparams[0] = static_cast<GLfloat>(texture->swizzle_g());
12605       } else {
12606         iparams[0] = texture->swizzle_g();
12607       }
12608       return;
12609     case GL_TEXTURE_SWIZZLE_B:
12610       if (fparams) {
12611         fparams[0] = static_cast<GLfloat>(texture->swizzle_b());
12612       } else {
12613         iparams[0] = texture->swizzle_b();
12614       }
12615       return;
12616     case GL_TEXTURE_SWIZZLE_A:
12617       if (fparams) {
12618         fparams[0] = static_cast<GLfloat>(texture->swizzle_a());
12619       } else {
12620         iparams[0] = texture->swizzle_a();
12621       }
12622       return;
12623     default:
12624       break;
12625   }
12626   if (fparams) {
12627     api()->glGetTexParameterfvFn(target, pname, fparams);
12628   } else {
12629     api()->glGetTexParameterivFn(target, pname, iparams);
12630   }
12631 }
12632 
DoGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params,GLsizei params_size)12633 void GLES2DecoderImpl::DoGetTexParameterfv(GLenum target,
12634                                            GLenum pname,
12635                                            GLfloat* params,
12636                                            GLsizei params_size) {
12637   GetTexParameterImpl(target, pname, params, nullptr, "glGetTexParameterfv");
12638 }
12639 
DoGetTexParameteriv(GLenum target,GLenum pname,GLint * params,GLsizei params_size)12640 void GLES2DecoderImpl::DoGetTexParameteriv(GLenum target,
12641                                            GLenum pname,
12642                                            GLint* params,
12643                                            GLsizei params_size) {
12644   GetTexParameterImpl(target, pname, nullptr, params, "glGetTexParameteriv");
12645 }
12646 
12647 template <typename T>
DoGetVertexAttribImpl(GLuint index,GLenum pname,T * params)12648 void GLES2DecoderImpl::DoGetVertexAttribImpl(
12649     GLuint index, GLenum pname, T* params) {
12650   VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
12651   if (!attrib) {
12652     LOCAL_SET_GL_ERROR(
12653         GL_INVALID_VALUE, "glGetVertexAttrib", "index out of range");
12654     return;
12655   }
12656   switch (pname) {
12657     case GL_CURRENT_VERTEX_ATTRIB:
12658       state_.attrib_values[index].GetValues(params);
12659       break;
12660     default: {
12661       GLint value = 0;
12662       GetVertexAttribHelper(attrib, pname, &value);
12663       *params = static_cast<T>(value);
12664       break;
12665     }
12666   }
12667 }
12668 
DoGetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params,GLsizei params_size)12669 void GLES2DecoderImpl::DoGetVertexAttribfv(GLuint index,
12670                                            GLenum pname,
12671                                            GLfloat* params,
12672                                            GLsizei params_size) {
12673   DoGetVertexAttribImpl<GLfloat>(index, pname, params);
12674 }
12675 
DoGetVertexAttribiv(GLuint index,GLenum pname,GLint * params,GLsizei params_size)12676 void GLES2DecoderImpl::DoGetVertexAttribiv(GLuint index,
12677                                            GLenum pname,
12678                                            GLint* params,
12679                                            GLsizei params_size) {
12680   DoGetVertexAttribImpl<GLint>(index, pname, params);
12681 }
12682 
DoGetVertexAttribIiv(GLuint index,GLenum pname,GLint * params,GLsizei params_size)12683 void GLES2DecoderImpl::DoGetVertexAttribIiv(GLuint index,
12684                                             GLenum pname,
12685                                             GLint* params,
12686                                             GLsizei params_size) {
12687   DoGetVertexAttribImpl<GLint>(index, pname, params);
12688 }
12689 
DoGetVertexAttribIuiv(GLuint index,GLenum pname,GLuint * params,GLsizei params_size)12690 void GLES2DecoderImpl::DoGetVertexAttribIuiv(GLuint index,
12691                                              GLenum pname,
12692                                              GLuint* params,
12693                                              GLsizei params_size) {
12694   DoGetVertexAttribImpl<GLuint>(index, pname, params);
12695 }
12696 
12697 template <typename T>
SetVertexAttribValue(const char * function_name,GLuint index,const T * value)12698 bool GLES2DecoderImpl::SetVertexAttribValue(
12699     const char* function_name, GLuint index, const T* value) {
12700   if (index >= state_.attrib_values.size()) {
12701     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
12702     return false;
12703   }
12704   state_.attrib_values[index].SetValues(value);
12705   return true;
12706 }
12707 
DoVertexAttrib1f(GLuint index,GLfloat v0)12708 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
12709   GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
12710   if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
12711     state_.SetGenericVertexAttribBaseType(
12712         index, SHADER_VARIABLE_FLOAT);
12713     api()->glVertexAttrib1fFn(index, v0);
12714   }
12715 }
12716 
DoVertexAttrib2f(GLuint index,GLfloat v0,GLfloat v1)12717 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
12718   GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
12719   if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
12720     state_.SetGenericVertexAttribBaseType(
12721         index, SHADER_VARIABLE_FLOAT);
12722     api()->glVertexAttrib2fFn(index, v0, v1);
12723   }
12724 }
12725 
DoVertexAttrib3f(GLuint index,GLfloat v0,GLfloat v1,GLfloat v2)12726 void GLES2DecoderImpl::DoVertexAttrib3f(
12727     GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
12728   GLfloat v[4] = { v0, v1, v2, 1.0f, };
12729   if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
12730     state_.SetGenericVertexAttribBaseType(
12731         index, SHADER_VARIABLE_FLOAT);
12732     api()->glVertexAttrib3fFn(index, v0, v1, v2);
12733   }
12734 }
12735 
DoVertexAttrib4f(GLuint index,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)12736 void GLES2DecoderImpl::DoVertexAttrib4f(
12737     GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
12738   GLfloat v[4] = { v0, v1, v2, v3, };
12739   if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
12740     state_.SetGenericVertexAttribBaseType(
12741         index, SHADER_VARIABLE_FLOAT);
12742     api()->glVertexAttrib4fFn(index, v0, v1, v2, v3);
12743   }
12744 }
12745 
DoVertexAttrib1fv(GLuint index,const volatile GLfloat * v)12746 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index,
12747                                          const volatile GLfloat* v) {
12748   GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
12749   if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
12750     state_.SetGenericVertexAttribBaseType(
12751         index, SHADER_VARIABLE_FLOAT);
12752     api()->glVertexAttrib1fvFn(index, t);
12753   }
12754 }
12755 
DoVertexAttrib2fv(GLuint index,const volatile GLfloat * v)12756 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index,
12757                                          const volatile GLfloat* v) {
12758   GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
12759   if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
12760     state_.SetGenericVertexAttribBaseType(
12761         index, SHADER_VARIABLE_FLOAT);
12762     api()->glVertexAttrib2fvFn(index, t);
12763   }
12764 }
12765 
DoVertexAttrib3fv(GLuint index,const volatile GLfloat * v)12766 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index,
12767                                          const volatile GLfloat* v) {
12768   GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
12769   if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
12770     state_.SetGenericVertexAttribBaseType(
12771         index, SHADER_VARIABLE_FLOAT);
12772     api()->glVertexAttrib3fvFn(index, t);
12773   }
12774 }
12775 
DoVertexAttrib4fv(GLuint index,const volatile GLfloat * v)12776 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index,
12777                                          const volatile GLfloat* v) {
12778   GLfloat t[4] = {v[0], v[1], v[2], v[3]};
12779   if (SetVertexAttribValue("glVertexAttrib4fv", index, t)) {
12780     state_.SetGenericVertexAttribBaseType(
12781         index, SHADER_VARIABLE_FLOAT);
12782     api()->glVertexAttrib4fvFn(index, t);
12783   }
12784 }
12785 
DoVertexAttribI4i(GLuint index,GLint v0,GLint v1,GLint v2,GLint v3)12786 void GLES2DecoderImpl::DoVertexAttribI4i(
12787     GLuint index, GLint v0, GLint v1, GLint v2, GLint v3) {
12788   GLint v[4] = { v0, v1, v2, v3 };
12789   if (SetVertexAttribValue("glVertexAttribI4i", index, v)) {
12790     state_.SetGenericVertexAttribBaseType(
12791         index, SHADER_VARIABLE_INT);
12792     api()->glVertexAttribI4iFn(index, v0, v1, v2, v3);
12793   }
12794 }
12795 
DoVertexAttribI4iv(GLuint index,const volatile GLint * v)12796 void GLES2DecoderImpl::DoVertexAttribI4iv(GLuint index,
12797                                           const volatile GLint* v) {
12798   GLint t[4] = {v[0], v[1], v[2], v[3]};
12799   if (SetVertexAttribValue("glVertexAttribI4iv", index, t)) {
12800     state_.SetGenericVertexAttribBaseType(
12801         index, SHADER_VARIABLE_INT);
12802     api()->glVertexAttribI4ivFn(index, t);
12803   }
12804 }
12805 
DoVertexAttribI4ui(GLuint index,GLuint v0,GLuint v1,GLuint v2,GLuint v3)12806 void GLES2DecoderImpl::DoVertexAttribI4ui(
12807     GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
12808   GLuint v[4] = { v0, v1, v2, v3 };
12809   if (SetVertexAttribValue("glVertexAttribI4ui", index, v)) {
12810     state_.SetGenericVertexAttribBaseType(
12811         index, SHADER_VARIABLE_UINT);
12812     api()->glVertexAttribI4uiFn(index, v0, v1, v2, v3);
12813   }
12814 }
12815 
DoVertexAttribI4uiv(GLuint index,const volatile GLuint * v)12816 void GLES2DecoderImpl::DoVertexAttribI4uiv(GLuint index,
12817                                            const volatile GLuint* v) {
12818   GLuint t[4] = {v[0], v[1], v[2], v[3]};
12819   if (SetVertexAttribValue("glVertexAttribI4uiv", index, t)) {
12820     state_.SetGenericVertexAttribBaseType(
12821         index, SHADER_VARIABLE_UINT);
12822     api()->glVertexAttribI4uivFn(index, t);
12823   }
12824 }
12825 
HandleVertexAttribIPointer(uint32_t immediate_data_size,const volatile void * cmd_data)12826 error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
12827     uint32_t immediate_data_size,
12828     const volatile void* cmd_data) {
12829   if (!feature_info_->IsWebGL2OrES3Context())
12830     return error::kUnknownCommand;
12831   const volatile gles2::cmds::VertexAttribIPointer& c =
12832       *static_cast<const volatile gles2::cmds::VertexAttribIPointer*>(cmd_data);
12833   GLuint indx = c.indx;
12834   GLint size = c.size;
12835   GLenum type = c.type;
12836   GLsizei stride = c.stride;
12837   GLsizei offset = c.offset;
12838 
12839   if (!state_.bound_array_buffer.get() ||
12840       state_.bound_array_buffer->IsDeleted()) {
12841     if (offset != 0) {
12842       LOCAL_SET_GL_ERROR(
12843           GL_INVALID_OPERATION, "glVertexAttribIPointer", "offset != 0");
12844       return error::kNoError;
12845     }
12846   }
12847 
12848   const void* ptr = reinterpret_cast<const void*>(offset);
12849   if (!validators_->vertex_attrib_i_type.IsValid(type)) {
12850     LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribIPointer", type, "type");
12851     return error::kNoError;
12852   }
12853   if (size < 1 || size > 4) {
12854     LOCAL_SET_GL_ERROR(
12855         GL_INVALID_VALUE, "glVertexAttribIPointer", "size GL_INVALID_VALUE");
12856     return error::kNoError;
12857   }
12858   if (indx >= group_->max_vertex_attribs()) {
12859     LOCAL_SET_GL_ERROR(
12860         GL_INVALID_VALUE, "glVertexAttribIPointer", "index out of range");
12861     return error::kNoError;
12862   }
12863   if (stride < 0) {
12864     LOCAL_SET_GL_ERROR(
12865         GL_INVALID_VALUE, "glVertexAttribIPointer", "stride < 0");
12866     return error::kNoError;
12867   }
12868   if (stride > 255) {
12869     LOCAL_SET_GL_ERROR(
12870         GL_INVALID_VALUE, "glVertexAttribIPointer", "stride > 255");
12871     return error::kNoError;
12872   }
12873   if (offset < 0) {
12874     LOCAL_SET_GL_ERROR(
12875         GL_INVALID_VALUE, "glVertexAttribIPointer", "offset < 0");
12876     return error::kNoError;
12877   }
12878   uint32_t type_size = GLES2Util::GetGLTypeSizeForBuffers(type);
12879   // type_size must be a power of two to use & as optimized modulo.
12880   DCHECK(GLES2Util::IsPOT(type_size));
12881   if (offset & (type_size - 1)) {
12882     LOCAL_SET_GL_ERROR(
12883         GL_INVALID_OPERATION,
12884         "glVertexAttribIPointer", "offset not valid for type");
12885     return error::kNoError;
12886   }
12887   if (stride & (type_size - 1)) {
12888     LOCAL_SET_GL_ERROR(
12889         GL_INVALID_OPERATION,
12890         "glVertexAttribIPointer", "stride not valid for type");
12891     return error::kNoError;
12892   }
12893 
12894   GLenum base_type = (type == GL_BYTE || type == GL_SHORT || type == GL_INT) ?
12895                       SHADER_VARIABLE_INT : SHADER_VARIABLE_UINT;
12896   state_.vertex_attrib_manager->UpdateAttribBaseTypeAndMask(indx, base_type);
12897 
12898   uint32_t group_size = GLES2Util::GetGroupSizeForBufferType(size, type);
12899   DCHECK_LE(group_size, static_cast<uint32_t>(INT_MAX));
12900   state_.vertex_attrib_manager
12901       ->SetAttribInfo(indx,
12902                       state_.bound_array_buffer.get(),
12903                       size,
12904                       type,
12905                       GL_FALSE,
12906                       stride,
12907                       stride != 0 ? stride : group_size,
12908                       offset,
12909                       GL_TRUE);
12910   api()->glVertexAttribIPointerFn(indx, size, type, stride, ptr);
12911   return error::kNoError;
12912 }
12913 
HandleVertexAttribPointer(uint32_t immediate_data_size,const volatile void * cmd_data)12914 error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
12915     uint32_t immediate_data_size,
12916     const volatile void* cmd_data) {
12917   const volatile gles2::cmds::VertexAttribPointer& c =
12918       *static_cast<const volatile gles2::cmds::VertexAttribPointer*>(cmd_data);
12919   GLuint indx = c.indx;
12920   GLint size = c.size;
12921   GLenum type = c.type;
12922   GLboolean normalized = static_cast<GLboolean>(c.normalized);
12923   GLsizei stride = c.stride;
12924   GLsizei offset = c.offset;
12925 
12926   if (!state_.bound_array_buffer.get() ||
12927       state_.bound_array_buffer->IsDeleted()) {
12928     if (offset != 0) {
12929       LOCAL_SET_GL_ERROR(
12930           GL_INVALID_OPERATION, "glVertexAttribPointer", "offset != 0");
12931       return error::kNoError;
12932     }
12933   }
12934   const void* ptr = reinterpret_cast<const void*>(offset);
12935   if (!validators_->vertex_attrib_type.IsValid(type)) {
12936     LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
12937     return error::kNoError;
12938   }
12939   if (size < 1 || size > 4) {
12940     LOCAL_SET_GL_ERROR(
12941         GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
12942     return error::kNoError;
12943   }
12944   if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV)
12945       && size != 4) {
12946     LOCAL_SET_GL_ERROR(
12947         GL_INVALID_OPERATION, "glVertexAttribPointer", "size != 4");
12948     return error::kNoError;
12949   }
12950   if (indx >= group_->max_vertex_attribs()) {
12951     LOCAL_SET_GL_ERROR(
12952         GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
12953     return error::kNoError;
12954   }
12955   if (stride < 0) {
12956     LOCAL_SET_GL_ERROR(
12957         GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
12958     return error::kNoError;
12959   }
12960   if (stride > 255) {
12961     LOCAL_SET_GL_ERROR(
12962         GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
12963     return error::kNoError;
12964   }
12965   if (offset < 0) {
12966     LOCAL_SET_GL_ERROR(
12967         GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
12968     return error::kNoError;
12969   }
12970   uint32_t type_size = GLES2Util::GetGLTypeSizeForBuffers(type);
12971   // type_size must be a power of two to use & as optimized modulo.
12972   DCHECK(GLES2Util::IsPOT(type_size));
12973   if (offset & (type_size - 1)) {
12974     LOCAL_SET_GL_ERROR(
12975         GL_INVALID_OPERATION,
12976         "glVertexAttribPointer", "offset not valid for type");
12977     return error::kNoError;
12978   }
12979   if (stride & (type_size - 1)) {
12980     LOCAL_SET_GL_ERROR(
12981         GL_INVALID_OPERATION,
12982         "glVertexAttribPointer", "stride not valid for type");
12983     return error::kNoError;
12984   }
12985 
12986   state_.vertex_attrib_manager->UpdateAttribBaseTypeAndMask(
12987       indx, SHADER_VARIABLE_FLOAT);
12988 
12989   uint32_t group_size = GLES2Util::GetGroupSizeForBufferType(size, type);
12990   DCHECK_LE(group_size, static_cast<uint32_t>(INT_MAX));
12991   state_.vertex_attrib_manager
12992       ->SetAttribInfo(indx,
12993                       state_.bound_array_buffer.get(),
12994                       size,
12995                       type,
12996                       normalized,
12997                       stride,
12998                       stride != 0 ? stride : group_size,
12999                       offset,
13000                       GL_FALSE);
13001   if (type != GL_FIXED || gl_version_info().SupportsFixedType()) {
13002     api()->glVertexAttribPointerFn(indx, size, type, normalized, stride, ptr);
13003   }
13004   return error::kNoError;
13005 }
13006 
DoViewport(GLint x,GLint y,GLsizei width,GLsizei height)13007 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
13008                                   GLsizei height) {
13009   state_.viewport_x = x;
13010   state_.viewport_y = y;
13011   state_.viewport_width = std::min(width, viewport_max_width_);
13012   state_.viewport_height = std::min(height, viewport_max_height_);
13013   gfx::Vector2d viewport_offset = GetBoundFramebufferDrawOffset();
13014   api()->glViewportFn(x + viewport_offset.x(), y + viewport_offset.y(), width,
13015                       height);
13016 }
13017 
DoScissor(GLint x,GLint y,GLsizei width,GLsizei height)13018 void GLES2DecoderImpl::DoScissor(GLint x,
13019                                  GLint y,
13020                                  GLsizei width,
13021                                  GLsizei height) {
13022   gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset();
13023   api()->glScissorFn(x + draw_offset.x(), y + draw_offset.y(), width, height);
13024 }
13025 
HandleVertexAttribDivisorANGLE(uint32_t immediate_data_size,const volatile void * cmd_data)13026 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
13027     uint32_t immediate_data_size,
13028     const volatile void* cmd_data) {
13029   const volatile gles2::cmds::VertexAttribDivisorANGLE& c =
13030       *static_cast<const volatile gles2::cmds::VertexAttribDivisorANGLE*>(
13031           cmd_data);
13032   if (!features().angle_instanced_arrays)
13033     return error::kUnknownCommand;
13034 
13035   GLuint index = c.index;
13036   GLuint divisor = c.divisor;
13037   if (index >= group_->max_vertex_attribs()) {
13038     LOCAL_SET_GL_ERROR(
13039         GL_INVALID_VALUE,
13040         "glVertexAttribDivisorANGLE", "index out of range");
13041     return error::kNoError;
13042   }
13043 
13044   state_.vertex_attrib_manager->SetDivisor(
13045       index,
13046       divisor);
13047   api()->glVertexAttribDivisorANGLEFn(index, divisor);
13048   return error::kNoError;
13049 }
13050 
13051 template <typename pixel_data_type>
WriteAlphaData(void * pixels,uint32_t row_count,uint32_t channel_count,uint32_t alpha_channel_index,uint32_t unpadded_row_size,uint32_t padded_row_size,pixel_data_type alpha_value)13052 static void WriteAlphaData(void* pixels,
13053                            uint32_t row_count,
13054                            uint32_t channel_count,
13055                            uint32_t alpha_channel_index,
13056                            uint32_t unpadded_row_size,
13057                            uint32_t padded_row_size,
13058                            pixel_data_type alpha_value) {
13059   DCHECK_GT(channel_count, 0U);
13060   DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
13061   uint32_t unpadded_row_size_in_elements =
13062       unpadded_row_size / sizeof(pixel_data_type);
13063   DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
13064   uint32_t padded_row_size_in_elements =
13065       padded_row_size / sizeof(pixel_data_type);
13066   pixel_data_type* dst =
13067       static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
13068   for (uint32_t yy = 0; yy < row_count; ++yy) {
13069     pixel_data_type* end = dst + unpadded_row_size_in_elements;
13070     for (pixel_data_type* d = dst; d < end; d += channel_count) {
13071       *d = alpha_value;
13072     }
13073     dst += padded_row_size_in_elements;
13074   }
13075 }
13076 
FinishReadPixels(GLsizei width,GLsizei height,GLsizei format,GLsizei type,uint32_t pixels_shm_id,uint32_t pixels_shm_offset,uint32_t result_shm_id,uint32_t result_shm_offset,GLint pack_alignment,GLenum read_format,GLuint buffer)13077 void GLES2DecoderImpl::FinishReadPixels(GLsizei width,
13078                                         GLsizei height,
13079                                         GLsizei format,
13080                                         GLsizei type,
13081                                         uint32_t pixels_shm_id,
13082                                         uint32_t pixels_shm_offset,
13083                                         uint32_t result_shm_id,
13084                                         uint32_t result_shm_offset,
13085                                         GLint pack_alignment,
13086                                         GLenum read_format,
13087                                         GLuint buffer) {
13088   TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
13089   typedef cmds::ReadPixels::Result Result;
13090   uint32_t pixels_size;
13091   Result* result = nullptr;
13092   if (result_shm_id != 0) {
13093     result = GetSharedMemoryAs<Result*>(result_shm_id, result_shm_offset,
13094                                         sizeof(*result));
13095     if (!result) {
13096       if (buffer != 0) {
13097         api()->glDeleteBuffersARBFn(1, &buffer);
13098       }
13099       return;
13100     }
13101   }
13102   GLES2Util::ComputeImageDataSizes(width, height, 1, format, type,
13103                                    pack_alignment, &pixels_size, nullptr,
13104                                    nullptr);
13105   void* pixels =
13106       GetSharedMemoryAs<void*>(pixels_shm_id, pixels_shm_offset, pixels_size);
13107   if (!pixels) {
13108     if (buffer != 0) {
13109       api()->glDeleteBuffersARBFn(1, &buffer);
13110     }
13111     return;
13112   }
13113 
13114   if (buffer != 0) {
13115     api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, buffer);
13116     void* data;
13117     if (features().map_buffer_range) {
13118       data = api()->glMapBufferRangeFn(GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size,
13119                                        GL_MAP_READ_BIT);
13120     } else {
13121       data = api()->glMapBufferFn(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
13122     }
13123     if (!data) {
13124       LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
13125                          "Unable to map memory for readback.");
13126       return;
13127     }
13128     memcpy(pixels, data, pixels_size);
13129     api()->glUnmapBufferFn(GL_PIXEL_PACK_BUFFER_ARB);
13130     api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB,
13131                           GetServiceId(state_.bound_pixel_pack_buffer.get()));
13132     api()->glDeleteBuffersARBFn(1, &buffer);
13133   }
13134 
13135   if (result != nullptr) {
13136     result->success = 1;
13137   }
13138 }
13139 
HandleReadPixels(uint32_t immediate_data_size,const volatile void * cmd_data)13140 error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
13141                                                 const volatile void* cmd_data) {
13142   const char* func_name = "glReadPixels";
13143   const volatile gles2::cmds::ReadPixels& c =
13144       *static_cast<const volatile gles2::cmds::ReadPixels*>(cmd_data);
13145   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
13146   error::Error fbo_error = WillAccessBoundFramebufferForRead();
13147   if (fbo_error != error::kNoError)
13148     return fbo_error;
13149   GLint x = c.x;
13150   GLint y = c.y;
13151   GLsizei width = c.width;
13152   GLsizei height = c.height;
13153   GLenum format = c.format;
13154   GLenum type = c.type;
13155   uint32_t pixels_shm_id = c.pixels_shm_id;
13156   uint32_t pixels_shm_offset = c.pixels_shm_offset;
13157   uint32_t result_shm_id = c.result_shm_id;
13158   uint32_t result_shm_offset = c.result_shm_offset;
13159   GLboolean async = static_cast<GLboolean>(c.async);
13160   if (width < 0 || height < 0) {
13161     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
13162     return error::kNoError;
13163   }
13164   typedef cmds::ReadPixels::Result Result;
13165 
13166   PixelStoreParams params;
13167   if (pixels_shm_id == 0) {
13168     params = state_.GetPackParams();
13169   } else {
13170     // When reading into client buffer, we actually set pack parameters to 0
13171     // (except for alignment) before calling glReadPixels. This makes sure we
13172     // only send back meaningful pixel data to the command buffer client side,
13173     // and the client side will take the responsibility to take the pixels and
13174     // write to the client buffer according to the full ES3 pack parameters.
13175     params.alignment = state_.pack_alignment;
13176   }
13177   uint32_t pixels_size = 0;
13178   uint32_t unpadded_row_size = 0;
13179   uint32_t padded_row_size = 0;
13180   uint32_t skip_size = 0;
13181   uint32_t padding = 0;
13182   if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1,
13183                                            format, type,
13184                                            params,
13185                                            &pixels_size,
13186                                            &unpadded_row_size,
13187                                            &padded_row_size,
13188                                            &skip_size,
13189                                            &padding)) {
13190     return error::kOutOfBounds;
13191   }
13192 
13193   uint8_t* pixels = nullptr;
13194   Buffer* buffer = state_.bound_pixel_pack_buffer.get();
13195   if (pixels_shm_id == 0) {
13196     if (!buffer) {
13197       return error::kInvalidArguments;
13198     }
13199     if (!buffer_manager()->RequestBufferAccess(
13200             error_state_.get(), buffer, func_name, "pixel pack buffer")) {
13201       return error::kNoError;
13202     }
13203     uint32_t size = 0;
13204     if (!base::CheckAdd(pixels_size + skip_size, pixels_shm_offset)
13205              .AssignIfValid(&size)) {
13206       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "size + offset overflow");
13207       return error::kNoError;
13208     }
13209     if (static_cast<uint32_t>(buffer->size()) < size) {
13210       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
13211                          "pixel pack buffer is not large enough");
13212       return error::kNoError;
13213     }
13214     pixels = reinterpret_cast<uint8_t *>(pixels_shm_offset);
13215     pixels += skip_size;
13216   } else {
13217     if (buffer) {
13218       return error::kInvalidArguments;
13219     }
13220     DCHECK_EQ(0u, skip_size);
13221     pixels = GetSharedMemoryAs<uint8_t*>(
13222         pixels_shm_id, pixels_shm_offset, pixels_size);
13223     if (!pixels) {
13224       return error::kOutOfBounds;
13225     }
13226   }
13227 
13228   Result* result = nullptr;
13229   if (result_shm_id != 0) {
13230     result = GetSharedMemoryAs<Result*>(
13231         result_shm_id, result_shm_offset, sizeof(*result));
13232     if (!result) {
13233       return error::kOutOfBounds;
13234     }
13235     if (result->success != 0) {
13236       return error::kInvalidArguments;
13237     }
13238   }
13239 
13240   if (!validators_->read_pixel_format.IsValid(format)) {
13241     LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format");
13242     return error::kNoError;
13243   }
13244   if (!validators_->read_pixel_type.IsValid(type)) {
13245     LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, type, "type");
13246     return error::kNoError;
13247   }
13248 
13249   if (!CheckBoundReadFramebufferValid(
13250           func_name, GL_INVALID_FRAMEBUFFER_OPERATION)) {
13251     return error::kNoError;
13252   }
13253   GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
13254   if (src_internal_format == 0) {
13255     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no valid color image");
13256     return error::kNoError;
13257   }
13258   std::vector<GLenum> accepted_formats;
13259   std::vector<GLenum> accepted_types;
13260   switch (src_internal_format) {
13261     case GL_R8UI:
13262     case GL_R16UI:
13263     case GL_R32UI:
13264     case GL_RG8UI:
13265     case GL_RG16UI:
13266     case GL_RG32UI:
13267     // All the RGB_INTEGER formats are not renderable.
13268     case GL_RGBA8UI:
13269     case GL_RGB10_A2UI:
13270     case GL_RGBA16UI:
13271     case GL_RGBA32UI:
13272       accepted_formats.push_back(GL_RGBA_INTEGER);
13273       accepted_types.push_back(GL_UNSIGNED_INT);
13274       break;
13275     case GL_R8I:
13276     case GL_R16I:
13277     case GL_R32I:
13278     case GL_RG8I:
13279     case GL_RG16I:
13280     case GL_RG32I:
13281     case GL_RGBA8I:
13282     case GL_RGBA16I:
13283     case GL_RGBA32I:
13284       accepted_formats.push_back(GL_RGBA_INTEGER);
13285       accepted_types.push_back(GL_INT);
13286       break;
13287     case GL_RGB10_A2:
13288       accepted_formats.push_back(GL_RGBA);
13289       accepted_types.push_back(GL_UNSIGNED_BYTE);
13290       // Special case with an extra supported format/type.
13291       accepted_formats.push_back(GL_RGBA);
13292       accepted_types.push_back(GL_UNSIGNED_INT_2_10_10_10_REV);
13293       break;
13294     case GL_R16_EXT:
13295     case GL_RG16_EXT:
13296     case GL_RGBA16_EXT:
13297       accepted_formats.push_back(GL_RGBA);
13298       accepted_types.push_back(GL_UNSIGNED_SHORT);
13299       break;
13300     default:
13301       accepted_formats.push_back(GL_RGBA);
13302       {
13303         GLenum src_type = GetBoundReadFramebufferTextureType();
13304         switch (src_type) {
13305           case GL_HALF_FLOAT:
13306           case GL_HALF_FLOAT_OES:
13307           case GL_FLOAT:
13308           case GL_UNSIGNED_INT_10F_11F_11F_REV:
13309             accepted_types.push_back(GL_FLOAT);
13310             break;
13311           default:
13312             accepted_types.push_back(GL_UNSIGNED_BYTE);
13313             break;
13314         }
13315       }
13316       break;
13317   }
13318   if (!feature_info_->IsWebGLContext()) {
13319     accepted_formats.push_back(GL_BGRA_EXT);
13320     accepted_types.push_back(GL_UNSIGNED_BYTE);
13321   }
13322   DCHECK_EQ(accepted_formats.size(), accepted_types.size());
13323   bool format_type_acceptable = false;
13324   for (size_t ii = 0; ii < accepted_formats.size(); ++ii) {
13325     if (format == accepted_formats[ii] && type == accepted_types[ii]) {
13326       format_type_acceptable = true;
13327       break;
13328     }
13329   }
13330   if (!format_type_acceptable) {
13331     // format and type are acceptable enums but not guaranteed to be supported
13332     // for this framebuffer.  Have to ask gl if they are valid.
13333     GLint preferred_format = 0;
13334     DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format, 1);
13335     GLint preferred_type = 0;
13336     DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type, 1);
13337     if (format == static_cast<GLenum>(preferred_format) &&
13338         type == static_cast<GLenum>(preferred_type)) {
13339       format_type_acceptable = true;
13340     }
13341   }
13342   if (!format_type_acceptable) {
13343     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
13344         "format and type incompatible with the current read framebuffer");
13345     return error::kNoError;
13346   }
13347   if (width == 0 || height == 0) {
13348     return error::kNoError;
13349   }
13350 
13351   // Get the size of the current fbo or backbuffer.
13352   gfx::Size max_size = GetBoundReadFramebufferSize();
13353 
13354   int32_t max_x;
13355   int32_t max_y;
13356   if (!base::CheckAdd(x, width).AssignIfValid(&max_x) ||
13357       !base::CheckAdd(y, height).AssignIfValid(&max_y)) {
13358     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
13359     return error::kNoError;
13360   }
13361 
13362   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
13363 
13364   ScopedResolvedFramebufferBinder binder(this, false, true);
13365   GLenum read_format = GetBoundReadFramebufferInternalFormat();
13366 
13367   gfx::Rect rect(x, y, width, height);  // Safe before we checked above.
13368   gfx::Rect max_rect(max_size);
13369   if (!max_rect.Contains(rect)) {
13370     rect.Intersect(max_rect);
13371     if (!rect.IsEmpty()) {
13372       std::unique_ptr<ScopedFramebufferCopyBinder> copy_binder;
13373       if (workarounds()
13374               .use_copyteximage2d_instead_of_readpixels_on_multisampled_textures &&
13375           framebuffer_state_.bound_read_framebuffer.get() &&
13376           framebuffer_state_.bound_read_framebuffer.get()
13377               ->GetReadBufferIsMultisampledTexture()) {
13378         copy_binder = std::make_unique<ScopedFramebufferCopyBinder>(this);
13379       }
13380       if (y < 0) {
13381         pixels += static_cast<uint32_t>(-y) * padded_row_size;;
13382       }
13383       if (x < 0) {
13384         uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type);
13385         uint32_t leading_bytes = static_cast<uint32_t>(-x) * group_size;
13386         pixels += leading_bytes;
13387       }
13388       for (GLint iy = rect.y(); iy < rect.bottom(); ++iy) {
13389         bool reset_row_length = false;
13390         if (iy + 1 == max_y && pixels_shm_id == 0 &&
13391             workarounds().pack_parameters_workaround_with_pack_buffer &&
13392             state_.pack_row_length > 0 && state_.pack_row_length < width) {
13393           // Some drivers (for example, Mac AMD) incorrecly limit the last
13394           // row to ROW_LENGTH in this case.
13395           api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, width);
13396           reset_row_length = true;
13397         }
13398         api()->glReadPixelsFn(rect.x(), iy, rect.width(), 1, format, type,
13399                               pixels);
13400         if (reset_row_length) {
13401           api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, state_.pack_row_length);
13402         }
13403         pixels += padded_row_size;
13404       }
13405     }
13406   } else {
13407     if (async && features().use_async_readpixels &&
13408         !state_.bound_pixel_pack_buffer.get()) {
13409       // This workaround isn't implemented in this code path yet. Hopefully it's
13410       // unnecessary.
13411       DCHECK(
13412           !workarounds()
13413                .use_copyteximage2d_instead_of_readpixels_on_multisampled_textures ||
13414           !framebuffer_state_.bound_read_framebuffer.get() ||
13415           !framebuffer_state_.bound_read_framebuffer.get()
13416                ->GetReadBufferIsMultisampledTexture());
13417       // To simply the state tracking, we don't go down the async path if
13418       // a PIXEL_PACK_BUFFER is bound (in which case the client can
13419       // implement something similar on their own - all necessary functions
13420       // should be exposed).
13421       GLuint buffer_handle = 0;
13422       api()->glGenBuffersARBFn(1, &buffer_handle);
13423       api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, buffer_handle);
13424       // For ANGLE client version 2, GL_STREAM_READ is not available.
13425       const GLenum usage_hint =
13426           gl_version_info().is_angle ? GL_STATIC_DRAW : GL_STREAM_READ;
13427       api()->glBufferDataFn(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, nullptr,
13428                             usage_hint);
13429       GLenum error = api()->glGetErrorFn();
13430       if (error == GL_NO_ERROR) {
13431         // No need to worry about ES3 pixel pack parameters, because no
13432         // PIXEL_PACK_BUFFER is bound, and all these settings haven't been
13433         // sent to GL.
13434         api()->glReadPixelsFn(x, y, width, height, format, type, 0);
13435         pending_readpixel_fences_.push(FenceCallback());
13436         WaitForReadPixels(base::BindOnce(
13437             &GLES2DecoderImpl::FinishReadPixels, weak_ptr_factory_.GetWeakPtr(),
13438             width, height, format, type, pixels_shm_id, pixels_shm_offset,
13439             result_shm_id, result_shm_offset, state_.pack_alignment,
13440             read_format, buffer_handle));
13441         api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, 0);
13442         return error::kNoError;
13443       } else {
13444         // On error, unbind pack buffer and fall through to sync readpixels
13445         api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, 0);
13446         api()->glDeleteBuffersARBFn(1, &buffer_handle);
13447       }
13448     }
13449     if (pixels_shm_id == 0 &&
13450         workarounds().pack_parameters_workaround_with_pack_buffer) {
13451       // If we ever have a device that needs both of these workarounds, we'll
13452       // need to do some extra work to implement that correctly here.
13453       DCHECK(
13454           !workarounds()
13455                .use_copyteximage2d_instead_of_readpixels_on_multisampled_textures);
13456       if (state_.pack_row_length > 0 && state_.pack_row_length < width) {
13457         // Some drivers (for example, NVidia Linux) reset in this case.
13458         // Some drivers (for example, Mac AMD) incorrecly limit the last
13459         // row to ROW_LENGTH in this case.
13460         api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, width);
13461         for (GLint iy = y; iy < max_y; ++iy) {
13462           // Need to set PACK_ALIGNMENT for last row. See comment below.
13463           if (iy + 1 == max_y && padding > 0)
13464             api()->glPixelStoreiFn(GL_PACK_ALIGNMENT, 1);
13465           api()->glReadPixelsFn(x, iy, width, 1, format, type, pixels);
13466           if (iy + 1 == max_y && padding > 0)
13467             api()->glPixelStoreiFn(GL_PACK_ALIGNMENT, state_.pack_alignment);
13468           pixels += padded_row_size;
13469         }
13470         api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, state_.pack_row_length);
13471       } else if (padding > 0) {
13472         // Some drivers (for example, NVidia Linux) incorrectly require the
13473         // pack buffer to have padding for the last row.
13474         if (height > 1)
13475           api()->glReadPixelsFn(x, y, width, height - 1, format, type, pixels);
13476         api()->glPixelStoreiFn(GL_PACK_ALIGNMENT, 1);
13477         pixels += padded_row_size * (height - 1);
13478         api()->glReadPixelsFn(x, max_y - 1, width, 1, format, type, pixels);
13479         api()->glPixelStoreiFn(GL_PACK_ALIGNMENT, state_.pack_alignment);
13480       } else {
13481         api()->glReadPixelsFn(x, y, width, height, format, type, pixels);
13482       }
13483     } else if (
13484         workarounds()
13485             .use_copyteximage2d_instead_of_readpixels_on_multisampled_textures &&
13486         framebuffer_state_.bound_read_framebuffer.get() &&
13487         framebuffer_state_.bound_read_framebuffer.get()
13488             ->GetReadBufferIsMultisampledTexture()) {
13489       ScopedFramebufferCopyBinder copy_binder(this, x, y, width, height);
13490       api()->glReadPixelsFn(0, 0, width, height, format, type, pixels);
13491     } else {
13492       api()->glReadPixelsFn(x, y, width, height, format, type, pixels);
13493     }
13494   }
13495   if (pixels_shm_id != 0) {
13496     GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
13497     if (error == GL_NO_ERROR) {
13498       if (result) {
13499         result->success = 1;
13500         result->row_length = static_cast<uint32_t>(rect.width());
13501         result->num_rows = static_cast<uint32_t>(rect.height());
13502       }
13503       FinishReadPixels(width, height, format, type, pixels_shm_id,
13504                        pixels_shm_offset, result_shm_id, result_shm_offset,
13505                        state_.pack_alignment, read_format, 0);
13506     }
13507   }
13508 
13509   return error::kNoError;
13510 }
13511 
HandlePixelStorei(uint32_t immediate_data_size,const volatile void * cmd_data)13512 error::Error GLES2DecoderImpl::HandlePixelStorei(
13513     uint32_t immediate_data_size,
13514     const volatile void* cmd_data) {
13515   const volatile gles2::cmds::PixelStorei& c =
13516       *static_cast<const volatile gles2::cmds::PixelStorei*>(cmd_data);
13517   GLenum pname = c.pname;
13518   GLint param = c.param;
13519   if (!validators_->pixel_store.IsValid(pname)) {
13520     LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
13521     return error::kNoError;
13522   }
13523   switch (pname) {
13524     case GL_PACK_ALIGNMENT:
13525     case GL_UNPACK_ALIGNMENT:
13526       if (!validators_->pixel_store_alignment.IsValid(param)) {
13527         LOCAL_SET_GL_ERROR(
13528             GL_INVALID_VALUE, "glPixelStorei", "invalid param");
13529         return error::kNoError;
13530       }
13531       break;
13532     case GL_PACK_ROW_LENGTH:
13533     case GL_UNPACK_ROW_LENGTH:
13534     case GL_UNPACK_IMAGE_HEIGHT:
13535       if (param < 0) {
13536         LOCAL_SET_GL_ERROR(
13537             GL_INVALID_VALUE, "glPixelStorei", "invalid param");
13538         return error::kNoError;
13539       }
13540       break;
13541     case GL_PACK_SKIP_PIXELS:
13542     case GL_PACK_SKIP_ROWS:
13543     case GL_UNPACK_SKIP_PIXELS:
13544     case GL_UNPACK_SKIP_ROWS:
13545     case GL_UNPACK_SKIP_IMAGES:
13546       // All SKIP parameters are handled on the client side and should never
13547       // be passed to the service side.
13548       return error::kInvalidArguments;
13549     default:
13550       break;
13551   }
13552   // For alignment parameters, we always apply them.
13553   // For other parameters, we don't apply them if no buffer is bound at
13554   // PIXEL_PACK or PIXEL_UNPACK. We will handle pack and unpack according to
13555   // the user specified parameters on the client side.
13556   switch (pname) {
13557     case GL_PACK_ROW_LENGTH:
13558       if (state_.bound_pixel_pack_buffer.get())
13559         api()->glPixelStoreiFn(pname, param);
13560       break;
13561     case GL_UNPACK_ROW_LENGTH:
13562     case GL_UNPACK_IMAGE_HEIGHT:
13563       if (state_.bound_pixel_unpack_buffer.get())
13564         api()->glPixelStoreiFn(pname, param);
13565       break;
13566     default:
13567       api()->glPixelStoreiFn(pname, param);
13568       break;
13569   }
13570   switch (pname) {
13571     case GL_PACK_ALIGNMENT:
13572       state_.pack_alignment = param;
13573       break;
13574     case GL_PACK_ROW_LENGTH:
13575       state_.pack_row_length = param;
13576       break;
13577     case GL_UNPACK_ALIGNMENT:
13578       state_.unpack_alignment = param;
13579       break;
13580     case GL_UNPACK_ROW_LENGTH:
13581       state_.unpack_row_length = param;
13582       break;
13583     case GL_UNPACK_IMAGE_HEIGHT:
13584       state_.unpack_image_height = param;
13585       break;
13586     default:
13587       // Validation should have prevented us from getting here.
13588       NOTREACHED();
13589       break;
13590   }
13591   return error::kNoError;
13592 }
13593 
DoSwapBuffersWithBoundsCHROMIUM(uint64_t swap_id,GLsizei count,const volatile GLint * rects,GLbitfield flags)13594 void GLES2DecoderImpl::DoSwapBuffersWithBoundsCHROMIUM(
13595     uint64_t swap_id,
13596     GLsizei count,
13597     const volatile GLint* rects,
13598     GLbitfield flags) {
13599   TRACE_EVENT0("gpu", "GLES2DecoderImpl::SwapBuffersWithBoundsCHROMIUM");
13600   if (!supports_swap_buffers_with_bounds_) {
13601     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSwapBuffersWithBoundsCHROMIUM",
13602                        "command not supported by surface");
13603     return;
13604   }
13605   bool is_tracing;
13606   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
13607                                      &is_tracing);
13608   if (is_tracing) {
13609     bool is_offscreen = !!offscreen_target_frame_buffer_.get();
13610     ScopedFramebufferBinder binder(this, GetBoundDrawFramebufferServiceId());
13611     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
13612         is_offscreen ? offscreen_size_ : surface_->GetSize());
13613   }
13614 
13615   ClearScheduleCALayerState();
13616 
13617   std::vector<gfx::Rect> bounds(count);
13618   for (GLsizei i = 0; i < count; ++i) {
13619     bounds[i] = gfx::Rect(rects[i * 4 + 0], rects[i * 4 + 1], rects[i * 4 + 2],
13620                           rects[i * 4 + 3]);
13621   }
13622   client()->OnSwapBuffers(swap_id, flags);
13623   FinishSwapBuffers(surface_->SwapBuffersWithBounds(bounds, base::DoNothing()));
13624 }
13625 
HandlePostSubBufferCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)13626 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
13627     uint32_t immediate_data_size,
13628     const volatile void* cmd_data) {
13629   const volatile gles2::cmds::PostSubBufferCHROMIUM& c =
13630       *static_cast<const volatile gles2::cmds::PostSubBufferCHROMIUM*>(
13631           cmd_data);
13632   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
13633   if (!supports_post_sub_buffer_) {
13634     LOCAL_SET_GL_ERROR(
13635         GL_INVALID_OPERATION,
13636         "glPostSubBufferCHROMIUM", "command not supported by surface");
13637     return error::kNoError;
13638   }
13639   bool is_tracing;
13640   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
13641                                      &is_tracing);
13642   if (is_tracing) {
13643     bool is_offscreen = !!offscreen_target_frame_buffer_.get();
13644     ScopedFramebufferBinder binder(this, GetBoundDrawFramebufferServiceId());
13645     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
13646         is_offscreen ? offscreen_size_ : surface_->GetSize());
13647   }
13648 
13649   ClearScheduleCALayerState();
13650 
13651   if (supports_async_swap_) {
13652     TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", c.swap_id());
13653 
13654     client()->OnSwapBuffers(c.swap_id(), c.flags);
13655     surface_->PostSubBufferAsync(
13656         c.x, c.y, c.width, c.height,
13657         base::BindOnce(&GLES2DecoderImpl::FinishAsyncSwapBuffers,
13658                        weak_ptr_factory_.GetWeakPtr(), c.swap_id()),
13659         base::DoNothing());
13660   } else {
13661     client()->OnSwapBuffers(c.swap_id(), c.flags);
13662     FinishSwapBuffers(surface_->PostSubBuffer(c.x, c.y, c.width, c.height,
13663                                               base::DoNothing()));
13664   }
13665 
13666   return error::kNoError;
13667 }
13668 
HandleScheduleOverlayPlaneCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)13669 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
13670     uint32_t immediate_data_size,
13671     const volatile void* cmd_data) {
13672   const volatile gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
13673       *static_cast<const volatile gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(
13674           cmd_data);
13675   TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
13676   if (!ref) {
13677     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
13678                        "glScheduleOverlayPlaneCHROMIUM",
13679                        "unknown texture");
13680     return error::kNoError;
13681   }
13682   Texture::ImageState image_state;
13683   gl::GLImage* image =
13684       ref->texture()->GetLevelImage(ref->texture()->target(), 0, &image_state);
13685   if (!image) {
13686     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
13687                        "glScheduleOverlayPlaneCHROMIUM",
13688                        "unsupported texture format");
13689     return error::kNoError;
13690   }
13691   gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
13692   if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
13693     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
13694                        "glScheduleOverlayPlaneCHROMIUM",
13695                        "invalid transform enum");
13696     return error::kNoError;
13697   }
13698   GLuint gpu_fence_id = static_cast<GLuint>(c.gpu_fence_id);
13699   std::unique_ptr<gfx::GpuFence> gpu_fence;
13700   if (gpu_fence_id > 0) {
13701     gpu_fence = GetGpuFenceManager()->GetGpuFence(gpu_fence_id);
13702     if (!gpu_fence) {
13703       LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, "glScheduleOverlayPlaneCHROMIUM",
13704                          "unknown fence");
13705       return error::kNoError;
13706     }
13707   }
13708   if (!surface_->ScheduleOverlayPlane(
13709           c.plane_z_order, transform, image,
13710           gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
13711           gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height), c.enable_blend,
13712           std::move(gpu_fence))) {
13713     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
13714                        "glScheduleOverlayPlaneCHROMIUM",
13715                        "failed to schedule overlay");
13716   }
13717   return error::kNoError;
13718 }
13719 
HandleScheduleCALayerSharedStateCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)13720 error::Error GLES2DecoderImpl::HandleScheduleCALayerSharedStateCHROMIUM(
13721     uint32_t immediate_data_size,
13722     const volatile void* cmd_data) {
13723   const volatile gles2::cmds::ScheduleCALayerSharedStateCHROMIUM& c =
13724       *static_cast<
13725           const volatile gles2::cmds::ScheduleCALayerSharedStateCHROMIUM*>(
13726           cmd_data);
13727 
13728   // 4 for |clip_rect|, 5 for |rounded_corner_bounds|, 16 for |transform|.
13729   const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset,
13730                                                          25 * sizeof(GLfloat));
13731   if (!mem) {
13732     return error::kOutOfBounds;
13733   }
13734   gfx::RectF clip_rect(mem[0], mem[1], mem[2], mem[3]);
13735   gfx::RRectF rounded_corner_bounds(mem[4], mem[5], mem[6], mem[7], mem[8]);
13736   gfx::Transform transform(mem[9], mem[13], mem[17], mem[21], mem[10], mem[14],
13737                            mem[18], mem[22], mem[11], mem[15], mem[19], mem[23],
13738                            mem[12], mem[16], mem[20], mem[24]);
13739   ca_layer_shared_state_.reset(new CALayerSharedState);
13740   ca_layer_shared_state_->opacity = c.opacity;
13741   ca_layer_shared_state_->is_clipped = c.is_clipped ? true : false;
13742   ca_layer_shared_state_->clip_rect = gfx::ToEnclosingRect(clip_rect);
13743   ca_layer_shared_state_->rounded_corner_bounds = rounded_corner_bounds;
13744   ca_layer_shared_state_->sorting_context_id = c.sorting_context_id;
13745   ca_layer_shared_state_->transform = transform;
13746   return error::kNoError;
13747 }
13748 
HandleScheduleCALayerCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)13749 error::Error GLES2DecoderImpl::HandleScheduleCALayerCHROMIUM(
13750     uint32_t immediate_data_size,
13751     const volatile void* cmd_data) {
13752   const volatile gles2::cmds::ScheduleCALayerCHROMIUM& c =
13753       *static_cast<const volatile gles2::cmds::ScheduleCALayerCHROMIUM*>(
13754           cmd_data);
13755   GLuint filter = c.filter;
13756   if (filter != GL_NEAREST && filter != GL_LINEAR) {
13757     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleCALayerCHROMIUM",
13758                        "invalid filter");
13759     return error::kNoError;
13760   }
13761 
13762   if (!ca_layer_shared_state_) {
13763     LOCAL_SET_GL_ERROR(
13764         GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM",
13765         "glScheduleCALayerSharedStateCHROMIUM has not been called");
13766     return error::kNoError;
13767   }
13768 
13769   gl::GLImage* image = nullptr;
13770   GLuint contents_texture_id = c.contents_texture_id;
13771   if (contents_texture_id) {
13772     TextureRef* ref = texture_manager()->GetTexture(contents_texture_id);
13773     if (!ref) {
13774       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleCALayerCHROMIUM",
13775                          "unknown texture");
13776       return error::kNoError;
13777     }
13778     Texture::ImageState image_state;
13779     image = ref->texture()->GetLevelImage(ref->texture()->target(), 0,
13780                                           &image_state);
13781     if (!image) {
13782       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleCALayerCHROMIUM",
13783                          "unsupported texture format");
13784       return error::kNoError;
13785     }
13786   }
13787 
13788   const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset,
13789                                                          8 * sizeof(GLfloat));
13790   if (!mem) {
13791     return error::kOutOfBounds;
13792   }
13793   gfx::RectF contents_rect(mem[0], mem[1], mem[2], mem[3]);
13794   gfx::RectF bounds_rect(mem[4], mem[5], mem[6], mem[7]);
13795 
13796   ui::CARendererLayerParams params = ui::CARendererLayerParams(
13797       ca_layer_shared_state_->is_clipped, ca_layer_shared_state_->clip_rect,
13798       ca_layer_shared_state_->rounded_corner_bounds,
13799       ca_layer_shared_state_->sorting_context_id,
13800       ca_layer_shared_state_->transform, image, contents_rect,
13801       gfx::ToEnclosingRect(bounds_rect), c.background_color, c.edge_aa_mask,
13802       ca_layer_shared_state_->opacity, filter);
13803   if (!surface_->ScheduleCALayer(params)) {
13804     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM",
13805                        "failed to schedule CALayer");
13806   }
13807   return error::kNoError;
13808 }
13809 
HandleSetColorSpaceMetadataCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)13810 error::Error GLES2DecoderImpl::HandleSetColorSpaceMetadataCHROMIUM(
13811     uint32_t immediate_data_size,
13812     const volatile void* cmd_data) {
13813   const volatile gles2::cmds::SetColorSpaceMetadataCHROMIUM& c =
13814       *static_cast<const volatile gles2::cmds::SetColorSpaceMetadataCHROMIUM*>(
13815           cmd_data);
13816 
13817   GLuint texture_id = c.texture_id;
13818   gfx::ColorSpace color_space;
13819   if (!ReadColorSpace(c.shm_id, c.shm_offset, c.color_space_size,
13820                       &color_space)) {
13821     return error::kOutOfBounds;
13822   }
13823 
13824   TextureRef* ref = texture_manager()->GetTexture(texture_id);
13825   if (!ref) {
13826     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glSetColorSpaceMetadataCHROMIUM",
13827                        "unknown texture");
13828     return error::kNoError;
13829   }
13830 
13831   scoped_refptr<gl::GLImage> image =
13832       ref->texture()->GetLevelImage(ref->texture()->target(), 0);
13833   if (!image) {
13834     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glSetColorSpaceMetadataCHROMIUM",
13835                        "no image associated with texture");
13836     return error::kNoError;
13837   }
13838 
13839   image->SetColorSpace(color_space);
13840   return error::kNoError;
13841 }
13842 
DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count,const volatile GLuint * textures)13843 void GLES2DecoderImpl::DoScheduleCALayerInUseQueryCHROMIUM(
13844     GLsizei count,
13845     const volatile GLuint* textures) {
13846   std::vector<gl::GLSurface::CALayerInUseQuery> queries;
13847   queries.reserve(count);
13848   for (GLsizei i = 0; i < count; ++i) {
13849     gl::GLImage* image = nullptr;
13850     GLuint texture_id = textures[i];
13851     if (texture_id) {
13852       TextureRef* ref = texture_manager()->GetTexture(texture_id);
13853       if (!ref) {
13854         LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
13855                            "glScheduleCALayerInUseQueryCHROMIUM",
13856                            "unknown texture");
13857         return;
13858       }
13859       Texture::ImageState image_state;
13860       image = ref->texture()->GetLevelImage(ref->texture()->target(), 0,
13861                                             &image_state);
13862     }
13863     gl::GLSurface::CALayerInUseQuery query;
13864     query.image = image;
13865     query.texture = texture_id;
13866     queries.push_back(query);
13867   }
13868 
13869   surface_->ScheduleCALayerInUseQuery(std::move(queries));
13870 }
13871 
GetAttribLocationHelper(GLuint client_id,uint32_t location_shm_id,uint32_t location_shm_offset,const std::string & name_str)13872 error::Error GLES2DecoderImpl::GetAttribLocationHelper(
13873     GLuint client_id,
13874     uint32_t location_shm_id,
13875     uint32_t location_shm_offset,
13876     const std::string& name_str) {
13877   if (!StringIsValidForGLES(name_str)) {
13878     LOCAL_SET_GL_ERROR(
13879         GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
13880     return error::kNoError;
13881   }
13882   Program* program = GetProgramInfoNotShader(
13883       client_id, "glGetAttribLocation");
13884   if (!program) {
13885     return error::kNoError;
13886   }
13887   if (!program->IsValid()) {
13888     LOCAL_SET_GL_ERROR(
13889         GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
13890     return error::kNoError;
13891   }
13892   GLint* location = GetSharedMemoryAs<GLint*>(
13893       location_shm_id, location_shm_offset, sizeof(GLint));
13894   if (!location) {
13895     return error::kOutOfBounds;
13896   }
13897   // Check that the client initialized the result.
13898   if (*location != -1) {
13899     return error::kInvalidArguments;
13900   }
13901   *location = program->GetAttribLocation(name_str);
13902   return error::kNoError;
13903 }
13904 
HandleGetAttribLocation(uint32_t immediate_data_size,const volatile void * cmd_data)13905 error::Error GLES2DecoderImpl::HandleGetAttribLocation(
13906     uint32_t immediate_data_size,
13907     const volatile void* cmd_data) {
13908   const volatile gles2::cmds::GetAttribLocation& c =
13909       *static_cast<const volatile gles2::cmds::GetAttribLocation*>(cmd_data);
13910   Bucket* bucket = GetBucket(c.name_bucket_id);
13911   if (!bucket) {
13912     return error::kInvalidArguments;
13913   }
13914   std::string name_str;
13915   if (!bucket->GetAsString(&name_str)) {
13916     return error::kInvalidArguments;
13917   }
13918   return GetAttribLocationHelper(
13919     c.program, c.location_shm_id, c.location_shm_offset, name_str);
13920 }
13921 
GetUniformLocationHelper(GLuint client_id,uint32_t location_shm_id,uint32_t location_shm_offset,const std::string & name_str)13922 error::Error GLES2DecoderImpl::GetUniformLocationHelper(
13923     GLuint client_id,
13924     uint32_t location_shm_id,
13925     uint32_t location_shm_offset,
13926     const std::string& name_str) {
13927   if (!StringIsValidForGLES(name_str)) {
13928     LOCAL_SET_GL_ERROR(
13929         GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
13930     return error::kNoError;
13931   }
13932   Program* program = GetProgramInfoNotShader(
13933       client_id, "glGetUniformLocation");
13934   if (!program) {
13935     return error::kNoError;
13936   }
13937   if (!program->IsValid()) {
13938     LOCAL_SET_GL_ERROR(
13939         GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
13940     return error::kNoError;
13941   }
13942   GLint* location = GetSharedMemoryAs<GLint*>(
13943       location_shm_id, location_shm_offset, sizeof(GLint));
13944   if (!location) {
13945     return error::kOutOfBounds;
13946   }
13947   // Check that the client initialized the result.
13948   if (*location != -1) {
13949     return error::kInvalidArguments;
13950   }
13951   *location = program->GetUniformFakeLocation(name_str);
13952   return error::kNoError;
13953 }
13954 
HandleGetUniformLocation(uint32_t immediate_data_size,const volatile void * cmd_data)13955 error::Error GLES2DecoderImpl::HandleGetUniformLocation(
13956     uint32_t immediate_data_size,
13957     const volatile void* cmd_data) {
13958   const volatile gles2::cmds::GetUniformLocation& c =
13959       *static_cast<const volatile gles2::cmds::GetUniformLocation*>(cmd_data);
13960   Bucket* bucket = GetBucket(c.name_bucket_id);
13961   if (!bucket) {
13962     return error::kInvalidArguments;
13963   }
13964   std::string name_str;
13965   if (!bucket->GetAsString(&name_str)) {
13966     return error::kInvalidArguments;
13967   }
13968   return GetUniformLocationHelper(
13969     c.program, c.location_shm_id, c.location_shm_offset, name_str);
13970 }
13971 
HandleGetUniformIndices(uint32_t immediate_data_size,const volatile void * cmd_data)13972 error::Error GLES2DecoderImpl::HandleGetUniformIndices(
13973     uint32_t immediate_data_size,
13974     const volatile void* cmd_data) {
13975   if (!feature_info_->IsWebGL2OrES3Context())
13976     return error::kUnknownCommand;
13977   const volatile gles2::cmds::GetUniformIndices& c =
13978       *static_cast<const volatile gles2::cmds::GetUniformIndices*>(cmd_data);
13979   Bucket* bucket = GetBucket(c.names_bucket_id);
13980   if (!bucket) {
13981     return error::kInvalidArguments;
13982   }
13983   GLsizei count = 0;
13984   std::vector<char*> names;
13985   std::vector<GLint> len;
13986   if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
13987     return error::kInvalidArguments;
13988   }
13989   typedef cmds::GetUniformIndices::Result Result;
13990   uint32_t checked_size = 0;
13991   if (!Result::ComputeSize(count).AssignIfValid(&checked_size)) {
13992     return error::kOutOfBounds;
13993   }
13994   Result* result = GetSharedMemoryAs<Result*>(
13995       c.indices_shm_id, c.indices_shm_offset, checked_size);
13996   GLuint* indices = result ? result->GetData() : nullptr;
13997   if (indices == nullptr) {
13998     return error::kOutOfBounds;
13999   }
14000   // Check that the client initialized the result.
14001   if (result->size != 0) {
14002     return error::kInvalidArguments;
14003   }
14004   Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
14005   if (!program) {
14006     return error::kNoError;
14007   }
14008   GLuint service_id = program->service_id();
14009   GLint link_status = GL_FALSE;
14010   api()->glGetProgramivFn(service_id, GL_LINK_STATUS, &link_status);
14011   if (link_status != GL_TRUE) {
14012     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
14013         "glGetUniformIndices", "program not linked");
14014     return error::kNoError;
14015   }
14016   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
14017   api()->glGetUniformIndicesFn(service_id, count, &names[0], indices);
14018   GLenum error = api()->glGetErrorFn();
14019   if (error == GL_NO_ERROR) {
14020     result->SetNumResults(count);
14021   } else {
14022     LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
14023   }
14024   return error::kNoError;
14025 }
14026 
GetFragDataLocationHelper(GLuint client_id,uint32_t location_shm_id,uint32_t location_shm_offset,const std::string & name_str)14027 error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
14028     GLuint client_id,
14029     uint32_t location_shm_id,
14030     uint32_t location_shm_offset,
14031     const std::string& name_str) {
14032   const char kFunctionName[] = "glGetFragDataLocation";
14033   GLint* location = GetSharedMemoryAs<GLint*>(
14034       location_shm_id, location_shm_offset, sizeof(GLint));
14035   if (!location) {
14036     return error::kOutOfBounds;
14037   }
14038   // Check that the client initialized the result.
14039   if (*location != -1) {
14040     return error::kInvalidArguments;
14041   }
14042   Program* program = GetProgramInfoNotShader(client_id, kFunctionName);
14043   if (!program) {
14044     return error::kNoError;
14045   }
14046   if (!program->IsValid()) {
14047     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
14048                        "program not linked");
14049     return error::kNoError;
14050   }
14051 
14052   *location = program->GetFragDataLocation(name_str);
14053   return error::kNoError;
14054 }
14055 
HandleGetFragDataLocation(uint32_t immediate_data_size,const volatile void * cmd_data)14056 error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
14057     uint32_t immediate_data_size,
14058     const volatile void* cmd_data) {
14059   if (!feature_info_->IsWebGL2OrES3Context())
14060     return error::kUnknownCommand;
14061   const volatile gles2::cmds::GetFragDataLocation& c =
14062       *static_cast<const volatile gles2::cmds::GetFragDataLocation*>(cmd_data);
14063   Bucket* bucket = GetBucket(c.name_bucket_id);
14064   if (!bucket) {
14065     return error::kInvalidArguments;
14066   }
14067   std::string name_str;
14068   if (!bucket->GetAsString(&name_str)) {
14069     return error::kInvalidArguments;
14070   }
14071   return GetFragDataLocationHelper(
14072       c.program, c.location_shm_id, c.location_shm_offset, name_str);
14073 }
14074 
GetFragDataIndexHelper(GLuint program_id,uint32_t index_shm_id,uint32_t index_shm_offset,const std::string & name_str)14075 error::Error GLES2DecoderImpl::GetFragDataIndexHelper(
14076     GLuint program_id,
14077     uint32_t index_shm_id,
14078     uint32_t index_shm_offset,
14079     const std::string& name_str) {
14080   const char kFunctionName[] = "glGetFragDataIndexEXT";
14081   GLint* index =
14082       GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint));
14083   if (!index) {
14084     return error::kOutOfBounds;
14085   }
14086   // Check that the client initialized the result.
14087   if (*index != -1) {
14088     return error::kInvalidArguments;
14089   }
14090   Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
14091   if (!program) {
14092     return error::kNoError;
14093   }
14094   if (!program->IsValid()) {
14095     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
14096                        "program not linked");
14097     return error::kNoError;
14098   }
14099 
14100   *index = program->GetFragDataIndex(name_str);
14101   return error::kNoError;
14102 }
14103 
HandleGetFragDataIndexEXT(uint32_t immediate_data_size,const volatile void * cmd_data)14104 error::Error GLES2DecoderImpl::HandleGetFragDataIndexEXT(
14105     uint32_t immediate_data_size,
14106     const volatile void* cmd_data) {
14107   if (!features().ext_blend_func_extended) {
14108     return error::kUnknownCommand;
14109   }
14110   const volatile gles2::cmds::GetFragDataIndexEXT& c =
14111       *static_cast<const volatile gles2::cmds::GetFragDataIndexEXT*>(cmd_data);
14112   Bucket* bucket = GetBucket(c.name_bucket_id);
14113   if (!bucket) {
14114     return error::kInvalidArguments;
14115   }
14116   std::string name_str;
14117   if (!bucket->GetAsString(&name_str)) {
14118     return error::kInvalidArguments;
14119   }
14120   return GetFragDataIndexHelper(c.program, c.index_shm_id, c.index_shm_offset,
14121                                 name_str);
14122 }
14123 
HandleGetUniformBlockIndex(uint32_t immediate_data_size,const volatile void * cmd_data)14124 error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
14125     uint32_t immediate_data_size,
14126     const volatile void* cmd_data) {
14127   if (!feature_info_->IsWebGL2OrES3Context())
14128     return error::kUnknownCommand;
14129   const volatile gles2::cmds::GetUniformBlockIndex& c =
14130       *static_cast<const volatile gles2::cmds::GetUniformBlockIndex*>(cmd_data);
14131   Bucket* bucket = GetBucket(c.name_bucket_id);
14132   if (!bucket) {
14133     return error::kInvalidArguments;
14134   }
14135   std::string name_str;
14136   if (!bucket->GetAsString(&name_str)) {
14137     return error::kInvalidArguments;
14138   }
14139   GLuint* index = GetSharedMemoryAs<GLuint*>(
14140       c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
14141   if (!index) {
14142     return error::kOutOfBounds;
14143   }
14144   // Check that the client initialized the result.
14145   if (*index != GL_INVALID_INDEX) {
14146     return error::kInvalidArguments;
14147   }
14148   Program* program = GetProgramInfoNotShader(
14149       c.program, "glGetUniformBlockIndex");
14150   if (!program) {
14151     return error::kNoError;
14152   }
14153   *index =
14154       api()->glGetUniformBlockIndexFn(program->service_id(), name_str.c_str());
14155   return error::kNoError;
14156 }
14157 
HandleGetString(uint32_t immediate_data_size,const volatile void * cmd_data)14158 error::Error GLES2DecoderImpl::HandleGetString(uint32_t immediate_data_size,
14159                                                const volatile void* cmd_data) {
14160   const volatile gles2::cmds::GetString& c =
14161       *static_cast<const volatile gles2::cmds::GetString*>(cmd_data);
14162   GLenum name = static_cast<GLenum>(c.name);
14163   if (!validators_->string_type.IsValid(name)) {
14164     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
14165     return error::kNoError;
14166   }
14167 
14168   const char* str = nullptr;
14169   std::string extensions;
14170   switch (name) {
14171     case GL_VERSION:
14172       str = GetServiceVersionString(feature_info_.get());
14173       break;
14174     case GL_SHADING_LANGUAGE_VERSION:
14175       str = GetServiceShadingLanguageVersionString(feature_info_.get());
14176       break;
14177     case GL_EXTENSIONS: {
14178       gfx::ExtensionSet extension_set = feature_info_->extensions();
14179       // For WebGL contexts, strip out shader extensions if they have not
14180       // been enabled on WebGL1 or no longer exist (become core) in WebGL2.
14181       if (feature_info_->IsWebGLContext()) {
14182         if (!derivatives_explicitly_enabled_)
14183           extension_set.erase(kOESDerivativeExtension);
14184         if (!fbo_render_mipmap_explicitly_enabled_)
14185           extension_set.erase(kOESFboRenderMipmapExtension);
14186         if (!frag_depth_explicitly_enabled_)
14187           extension_set.erase(kEXTFragDepthExtension);
14188         if (!draw_buffers_explicitly_enabled_)
14189           extension_set.erase(kEXTDrawBuffersExtension);
14190         if (!shader_texture_lod_explicitly_enabled_)
14191           extension_set.erase(kEXTShaderTextureLodExtension);
14192         if (!multi_draw_explicitly_enabled_)
14193           extension_set.erase(kWEBGLMultiDrawExtension);
14194         if (!draw_instanced_base_vertex_base_instance_explicitly_enabled_)
14195           extension_set.erase(
14196               kWEBGLDrawInstancedBaseVertexBaseInstanceExtension);
14197         if (!multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_)
14198           extension_set.erase(
14199               kWEBGLMultiDrawInstancedBaseVertexBaseInstanceExtension);
14200       }
14201       if (supports_post_sub_buffer_)
14202         extension_set.insert("GL_CHROMIUM_post_sub_buffer");
14203       extensions = gfx::MakeExtensionString(extension_set);
14204       str = extensions.c_str();
14205       break;
14206     }
14207     default:
14208       str = reinterpret_cast<const char*>(api()->glGetStringFn(name));
14209       break;
14210   }
14211   Bucket* bucket = CreateBucket(c.bucket_id);
14212   bucket->SetFromString(str);
14213   return error::kNoError;
14214 }
14215 
HandleBufferData(uint32_t immediate_data_size,const volatile void * cmd_data)14216 error::Error GLES2DecoderImpl::HandleBufferData(uint32_t immediate_data_size,
14217                                                 const volatile void* cmd_data) {
14218   const volatile gles2::cmds::BufferData& c =
14219       *static_cast<const volatile gles2::cmds::BufferData*>(cmd_data);
14220   GLenum target = static_cast<GLenum>(c.target);
14221   GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
14222   uint32_t data_shm_id = static_cast<uint32_t>(c.data_shm_id);
14223   uint32_t data_shm_offset = static_cast<uint32_t>(c.data_shm_offset);
14224   GLenum usage = static_cast<GLenum>(c.usage);
14225   const void* data = nullptr;
14226   if (data_shm_id != 0 || data_shm_offset != 0) {
14227     data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
14228     if (!data) {
14229       return error::kOutOfBounds;
14230     }
14231   }
14232   buffer_manager()->ValidateAndDoBufferData(&state_, error_state_.get(), target,
14233                                             size, data, usage);
14234   return error::kNoError;
14235 }
14236 
DoBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)14237 void GLES2DecoderImpl::DoBufferSubData(
14238   GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
14239   // Just delegate it. Some validation is actually done before this.
14240   buffer_manager()->ValidateAndDoBufferSubData(&state_, error_state_.get(),
14241                                                target, offset, size, data);
14242 }
14243 
ClearLevel(Texture * texture,unsigned target,int level,unsigned format,unsigned type,int xoffset,int yoffset,int width,int height)14244 bool GLES2DecoderImpl::ClearLevel(Texture* texture,
14245                                   unsigned target,
14246                                   int level,
14247                                   unsigned format,
14248                                   unsigned type,
14249                                   int xoffset,
14250                                   int yoffset,
14251                                   int width,
14252                                   int height) {
14253   TRACE_EVENT0("gpu", "GLES2DecoderImpl::ClearLevel");
14254   DCHECK(target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY &&
14255          target != GL_TEXTURE_EXTERNAL_OES);
14256   uint32_t channels = GLES2Util::GetChannelsForFormat(format);
14257 
14258   bool must_use_gl_clear = false;
14259   if ((channels & GLES2Util::kDepth) != 0 &&
14260       feature_info_->feature_flags().angle_depth_texture &&
14261       feature_info_->gl_version_info().is_es2) {
14262     // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
14263     // on depth formats in ES2.
14264     must_use_gl_clear = true;
14265   }
14266 
14267   uint32_t size;
14268   uint32_t padded_row_size;
14269   if (!GLES2Util::ComputeImageDataSizes(width, height, 1, format, type,
14270                                         state_.unpack_alignment, &size, nullptr,
14271                                         &padded_row_size)) {
14272     return false;
14273   }
14274 
14275   // Prefer to do the clear using a glClear call unless the clear is very small
14276   // (less than 64x64, or one page). Calls to TexSubImage2D on large textures
14277   // can take hundreds of milliseconds because of slow uploads on macOS. Do this
14278   // only on macOS because clears are buggy on other drivers.
14279   // https://crbug.com/848952 (slow uploads on macOS)
14280   // https://crbug.com/883276 (buggy clears on Android)
14281   bool prefer_use_gl_clear = false;
14282 #if defined(OS_MACOSX)
14283   const uint32_t kMinSizeForGLClear = 4 * 1024;
14284   prefer_use_gl_clear = size > kMinSizeForGLClear;
14285 #endif
14286   if (must_use_gl_clear || prefer_use_gl_clear) {
14287     if (ClearLevelUsingGL(texture, channels, target, level, xoffset, yoffset,
14288                           width, height)) {
14289       return true;
14290     }
14291   }
14292   if (must_use_gl_clear)
14293     return false;
14294 
14295   TRACE_EVENT1("gpu", "Clear using TexSubImage2D", "size", size);
14296 
14297   int tile_height;
14298 
14299   const uint32_t kMaxZeroSize = 1024 * 1024 * 4;
14300   if (size > kMaxZeroSize) {
14301     if (kMaxZeroSize < padded_row_size) {
14302       // That'd be an awfully large texture.
14303       return false;
14304     }
14305     // We should never have a large total size with a zero row size.
14306     DCHECK_GT(padded_row_size, 0U);
14307     tile_height = kMaxZeroSize / padded_row_size;
14308     if (!GLES2Util::ComputeImageDataSizes(width, tile_height, 1, format, type,
14309                                           state_.unpack_alignment, &size,
14310                                           nullptr, nullptr)) {
14311       return false;
14312     }
14313   } else {
14314     tile_height = height;
14315   }
14316 
14317   api()->glBindTextureFn(texture->target(), texture->service_id());
14318   {
14319     // Add extra scope to destroy zero and the object it owns right
14320     // after its usage.
14321     // Assumes the size has already been checked.
14322     std::unique_ptr<char[]> zero(new char[size]);
14323     memset(zero.get(), 0, size);
14324 
14325     ScopedPixelUnpackState reset_restore(&state_);
14326     GLint y = 0;
14327     while (y < height) {
14328       GLint h = y + tile_height > height ? height - y : tile_height;
14329       api()->glTexSubImage2DFn(
14330           target, level, xoffset, yoffset + y, width, h,
14331           TextureManager::AdjustTexFormat(feature_info_.get(), format), type,
14332           zero.get());
14333       y += tile_height;
14334     }
14335   }
14336 
14337   TextureRef* bound_texture =
14338       texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
14339   api()->glBindTextureFn(texture->target(),
14340                          bound_texture ? bound_texture->service_id() : 0);
14341   DCHECK(glGetError() == GL_NO_ERROR);
14342   return true;
14343 }
14344 
ClearLevelUsingGL(Texture * texture,uint32_t channels,unsigned target,int level,int xoffset,int yoffset,int width,int height)14345 bool GLES2DecoderImpl::ClearLevelUsingGL(Texture* texture,
14346                                          uint32_t channels,
14347                                          unsigned target,
14348                                          int level,
14349                                          int xoffset,
14350                                          int yoffset,
14351                                          int width,
14352                                          int height) {
14353   TRACE_EVENT0("gpu", "GLES2DecoderImpl::ClearLevelUsingGL");
14354   GLenum fb_target = GetDrawFramebufferTarget();
14355   GLuint fb = 0;
14356   api()->glGenFramebuffersEXTFn(1, &fb);
14357   api()->glBindFramebufferEXTFn(fb_target, fb);
14358 
14359   bool have_color = (channels & GLES2Util::kRGBA) != 0;
14360   if (have_color) {
14361     api()->glFramebufferTexture2DEXTFn(fb_target, GL_COLOR_ATTACHMENT0, target,
14362                                        texture->service_id(), level);
14363   }
14364   bool have_depth = (channels & GLES2Util::kDepth) != 0;
14365   if (have_depth) {
14366     api()->glFramebufferTexture2DEXTFn(fb_target, GL_DEPTH_ATTACHMENT, target,
14367                                        texture->service_id(), level);
14368   }
14369   bool have_stencil = (channels & GLES2Util::kStencil) != 0;
14370   if (have_stencil) {
14371     api()->glFramebufferTexture2DEXTFn(fb_target, GL_STENCIL_ATTACHMENT, target,
14372                                        texture->service_id(), level);
14373   }
14374   // Attempt to do the clear only if the framebuffer is complete. ANGLE
14375   // promises a depth only attachment ok.
14376   bool result = false;
14377   if (api()->glCheckFramebufferStatusEXTFn(fb_target) ==
14378       GL_FRAMEBUFFER_COMPLETE) {
14379     state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
14380     api()->glClearColorFn(0.0, 0.0, 0.0, 0.0);
14381     api()->glClearStencilFn(0);
14382     state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
14383     state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
14384     api()->glClearDepthFn(1.0f);
14385     state_.SetDeviceDepthMask(GL_TRUE);
14386     state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
14387     gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
14388     api()->glScissorFn(xoffset + scissor_offset.x(),
14389                        yoffset + scissor_offset.y(), width, height);
14390     ClearDeviceWindowRectangles();
14391 
14392     api()->glClearFn((have_color ? GL_COLOR_BUFFER_BIT : 0) |
14393                      (have_depth ? GL_DEPTH_BUFFER_BIT : 0) |
14394                      (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
14395     result = true;
14396   }
14397   RestoreClearState();
14398   api()->glDeleteFramebuffersEXTFn(1, &fb);
14399   Framebuffer* framebuffer = GetFramebufferInfoForTarget(fb_target);
14400   GLuint fb_service_id =
14401       framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
14402   api()->glBindFramebufferEXTFn(fb_target, fb_service_id);
14403   return result;
14404 }
14405 
ClearCompressedTextureLevel(Texture * texture,unsigned target,int level,unsigned format,int width,int height)14406 bool GLES2DecoderImpl::ClearCompressedTextureLevel(Texture* texture,
14407                                                    unsigned target,
14408                                                    int level,
14409                                                    unsigned format,
14410                                                    int width,
14411                                                    int height) {
14412   DCHECK(target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY);
14413   // This code path can only be called if the texture was originally
14414   // allocated via TexStorage2D. Note that TexStorage2D is exposed
14415   // internally for ES 2.0 contexts, but compressed texture support is
14416   // not part of that exposure.
14417   DCHECK(feature_info_->IsWebGL2OrES3Context());
14418 
14419   GLsizei bytes_required = 0;
14420   if (!GetCompressedTexSizeInBytes("ClearCompressedTextureLevel", width, height,
14421                                    1, format, &bytes_required,
14422                                    error_state_.get())) {
14423     return false;
14424   }
14425 
14426   TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearCompressedTextureLevel",
14427                "bytes_required", bytes_required);
14428 
14429   api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, 0);
14430   {
14431     // Add extra scope to destroy zero and the object it owns right
14432     // after its usage.
14433     std::unique_ptr<char[]> zero(new char[bytes_required]);
14434     memset(zero.get(), 0, bytes_required);
14435     api()->glBindTextureFn(texture->target(), texture->service_id());
14436     api()->glCompressedTexSubImage2DFn(target, level, 0, 0, width, height,
14437                                        format, bytes_required, zero.get());
14438   }
14439   TextureRef* bound_texture =
14440       texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
14441   api()->glBindTextureFn(texture->target(),
14442                          bound_texture ? bound_texture->service_id() : 0);
14443   Buffer* bound_buffer = buffer_manager()->GetBufferInfoForTarget(
14444       &state_, GL_PIXEL_UNPACK_BUFFER);
14445   if (bound_buffer) {
14446     api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, bound_buffer->service_id());
14447   }
14448   return true;
14449 }
14450 
ClearCompressedTextureLevel3D(Texture * texture,unsigned target,int level,unsigned format,int width,int height,int depth)14451 bool GLES2DecoderImpl::ClearCompressedTextureLevel3D(Texture* texture,
14452                                                      unsigned target,
14453                                                      int level,
14454                                                      unsigned format,
14455                                                      int width,
14456                                                      int height,
14457                                                      int depth) {
14458   DCHECK(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY);
14459   // This code path can only be called if the texture was originally
14460   // allocated via TexStorage3D. Note that TexStorage3D is exposed
14461   // internally for ES 2.0 contexts, but compressed texture support is
14462   // not part of that exposure.
14463   DCHECK(feature_info_->IsWebGL2OrES3Context());
14464 
14465   GLsizei bytes_required = 0;
14466   if (!GetCompressedTexSizeInBytes("ClearCompressedTextureLevel3D", width,
14467                                    height, 1, format, &bytes_required,
14468                                    error_state_.get())) {
14469     return false;
14470   }
14471 
14472   TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearCompressedTextureLevel3D",
14473                "bytes_required", bytes_required);
14474 
14475   api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, 0);
14476   {
14477     // Add extra scope to destroy zero and the object it owns right
14478     // after its usage.
14479     std::unique_ptr<char[]> zero(new char[bytes_required]);
14480     memset(zero.get(), 0, bytes_required);
14481     api()->glBindTextureFn(texture->target(), texture->service_id());
14482     api()->glCompressedTexSubImage3DFn(target, level, 0, 0, 0, width, height,
14483                                        depth, format, bytes_required,
14484                                        zero.get());
14485   }
14486   TextureRef* bound_texture =
14487       texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
14488   api()->glBindTextureFn(texture->target(),
14489                          bound_texture ? bound_texture->service_id() : 0);
14490   Buffer* bound_buffer =
14491       buffer_manager()->GetBufferInfoForTarget(&state_, GL_PIXEL_UNPACK_BUFFER);
14492   if (bound_buffer) {
14493     api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, bound_buffer->service_id());
14494   }
14495   return true;
14496 }
14497 
IsCompressedTextureFormat(unsigned format)14498 bool GLES2DecoderImpl::IsCompressedTextureFormat(unsigned format) {
14499   return feature_info_->validators()->compressed_texture_format.IsValid(
14500       format);
14501 }
14502 
ClearLevel3D(Texture * texture,unsigned target,int level,unsigned format,unsigned type,int width,int height,int depth)14503 bool GLES2DecoderImpl::ClearLevel3D(Texture* texture,
14504                                     unsigned target,
14505                                     int level,
14506                                     unsigned format,
14507                                     unsigned type,
14508                                     int width,
14509                                     int height,
14510                                     int depth) {
14511   DCHECK(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY);
14512   DCHECK(feature_info_->IsWebGL2OrES3Context());
14513   if (width == 0 || height == 0 || depth == 0)
14514     return true;
14515 
14516   uint32_t size;
14517   uint32_t padded_row_size;
14518   uint32_t padding;
14519   // Here we use unpack buffer to upload zeros into the texture, one layer
14520   // at a time.
14521   // We only take into consideration UNPACK_ALIGNMENT, and clear other unpack
14522   // parameters if necessary before TexSubImage3D calls.
14523   PixelStoreParams params;
14524   params.alignment = state_.unpack_alignment;
14525   if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth,
14526                                            format, type,
14527                                            params,
14528                                            &size,
14529                                            nullptr,
14530                                            &padded_row_size,
14531                                            nullptr,
14532                                            &padding)) {
14533     return false;
14534   }
14535   const uint32_t kMaxZeroSize = 1024 * 1024 * 2;
14536   uint32_t buffer_size;
14537   std::vector<TexSubCoord3D> subs;
14538   if (size < kMaxZeroSize) {
14539     // Case 1: one TexSubImage3D call clears the entire 3D texture.
14540     buffer_size = size;
14541     subs.push_back(TexSubCoord3D(0, 0, 0, width, height, depth));
14542   } else {
14543     uint32_t size_per_layer;
14544     if (!base::CheckMul(padded_row_size, height)
14545              .AssignIfValid(&size_per_layer)) {
14546       return false;
14547     }
14548     if (size_per_layer < kMaxZeroSize) {
14549       // Case 2: Each TexSubImage3D call clears 1 or more layers.
14550       uint32_t depth_step = kMaxZeroSize / size_per_layer;
14551       uint32_t num_of_slices = depth / depth_step;
14552       if (num_of_slices * depth_step < static_cast<uint32_t>(depth))
14553         num_of_slices++;
14554       DCHECK_LT(0u, num_of_slices);
14555       buffer_size = size_per_layer * depth_step;
14556       int depth_of_last_slice = depth - (num_of_slices - 1) * depth_step;
14557       DCHECK_LT(0, depth_of_last_slice);
14558       for (uint32_t ii = 0; ii < num_of_slices; ++ii) {
14559         int depth_ii =
14560             (ii + 1 == num_of_slices ? depth_of_last_slice : depth_step);
14561         subs.push_back(
14562             TexSubCoord3D(0, 0, depth_step * ii, width, height, depth_ii));
14563       }
14564     } else {
14565       // Case 3: Multiple TexSubImage3D calls clear 1 layer.
14566       if (kMaxZeroSize < padded_row_size) {
14567         // That'd be an awfully large texture.
14568         return false;
14569       }
14570       uint32_t height_step = kMaxZeroSize / padded_row_size;
14571       uint32_t num_of_slices = height / height_step;
14572       if (num_of_slices * height_step < static_cast<uint32_t>(height))
14573         num_of_slices++;
14574       DCHECK_LT(0u, num_of_slices);
14575       buffer_size = padded_row_size * height_step;
14576       int height_of_last_slice = height - (num_of_slices - 1) * height_step;
14577       DCHECK_LT(0, height_of_last_slice);
14578       for (int zz = 0; zz < depth; ++zz) {
14579         for (uint32_t ii = 0; ii < num_of_slices; ++ii) {
14580           int height_ii =
14581               (ii + 1 == num_of_slices ? height_of_last_slice : height_step);
14582           subs.push_back(
14583               TexSubCoord3D(0, height_step * ii, zz, width, height_ii, 1));
14584         }
14585       }
14586     }
14587   }
14588 
14589   TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel3D", "size", size);
14590 
14591   {
14592     ScopedPixelUnpackState reset_restore(&state_);
14593     GLuint buffer_id = 0;
14594     api()->glGenBuffersARBFn(1, &buffer_id);
14595     api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, buffer_id);
14596     {
14597       // Include padding as some drivers incorrectly requires padding for the
14598       // last row.
14599       buffer_size += padding;
14600       std::unique_ptr<char[]> zero(new char[buffer_size]);
14601       memset(zero.get(), 0, buffer_size);
14602       // TODO(zmo): Consider glMapBufferRange instead.
14603       api()->glBufferDataFn(GL_PIXEL_UNPACK_BUFFER, buffer_size, zero.get(),
14604                             GL_STATIC_DRAW);
14605     }
14606 
14607     api()->glBindTextureFn(texture->target(), texture->service_id());
14608     for (size_t ii = 0; ii < subs.size(); ++ii) {
14609       api()->glTexSubImage3DFn(target, level, subs[ii].xoffset,
14610                                subs[ii].yoffset, subs[ii].zoffset,
14611                                subs[ii].width, subs[ii].height, subs[ii].depth,
14612                                format, type, nullptr);
14613     }
14614     api()->glDeleteBuffersARBFn(1, &buffer_id);
14615   }
14616 
14617   TextureRef* bound_texture =
14618       texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
14619   api()->glBindTextureFn(texture->target(),
14620                          bound_texture ? bound_texture->service_id() : 0);
14621   return true;
14622 }
14623 
14624 namespace {
14625 
CheckETCFormatSupport(const FeatureInfo & feature_info)14626 bool CheckETCFormatSupport(const FeatureInfo& feature_info) {
14627   const gl::GLVersionInfo& version_info = feature_info.gl_version_info();
14628   return version_info.IsAtLeastGL(4, 3) || version_info.IsAtLeastGLES(3, 0) ||
14629          feature_info.feature_flags().arb_es3_compatibility;
14630 }
14631 
14632 using CompressedFormatSupportCheck = bool (*)(const FeatureInfo&);
14633 using CompressedFormatDecompressionFunction = void (*)(size_t width,
14634                                                        size_t height,
14635                                                        size_t depth,
14636                                                        const uint8_t* input,
14637                                                        size_t inputRowPitch,
14638                                                        size_t inputDepthPitch,
14639                                                        uint8_t* output,
14640                                                        size_t outputRowPitch,
14641                                                        size_t outputDepthPitch);
14642 
14643 struct CompressedFormatInfo {
14644   GLenum format;
14645   uint32_t block_size;
14646   uint32_t bytes_per_block;
14647   CompressedFormatSupportCheck support_check;
14648   CompressedFormatDecompressionFunction decompression_function;
14649   GLenum decompressed_internal_format;
14650   GLenum decompressed_format;
14651   GLenum decompressed_type;
14652 };
14653 
14654 const CompressedFormatInfo kCompressedFormatInfoArray[] = {
14655     {
14656         GL_COMPRESSED_R11_EAC, 4, 8, CheckETCFormatSupport,
14657         angle::LoadEACR11ToR8, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
14658     },
14659     {
14660         GL_COMPRESSED_SIGNED_R11_EAC, 4, 8, CheckETCFormatSupport,
14661         angle::LoadEACR11SToR8, GL_R8_SNORM, GL_RED, GL_BYTE,
14662     },
14663     {
14664         GL_COMPRESSED_RG11_EAC, 4, 16, CheckETCFormatSupport,
14665         angle::LoadEACRG11ToRG8, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
14666     },
14667     {
14668         GL_COMPRESSED_SIGNED_RG11_EAC, 4, 16, CheckETCFormatSupport,
14669         angle::LoadEACRG11SToRG8, GL_RG8_SNORM, GL_RG, GL_BYTE,
14670     },
14671     {
14672         GL_COMPRESSED_RGB8_ETC2, 4, 8, CheckETCFormatSupport,
14673         angle::LoadETC2RGB8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
14674     },
14675     {
14676         GL_COMPRESSED_SRGB8_ETC2, 4, 8, CheckETCFormatSupport,
14677         angle::LoadETC2SRGB8ToRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA,
14678         GL_UNSIGNED_BYTE,
14679     },
14680     {
14681         GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 16, CheckETCFormatSupport,
14682         angle::LoadETC2RGBA8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
14683     },
14684     {
14685         GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8,
14686         CheckETCFormatSupport, angle::LoadETC2RGB8A1ToRGBA8, GL_RGBA8, GL_RGBA,
14687         GL_UNSIGNED_BYTE,
14688     },
14689     {
14690         GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 16, CheckETCFormatSupport,
14691         angle::LoadETC2SRGBA8ToSRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA,
14692         GL_UNSIGNED_BYTE,
14693     },
14694     {
14695         GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8,
14696         CheckETCFormatSupport, angle::LoadETC2SRGB8A1ToRGBA8, GL_SRGB8_ALPHA8,
14697         GL_SRGB_ALPHA, GL_UNSIGNED_BYTE,
14698     },
14699 };
14700 
GetCompressedFormatInfo(GLenum format)14701 const CompressedFormatInfo* GetCompressedFormatInfo(GLenum format) {
14702   for (size_t i = 0; i < base::size(kCompressedFormatInfoArray); i++) {
14703     if (kCompressedFormatInfoArray[i].format == format) {
14704       return &kCompressedFormatInfoArray[i];
14705     }
14706   }
14707   return nullptr;
14708 }
14709 
GetCompressedFormatRowPitch(const CompressedFormatInfo & info,uint32_t width)14710 uint32_t GetCompressedFormatRowPitch(const CompressedFormatInfo& info,
14711                                      uint32_t width) {
14712   uint32_t num_blocks_wide = (width + info.block_size - 1) / info.block_size;
14713   return num_blocks_wide * info.bytes_per_block;
14714 }
14715 
GetCompressedFormatDepthPitch(const CompressedFormatInfo & info,uint32_t width,uint32_t height)14716 uint32_t GetCompressedFormatDepthPitch(const CompressedFormatInfo& info,
14717                                        uint32_t width,
14718                                        uint32_t height) {
14719   uint32_t num_blocks_high = (height + info.block_size - 1) / info.block_size;
14720   return num_blocks_high * GetCompressedFormatRowPitch(info, width);
14721 }
14722 
DecompressTextureData(const ContextState & state,const CompressedFormatInfo & info,uint32_t width,uint32_t height,uint32_t depth,GLsizei image_size,const void * data)14723 std::unique_ptr<uint8_t[]> DecompressTextureData(
14724     const ContextState& state,
14725     const CompressedFormatInfo& info,
14726     uint32_t width,
14727     uint32_t height,
14728     uint32_t depth,
14729     GLsizei image_size,
14730     const void* data) {
14731   auto* api = state.api();
14732   uint32_t output_pixel_size = GLES2Util::ComputeImageGroupSize(
14733       info.decompressed_format, info.decompressed_type);
14734   std::unique_ptr<uint8_t[]> decompressed_data(
14735       new uint8_t[output_pixel_size * width * height]);
14736 
14737   // If a PBO is bound, map it to decompress the data.
14738   const void* input_data = data;
14739   if (state.bound_pixel_unpack_buffer) {
14740     input_data = api->glMapBufferRangeFn(GL_PIXEL_UNPACK_BUFFER,
14741                                          reinterpret_cast<GLintptr>(data),
14742                                          image_size, GL_MAP_READ_BIT);
14743     if (input_data == nullptr) {
14744       LOG(ERROR) << "Failed to map pixel unpack buffer.";
14745       return nullptr;
14746     }
14747   }
14748 
14749   DCHECK_NE(input_data, nullptr);
14750   info.decompression_function(
14751       width, height, depth, static_cast<const uint8_t*>(input_data),
14752       GetCompressedFormatRowPitch(info, width),
14753       GetCompressedFormatDepthPitch(info, width, height),
14754       decompressed_data.get(), output_pixel_size * width,
14755       output_pixel_size * width * height);
14756 
14757   if (state.bound_pixel_unpack_buffer) {
14758     if (api->glUnmapBufferFn(GL_PIXEL_UNPACK_BUFFER) != GL_TRUE) {
14759       LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
14760       return nullptr;
14761     }
14762   }
14763 
14764   return decompressed_data;
14765 }
14766 
14767 }  // anonymous namespace.
14768 
ValidateCompressedTexFuncData(const char * function_name,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei size,const GLvoid * data)14769 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(const char* function_name,
14770                                                      GLsizei width,
14771                                                      GLsizei height,
14772                                                      GLsizei depth,
14773                                                      GLenum format,
14774                                                      GLsizei size,
14775                                                      const GLvoid* data) {
14776   GLsizei bytes_required = 0;
14777   if (!GetCompressedTexSizeInBytes(function_name, width, height, depth, format,
14778                                    &bytes_required, error_state_.get())) {
14779     return false;
14780   }
14781 
14782   if (size != bytes_required) {
14783     LOCAL_SET_GL_ERROR(
14784         GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
14785     return false;
14786   }
14787 
14788   Buffer* buffer = state_.bound_pixel_unpack_buffer.get();
14789   if (buffer &&
14790       !buffer_manager()->RequestBufferAccess(
14791           error_state_.get(), buffer, reinterpret_cast<GLintptr>(data),
14792           static_cast<GLsizeiptr>(bytes_required), function_name,
14793           "pixel unpack buffer")) {
14794     return false;
14795   }
14796 
14797   return true;
14798 }
14799 
ValidateCompressedTexDimensions(const char * function_name,GLenum target,GLint level,GLsizei width,GLsizei height,GLsizei depth,GLenum format)14800 bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
14801     const char* function_name, GLenum target, GLint level,
14802     GLsizei width, GLsizei height, GLsizei depth, GLenum format) {
14803   const char* error_message = "";
14804   if (!::gpu::gles2::ValidateCompressedTexDimensions(
14805           target, level, width, height, depth, format, &error_message)) {
14806     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, error_message);
14807     return false;
14808   }
14809   return true;
14810 }
14811 
ValidateCompressedTexSubDimensions(const char * function_name,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,Texture * texture)14812 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
14813     const char* function_name,
14814     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
14815     GLsizei width, GLsizei height, GLsizei depth, GLenum format,
14816     Texture* texture) {
14817   const char* error_message = "";
14818   if (!::gpu::gles2::ValidateCompressedTexSubDimensions(
14819           target, level, xoffset, yoffset, zoffset, width, height, depth,
14820           format, texture, &error_message)) {
14821     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, error_message);
14822     return false;
14823   }
14824   return true;
14825 }
14826 
HandleCompressedTexImage2DBucket(uint32_t immediate_data_size,const volatile void * cmd_data)14827 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
14828     uint32_t immediate_data_size, const volatile void* cmd_data) {
14829   const volatile gles2::cmds::CompressedTexImage2DBucket& c =
14830       *static_cast<const volatile gles2::cmds::CompressedTexImage2DBucket*>(
14831           cmd_data);
14832   GLenum target = static_cast<GLenum>(c.target);
14833   GLint level = static_cast<GLint>(c.level);
14834   GLenum internal_format = static_cast<GLenum>(c.internalformat);
14835   GLsizei width = static_cast<GLsizei>(c.width);
14836   GLsizei height = static_cast<GLsizei>(c.height);
14837   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
14838   GLint border = static_cast<GLint>(c.border);
14839 
14840   if (state_.bound_pixel_unpack_buffer.get()) {
14841     return error::kInvalidArguments;
14842   }
14843   Bucket* bucket = GetBucket(bucket_id);
14844   if (!bucket)
14845     return error::kInvalidArguments;
14846   uint32_t image_size = bucket->size();
14847   const void* data = bucket->GetData(0, image_size);
14848   DCHECK(data || !image_size);
14849   return DoCompressedTexImage(target, level, internal_format, width, height, 1,
14850                               border, image_size, data, ContextState::k2D);
14851 }
14852 
HandleCompressedTexImage2D(uint32_t immediate_data_size,const volatile void * cmd_data)14853 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
14854     uint32_t immediate_data_size, const volatile void* cmd_data) {
14855   const volatile gles2::cmds::CompressedTexImage2D& c =
14856       *static_cast<const volatile gles2::cmds::CompressedTexImage2D*>(cmd_data);
14857   GLenum target = static_cast<GLenum>(c.target);
14858   GLint level = static_cast<GLint>(c.level);
14859   GLenum internal_format = static_cast<GLenum>(c.internalformat);
14860   GLsizei width = static_cast<GLsizei>(c.width);
14861   GLsizei height = static_cast<GLsizei>(c.height);
14862   GLint border = static_cast<GLint>(c.border);
14863   GLsizei image_size = static_cast<GLsizei>(c.imageSize);
14864   uint32_t data_shm_id = c.data_shm_id;
14865   uint32_t data_shm_offset = c.data_shm_offset;
14866 
14867   const void* data;
14868   if (state_.bound_pixel_unpack_buffer.get()) {
14869     if (data_shm_id) {
14870       return error::kInvalidArguments;
14871     }
14872     data = reinterpret_cast<const void*>(data_shm_offset);
14873   } else {
14874     if (!data_shm_id && data_shm_offset) {
14875       return error::kInvalidArguments;
14876     }
14877     data = GetSharedMemoryAs<const void*>(
14878         data_shm_id, data_shm_offset, image_size);
14879   }
14880   return DoCompressedTexImage(target, level, internal_format, width, height, 1,
14881                               border, image_size, data, ContextState::k2D);
14882 }
14883 
HandleCompressedTexImage3DBucket(uint32_t immediate_data_size,const volatile void * cmd_data)14884 error::Error GLES2DecoderImpl::HandleCompressedTexImage3DBucket(
14885     uint32_t immediate_data_size, const volatile void* cmd_data) {
14886   if (!feature_info_->IsWebGL2OrES3Context())
14887     return error::kUnknownCommand;
14888   const volatile gles2::cmds::CompressedTexImage3DBucket& c =
14889       *static_cast<const volatile gles2::cmds::CompressedTexImage3DBucket*>(
14890           cmd_data);
14891   GLenum target = static_cast<GLenum>(c.target);
14892   GLint level = static_cast<GLint>(c.level);
14893   GLenum internal_format = static_cast<GLenum>(c.internalformat);
14894   GLsizei width = static_cast<GLsizei>(c.width);
14895   GLsizei height = static_cast<GLsizei>(c.height);
14896   GLsizei depth = static_cast<GLsizei>(c.depth);
14897   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
14898   GLint border = static_cast<GLint>(c.border);
14899 
14900   if (state_.bound_pixel_unpack_buffer.get()) {
14901     return error::kInvalidArguments;
14902   }
14903   Bucket* bucket = GetBucket(bucket_id);
14904   if (!bucket)
14905     return error::kInvalidArguments;
14906   uint32_t image_size = bucket->size();
14907   const void* data = bucket->GetData(0, image_size);
14908   DCHECK(data || !image_size);
14909   return DoCompressedTexImage(target, level, internal_format, width, height,
14910                               depth, border, image_size, data,
14911                               ContextState::k3D);
14912 }
14913 
HandleCompressedTexImage3D(uint32_t immediate_data_size,const volatile void * cmd_data)14914 error::Error GLES2DecoderImpl::HandleCompressedTexImage3D(
14915     uint32_t immediate_data_size, const volatile void* cmd_data) {
14916   if (!feature_info_->IsWebGL2OrES3Context())
14917     return error::kUnknownCommand;
14918   const volatile gles2::cmds::CompressedTexImage3D& c =
14919       *static_cast<const volatile gles2::cmds::CompressedTexImage3D*>(cmd_data);
14920   GLenum target = static_cast<GLenum>(c.target);
14921   GLint level = static_cast<GLint>(c.level);
14922   GLenum internal_format = static_cast<GLenum>(c.internalformat);
14923   GLsizei width = static_cast<GLsizei>(c.width);
14924   GLsizei height = static_cast<GLsizei>(c.height);
14925   GLsizei depth = static_cast<GLsizei>(c.depth);
14926   GLint border = static_cast<GLint>(c.border);
14927   GLsizei image_size = static_cast<GLsizei>(c.imageSize);
14928   uint32_t data_shm_id = c.data_shm_id;
14929   uint32_t data_shm_offset = c.data_shm_offset;
14930 
14931   const void* data;
14932   if (state_.bound_pixel_unpack_buffer.get()) {
14933     if (data_shm_id) {
14934       return error::kInvalidArguments;
14935     }
14936     data = reinterpret_cast<const void*>(data_shm_offset);
14937   } else {
14938     if (!data_shm_id && data_shm_offset) {
14939       return error::kInvalidArguments;
14940     }
14941     data = GetSharedMemoryAs<const void*>(
14942         data_shm_id, data_shm_offset, image_size);
14943   }
14944   return DoCompressedTexImage(target, level, internal_format, width, height,
14945                               depth, border, image_size, data,
14946                               ContextState::k3D);
14947 }
14948 
HandleCompressedTexSubImage3DBucket(uint32_t immediate_data_size,const volatile void * cmd_data)14949 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3DBucket(
14950     uint32_t immediate_data_size, const volatile void* cmd_data) {
14951   if (!feature_info_->IsWebGL2OrES3Context())
14952     return error::kUnknownCommand;
14953   const volatile gles2::cmds::CompressedTexSubImage3DBucket& c =
14954       *static_cast<const volatile gles2::cmds::CompressedTexSubImage3DBucket*>(
14955           cmd_data);
14956   GLenum target = static_cast<GLenum>(c.target);
14957   GLint level = static_cast<GLint>(c.level);
14958   GLint xoffset = static_cast<GLint>(c.xoffset);
14959   GLint yoffset = static_cast<GLint>(c.yoffset);
14960   GLint zoffset = static_cast<GLint>(c.zoffset);
14961   GLsizei width = static_cast<GLsizei>(c.width);
14962   GLsizei height = static_cast<GLsizei>(c.height);
14963   GLsizei depth = static_cast<GLsizei>(c.depth);
14964   GLenum format = static_cast<GLenum>(c.format);
14965   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
14966 
14967   if (state_.bound_pixel_unpack_buffer.get()) {
14968     return error::kInvalidArguments;
14969   }
14970   Bucket* bucket = GetBucket(bucket_id);
14971   if (!bucket)
14972     return error::kInvalidArguments;
14973   uint32_t image_size = bucket->size();
14974   const void* data = bucket->GetData(0, image_size);
14975   DCHECK(data || !image_size);
14976   return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset,
14977                                  width, height, depth, format, image_size,
14978                                  data, ContextState::k3D);
14979 }
14980 
HandleCompressedTexSubImage3D(uint32_t immediate_data_size,const volatile void * cmd_data)14981 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3D(
14982     uint32_t immediate_data_size, const volatile void* cmd_data) {
14983   if (!feature_info_->IsWebGL2OrES3Context())
14984     return error::kUnknownCommand;
14985   const volatile gles2::cmds::CompressedTexSubImage3D& c =
14986       *static_cast<const volatile gles2::cmds::CompressedTexSubImage3D*>(
14987           cmd_data);
14988   GLenum target = static_cast<GLenum>(c.target);
14989   GLint level = static_cast<GLint>(c.level);
14990   GLint xoffset = static_cast<GLint>(c.xoffset);
14991   GLint yoffset = static_cast<GLint>(c.yoffset);
14992   GLint zoffset = static_cast<GLint>(c.zoffset);
14993   GLsizei width = static_cast<GLsizei>(c.width);
14994   GLsizei height = static_cast<GLsizei>(c.height);
14995   GLsizei depth = static_cast<GLsizei>(c.depth);
14996   GLenum format = static_cast<GLenum>(c.format);
14997   GLsizei image_size = static_cast<GLsizei>(c.imageSize);
14998   uint32_t data_shm_id = c.data_shm_id;
14999   uint32_t data_shm_offset = c.data_shm_offset;
15000 
15001   const void* data;
15002   if (state_.bound_pixel_unpack_buffer.get()) {
15003     if (data_shm_id) {
15004       return error::kInvalidArguments;
15005     }
15006     data = reinterpret_cast<const void*>(data_shm_offset);
15007   } else {
15008     if (!data_shm_id && data_shm_offset) {
15009       return error::kInvalidArguments;
15010     }
15011     data = GetSharedMemoryAs<const void*>(
15012         data_shm_id, data_shm_offset, image_size);
15013   }
15014   return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset,
15015                                  width, height, depth, format, image_size,
15016                                  data, ContextState::k3D);
15017 }
15018 
DoCompressedTexImage(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei image_size,const void * data,ContextState::Dimension dimension)15019 error::Error GLES2DecoderImpl::DoCompressedTexImage(
15020     GLenum target, GLint level, GLenum internal_format, GLsizei width,
15021     GLsizei height, GLsizei depth, GLint border, GLsizei image_size,
15022     const void* data, ContextState::Dimension dimension) {
15023   const char* func_name;
15024   if (dimension == ContextState::k2D) {
15025     func_name = "glCompressedTexImage2D";
15026     if (!validators_->texture_target.IsValid(target)) {
15027       LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
15028       return error::kNoError;
15029     }
15030     // TODO(ccameron): Add a separate texture from |texture_target| for
15031     // [Compressed]Tex[Sub]Image2D and related functions.
15032     // http://crbug.com/536854
15033     if (target == GL_TEXTURE_RECTANGLE_ARB) {
15034       LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
15035       return error::kNoError;
15036     }
15037   } else {
15038     DCHECK_EQ(ContextState::k3D, dimension);
15039     func_name = "glCompressedTexImage3D";
15040     if (!validators_->texture_3_d_target.IsValid(target)) {
15041       LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
15042       return error::kNoError;
15043     }
15044   }
15045   if (!validators_->compressed_texture_format.IsValid(internal_format)) {
15046     LOCAL_SET_GL_ERROR_INVALID_ENUM(
15047         func_name, internal_format, "internalformat");
15048     return error::kNoError;
15049   }
15050   if (image_size < 0) {
15051     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
15052     return error::kNoError;
15053   }
15054   if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
15055       border != 0) {
15056     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
15057     return error::kNoError;
15058   }
15059   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
15060       &state_, target);
15061   if (!texture_ref) {
15062     LOCAL_SET_GL_ERROR(
15063         GL_INVALID_VALUE, func_name, "no texture bound at target");
15064     return error::kNoError;
15065   }
15066   Texture* texture = texture_ref->texture();
15067   if (texture->IsImmutable()) {
15068     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable");
15069     return error::kNoError;
15070   }
15071 
15072   if (!ValidateCompressedTexDimensions(func_name, target, level,
15073                                        width, height, depth, internal_format) ||
15074       !ValidateCompressedTexFuncData(func_name, width, height, depth,
15075                                      internal_format, image_size, data)) {
15076     return error::kNoError;
15077   }
15078 
15079   if (texture->IsAttachedToFramebuffer()) {
15080     framebuffer_state_.clear_state_dirty = true;
15081   }
15082 
15083   std::unique_ptr<int8_t[]> zero;
15084   if (!state_.bound_pixel_unpack_buffer && !data) {
15085     zero.reset(new int8_t[image_size]);
15086     memset(zero.get(), 0, image_size);
15087     data = zero.get();
15088   }
15089   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
15090   const CompressedFormatInfo* format_info =
15091       GetCompressedFormatInfo(internal_format);
15092   if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
15093     std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
15094         state_, *format_info, width, height, depth, image_size, data);
15095     if (!decompressed_data) {
15096       MarkContextLost(error::kGuilty);
15097       group_->LoseContexts(error::kInnocent);
15098       return error::kLostContext;
15099     }
15100     ScopedPixelUnpackState reset_restore(&state_);
15101     if (dimension == ContextState::k2D) {
15102       api()->glTexImage2DFn(
15103           target, level, format_info->decompressed_internal_format, width,
15104           height, border, format_info->decompressed_format,
15105           format_info->decompressed_type, decompressed_data.get());
15106     } else {
15107       api()->glTexImage3DFn(
15108           target, level, format_info->decompressed_internal_format, width,
15109           height, depth, border, format_info->decompressed_format,
15110           format_info->decompressed_type, decompressed_data.get());
15111     }
15112   } else {
15113     if (dimension == ContextState::k2D) {
15114       api()->glCompressedTexImage2DFn(target, level, internal_format, width,
15115                                       height, border, image_size, data);
15116     } else {
15117       api()->glCompressedTexImage3DFn(target, level, internal_format, width,
15118                                       height, depth, border, image_size, data);
15119     }
15120   }
15121   GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
15122   if (error == GL_NO_ERROR) {
15123     texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
15124                                     width, height, depth, border, 0, 0,
15125                                     gfx::Rect(width, height));
15126   }
15127 
15128   // This may be a slow command.  Exit command processing to allow for
15129   // context preemption and GPU watchdog checks.
15130   ExitCommandProcessingEarly();
15131   return error::kNoError;
15132 }
15133 
HandleTexImage2D(uint32_t immediate_data_size,const volatile void * cmd_data)15134 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size,
15135                                                 const volatile void* cmd_data) {
15136   const char* func_name = "glTexImage2D";
15137   const volatile gles2::cmds::TexImage2D& c =
15138       *static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data);
15139   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
15140       "width", c.width, "height", c.height);
15141   // Set as failed for now, but if it successed, this will be set to not failed.
15142   texture_state_.tex_image_failed = true;
15143   GLenum target = static_cast<GLenum>(c.target);
15144   GLint level = static_cast<GLint>(c.level);
15145   GLenum internal_format = static_cast<GLenum>(c.internalformat);
15146   GLsizei width = static_cast<GLsizei>(c.width);
15147   GLsizei height = static_cast<GLsizei>(c.height);
15148   GLint border = static_cast<GLint>(c.border);
15149   GLenum format = static_cast<GLenum>(c.format);
15150   GLenum type = static_cast<GLenum>(c.type);
15151   uint32_t pixels_shm_id = static_cast<uint32_t>(c.pixels_shm_id);
15152   uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset);
15153 
15154   if (width < 0 || height < 0) {
15155     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
15156     return error::kNoError;
15157   }
15158 
15159   PixelStoreParams params;
15160   Buffer* buffer = state_.bound_pixel_unpack_buffer.get();
15161   if (buffer) {
15162     if (pixels_shm_id)
15163       return error::kInvalidArguments;
15164     if (buffer->GetMappedRange()) {
15165       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
15166           "pixel unpack buffer should not be mapped to client memory");
15167       return error::kNoError;
15168     }
15169     params = state_.GetUnpackParams(ContextState::k2D);
15170   } else {
15171     if (!pixels_shm_id && pixels_shm_offset)
15172       return error::kInvalidArguments;
15173     // When reading from client buffer, the command buffer client side took
15174     // the responsibility to take the pixels from the client buffer and
15175     // unpack them according to the full ES3 pack parameters as source, all
15176     // parameters for 0 (except for alignment) as destination mem for the
15177     // service side.
15178     params.alignment = state_.unpack_alignment;
15179   }
15180   uint32_t pixels_size;
15181   uint32_t skip_size;
15182   uint32_t padding;
15183   if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1,
15184                                            format, type,
15185                                            params,
15186                                            &pixels_size,
15187                                            nullptr,
15188                                            nullptr,
15189                                            &skip_size,
15190                                            &padding)) {
15191     return error::kOutOfBounds;
15192   }
15193   DCHECK_EQ(0u, skip_size);
15194 
15195   const void* pixels;
15196   if (pixels_shm_id) {
15197     pixels = GetSharedMemoryAs<const void*>(
15198         pixels_shm_id, pixels_shm_offset, pixels_size);
15199     if (!pixels)
15200       return error::kOutOfBounds;
15201   } else {
15202     pixels = reinterpret_cast<const void*>(pixels_shm_offset);
15203   }
15204 
15205   // For testing only. Allows us to stress the ability to respond to OOM errors.
15206   uint32_t num_pixels;
15207   if (workarounds().simulate_out_of_memory_on_large_textures &&
15208       (!base::CheckMul(width, height).AssignIfValid(&num_pixels) ||
15209        (num_pixels >= 4096 * 4096))) {
15210     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "synthetic out of memory");
15211     return error::kNoError;
15212   }
15213 
15214   TextureManager::DoTexImageArguments args = {
15215       target,
15216       level,
15217       internal_format,
15218       width,
15219       height,
15220       1,
15221       border,
15222       format,
15223       type,
15224       pixels,
15225       pixels_size,
15226       padding,
15227       TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
15228   texture_manager()->ValidateAndDoTexImage(
15229       &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
15230       func_name, args);
15231 
15232   // This may be a slow command.  Exit command processing to allow for
15233   // context preemption and GPU watchdog checks.
15234   ExitCommandProcessingEarly();
15235   return error::kNoError;
15236 }
15237 
HandleTexImage3D(uint32_t immediate_data_size,const volatile void * cmd_data)15238 error::Error GLES2DecoderImpl::HandleTexImage3D(uint32_t immediate_data_size,
15239                                                 const volatile void* cmd_data) {
15240   if (!feature_info_->IsWebGL2OrES3Context())
15241     return error::kUnknownCommand;
15242 
15243   const char* func_name = "glTexImage3D";
15244   const volatile gles2::cmds::TexImage3D& c =
15245       *static_cast<const volatile gles2::cmds::TexImage3D*>(cmd_data);
15246   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
15247       "widthXheight", c.width * c.height, "depth", c.depth);
15248   // Set as failed for now, but if it successed, this will be set to not failed.
15249   texture_state_.tex_image_failed = true;
15250   GLenum target = static_cast<GLenum>(c.target);
15251   GLint level = static_cast<GLint>(c.level);
15252   GLenum internal_format = static_cast<GLenum>(c.internalformat);
15253   GLsizei width = static_cast<GLsizei>(c.width);
15254   GLsizei height = static_cast<GLsizei>(c.height);
15255   GLsizei depth = static_cast<GLsizei>(c.depth);
15256   GLint border = static_cast<GLint>(c.border);
15257   GLenum format = static_cast<GLenum>(c.format);
15258   GLenum type = static_cast<GLenum>(c.type);
15259   uint32_t pixels_shm_id = static_cast<uint32_t>(c.pixels_shm_id);
15260   uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset);
15261 
15262   if (width < 0 || height < 0 || depth < 0) {
15263     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
15264     return error::kNoError;
15265   }
15266 
15267   PixelStoreParams params;
15268   Buffer* buffer = state_.bound_pixel_unpack_buffer.get();
15269   if (buffer) {
15270     if (pixels_shm_id)
15271       return error::kInvalidArguments;
15272     if (buffer->GetMappedRange()) {
15273       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
15274           "pixel unpack buffer should not be mapped to client memory");
15275       return error::kNoError;
15276     }
15277     params = state_.GetUnpackParams(ContextState::k3D);
15278   } else {
15279     if (!pixels_shm_id && pixels_shm_offset)
15280       return error::kInvalidArguments;
15281     // When reading from client buffer, the command buffer client side took
15282     // the responsibility to take the pixels from the client buffer and
15283     // unpack them according to the full ES3 pack parameters as source, all
15284     // parameters for 0 (except for alignment) as destination mem for the
15285     // service side.
15286     params.alignment = state_.unpack_alignment;
15287   }
15288   uint32_t pixels_size;
15289   uint32_t skip_size;
15290   uint32_t padding;
15291   if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth,
15292                                            format, type,
15293                                            params,
15294                                            &pixels_size,
15295                                            nullptr,
15296                                            nullptr,
15297                                            &skip_size,
15298                                            &padding)) {
15299     return error::kOutOfBounds;
15300   }
15301   DCHECK_EQ(0u, skip_size);
15302 
15303   const void* pixels;
15304   if (pixels_shm_id) {
15305     pixels = GetSharedMemoryAs<const void*>(
15306         pixels_shm_id, pixels_shm_offset, pixels_size);
15307     if (!pixels)
15308       return error::kOutOfBounds;
15309   } else {
15310     pixels = reinterpret_cast<const void*>(pixels_shm_offset);
15311   }
15312 
15313   // For testing only. Allows us to stress the ability to respond to OOM errors.
15314   uint32_t num_pixels;
15315   if (workarounds().simulate_out_of_memory_on_large_textures &&
15316       (!base::CheckMul(width, height).AssignIfValid(&num_pixels) ||
15317        (num_pixels >= 4096 * 4096))) {
15318     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "synthetic out of memory");
15319     return error::kNoError;
15320   }
15321 
15322   TextureManager::DoTexImageArguments args = {
15323       target,
15324       level,
15325       internal_format,
15326       width,
15327       height,
15328       depth,
15329       border,
15330       format,
15331       type,
15332       pixels,
15333       pixels_size,
15334       padding,
15335       TextureManager::DoTexImageArguments::CommandType::kTexImage3D};
15336   texture_manager()->ValidateAndDoTexImage(
15337       &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
15338       func_name, args);
15339 
15340   // This may be a slow command.  Exit command processing to allow for
15341   // context preemption and GPU watchdog checks.
15342   ExitCommandProcessingEarly();
15343   return error::kNoError;
15344 }
15345 
HandleCompressedTexSubImage2DBucket(uint32_t immediate_data_size,const volatile void * cmd_data)15346 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
15347     uint32_t immediate_data_size, const volatile void* cmd_data) {
15348   const volatile gles2::cmds::CompressedTexSubImage2DBucket& c =
15349       *static_cast<const volatile gles2::cmds::CompressedTexSubImage2DBucket*>(
15350           cmd_data);
15351   GLenum target = static_cast<GLenum>(c.target);
15352   GLint level = static_cast<GLint>(c.level);
15353   GLint xoffset = static_cast<GLint>(c.xoffset);
15354   GLint yoffset = static_cast<GLint>(c.yoffset);
15355   GLsizei width = static_cast<GLsizei>(c.width);
15356   GLsizei height = static_cast<GLsizei>(c.height);
15357   GLenum format = static_cast<GLenum>(c.format);
15358   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
15359 
15360   if (state_.bound_pixel_unpack_buffer.get()) {
15361     return error::kInvalidArguments;
15362   }
15363   Bucket* bucket = GetBucket(bucket_id);
15364   if (!bucket)
15365     return error::kInvalidArguments;
15366   uint32_t image_size = bucket->size();
15367   const void* data = bucket->GetData(0, image_size);
15368   DCHECK(data || !image_size);
15369   return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0,
15370                                  width, height, 1, format, image_size, data,
15371                                  ContextState::k2D);
15372 }
15373 
HandleCompressedTexSubImage2D(uint32_t immediate_data_size,const volatile void * cmd_data)15374 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
15375     uint32_t immediate_data_size,
15376     const volatile void* cmd_data) {
15377   const volatile gles2::cmds::CompressedTexSubImage2D& c =
15378       *static_cast<const volatile gles2::cmds::CompressedTexSubImage2D*>(
15379           cmd_data);
15380   GLenum target = static_cast<GLenum>(c.target);
15381   GLint level = static_cast<GLint>(c.level);
15382   GLint xoffset = static_cast<GLint>(c.xoffset);
15383   GLint yoffset = static_cast<GLint>(c.yoffset);
15384   GLsizei width = static_cast<GLsizei>(c.width);
15385   GLsizei height = static_cast<GLsizei>(c.height);
15386   GLenum format = static_cast<GLenum>(c.format);
15387   GLsizei image_size = static_cast<GLsizei>(c.imageSize);
15388   uint32_t data_shm_id = c.data_shm_id;
15389   uint32_t data_shm_offset = c.data_shm_offset;
15390 
15391   const void* data;
15392   if (state_.bound_pixel_unpack_buffer.get()) {
15393     if (data_shm_id) {
15394       return error::kInvalidArguments;
15395     }
15396     data = reinterpret_cast<const void*>(data_shm_offset);
15397   } else {
15398     if (!data_shm_id) {
15399       return error::kInvalidArguments;
15400     }
15401     data = GetSharedMemoryAs<const void*>(
15402         data_shm_id, data_shm_offset, image_size);
15403   }
15404   return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0,
15405                                  width, height, 1, format, image_size, data,
15406                                  ContextState::k2D);
15407 }
15408 
DoCompressedTexSubImage(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei image_size,const void * data,ContextState::Dimension dimension)15409 error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
15410     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
15411     GLsizei width, GLsizei height, GLsizei depth, GLenum format,
15412     GLsizei image_size, const void * data, ContextState::Dimension dimension) {
15413   const char* func_name;
15414   if (dimension == ContextState::k2D) {
15415     func_name = "glCompressedTexSubImage2D";
15416     if (!validators_->texture_target.IsValid(target)) {
15417       LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
15418       return error::kNoError;
15419     }
15420   } else {
15421     DCHECK_EQ(ContextState::k3D, dimension);
15422     func_name = "glCompressedTexSubImage3D";
15423     if (!validators_->texture_3_d_target.IsValid(target)) {
15424       LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
15425       return error::kNoError;
15426     }
15427   }
15428   if (!validators_->compressed_texture_format.IsValid(format)) {
15429     LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format");
15430     return error::kNoError;
15431   }
15432   if (image_size < 0) {
15433     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
15434     return error::kNoError;
15435   }
15436   if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
15437     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
15438     return error::kNoError;
15439   }
15440   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
15441       &state_, target);
15442   if (!texture_ref) {
15443     LOCAL_SET_GL_ERROR(
15444         GL_INVALID_OPERATION, func_name, "no texture bound at target");
15445     return error::kNoError;
15446   }
15447   Texture* texture = texture_ref->texture();
15448   GLenum type = 0;
15449   GLenum internal_format = 0;
15450   if (!texture->GetLevelType(target, level, &type, &internal_format)) {
15451     std::string msg = base::StringPrintf("level %d does not exist", level);
15452     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, msg.c_str());
15453     return error::kNoError;
15454   }
15455   if (internal_format != format) {
15456     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
15457                        "format does not match internalformat.");
15458     return error::kNoError;
15459   }
15460   if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset,
15461                                 width, height, depth)) {
15462     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions.");
15463     return error::kNoError;
15464   }
15465 
15466   if (!ValidateCompressedTexFuncData(
15467           func_name, width, height, depth, format, image_size, data) ||
15468       !ValidateCompressedTexSubDimensions(
15469           func_name, target, level, xoffset, yoffset, zoffset,
15470           width, height, depth, format, texture)) {
15471     return error::kNoError;
15472   }
15473   if (image_size > 0 && !state_.bound_pixel_unpack_buffer && !data)
15474     return error::kInvalidArguments;
15475 
15476   if (!texture->IsLevelCleared(target, level)) {
15477     // This can only happen if the compressed texture was allocated
15478     // using TexStorage{2|3}D.
15479     DCHECK(texture->IsImmutable());
15480     GLsizei level_width = 0, level_height = 0, level_depth = 0;
15481     bool success = texture->GetLevelSize(
15482         target, level, &level_width, &level_height, &level_depth);
15483     DCHECK(success);
15484     if (xoffset == 0 && width == level_width &&
15485         yoffset == 0 && height == level_height &&
15486         zoffset == 0 && depth == level_depth) {
15487       // We can skip the clear if we're uploading the entire level.
15488       texture_manager()->SetLevelCleared(texture_ref, target, level, true);
15489     } else {
15490       texture_manager()->ClearTextureLevel(this, texture_ref, target, level);
15491     }
15492     DCHECK(texture->IsLevelCleared(target, level));
15493   }
15494 
15495   const CompressedFormatInfo* format_info =
15496       GetCompressedFormatInfo(internal_format);
15497   if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
15498     std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
15499         state_, *format_info, width, height, depth, image_size, data);
15500     if (!decompressed_data) {
15501       MarkContextLost(error::kGuilty);
15502       group_->LoseContexts(error::kInnocent);
15503       return error::kLostContext;
15504     }
15505     ScopedPixelUnpackState reset_restore(&state_);
15506     if (dimension == ContextState::k2D) {
15507       api()->glTexSubImage2DFn(target, level, xoffset, yoffset, width, height,
15508                                format_info->decompressed_format,
15509                                format_info->decompressed_type,
15510                                decompressed_data.get());
15511     } else {
15512       api()->glTexSubImage3DFn(target, level, xoffset, yoffset, zoffset, width,
15513                                height, depth, format_info->decompressed_format,
15514                                format_info->decompressed_type,
15515                                decompressed_data.get());
15516     }
15517   } else {
15518     if (dimension == ContextState::k2D) {
15519       api()->glCompressedTexSubImage2DFn(target, level, xoffset, yoffset, width,
15520                                          height, format, image_size, data);
15521     } else {
15522       api()->glCompressedTexSubImage3DFn(target, level, xoffset, yoffset,
15523                                          zoffset, width, height, depth, format,
15524                                          image_size, data);
15525     }
15526   }
15527 
15528   // This may be a slow command.  Exit command processing to allow for
15529   // context preemption and GPU watchdog checks.
15530   ExitCommandProcessingEarly();
15531   return error::kNoError;
15532 }
15533 
ValidateCopyTexFormat(const char * func_name,GLenum internal_format,GLenum read_format,GLenum read_type)15534 bool GLES2DecoderImpl::ValidateCopyTexFormat(const char* func_name,
15535                                              GLenum internal_format,
15536                                              GLenum read_format,
15537                                              GLenum read_type) {
15538   std::string output_error_msg;
15539   if (!ValidateCopyTexFormatHelper(GetFeatureInfo(), internal_format,
15540                                    read_format, read_type, &output_error_msg)) {
15541     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
15542                        output_error_msg.c_str());
15543     return false;
15544   }
15545   return true;
15546 }
15547 
DoCopyTexImage2D(GLenum target,GLint level,GLenum internal_format,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)15548 void GLES2DecoderImpl::DoCopyTexImage2D(
15549     GLenum target,
15550     GLint level,
15551     GLenum internal_format,
15552     GLint x,
15553     GLint y,
15554     GLsizei width,
15555     GLsizei height,
15556     GLint border) {
15557   const char* func_name = "glCopyTexImage2D";
15558   DCHECK(!ShouldDeferReads());
15559   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
15560       &state_, target);
15561   if (!texture_ref) {
15562     LOCAL_SET_GL_ERROR(
15563         GL_INVALID_OPERATION, func_name, "unknown texture for target");
15564     return;
15565   }
15566   Texture* texture = texture_ref->texture();
15567   if (texture->IsImmutable()) {
15568     LOCAL_SET_GL_ERROR(
15569         GL_INVALID_OPERATION, func_name, "texture is immutable");
15570     return;
15571   }
15572   if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
15573       border != 0) {
15574     LOCAL_SET_GL_ERROR(
15575         GL_INVALID_VALUE, func_name, "dimensions out of range");
15576     return;
15577   }
15578 
15579   if (!CheckBoundReadFramebufferValid(func_name,
15580                                       GL_INVALID_FRAMEBUFFER_OPERATION)) {
15581     return;
15582   }
15583 
15584   GLenum read_format = GetBoundReadFramebufferInternalFormat();
15585   GLenum read_type = GetBoundReadFramebufferTextureType();
15586   if (!ValidateCopyTexFormat(func_name, internal_format,
15587                              read_format, read_type)) {
15588     return;
15589   }
15590 
15591   uint32_t pixels_size = 0;
15592   // TODO(piman): OpenGL ES 3.0.4 Section 3.8.5 specifies how to pick an
15593   // effective internal format if internal_format is unsized, which is a fairly
15594   // involved logic. For now, just make sure we pick something valid.
15595   GLenum format =
15596       TextureManager::ExtractFormatFromStorageFormat(internal_format);
15597   GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
15598   bool internal_format_unsized = internal_format == format;
15599   // The picks made by the temporary logic above may not be valid on ES3.
15600   // This if-block checks the temporary logic and should be removed with it.
15601   if (internal_format_unsized && feature_info_->IsWebGL2OrES3Context()) {
15602     // While there are other possible types for unsized formats (cf. OpenGL ES
15603     // 3.0.5, section 3.7, table 3.3, page 113), they won't appear here.
15604     // ExtractTypeFromStorageFormat will always return UNSIGNED_BYTE for
15605     // unsized formats.
15606     DCHECK(type == GL_UNSIGNED_BYTE);
15607     switch (internal_format) {
15608       case GL_RGB:
15609       case GL_RGBA:
15610       case GL_LUMINANCE_ALPHA:
15611       case GL_LUMINANCE:
15612       case GL_ALPHA:
15613       case GL_BGRA_EXT:
15614         break;
15615       default:
15616         // Other unsized internal_formats are invalid in ES3.
15617         format = GL_NONE;
15618         break;
15619     }
15620   }
15621   if (!format || !type) {
15622     LOCAL_SET_GL_ERROR(
15623         GL_INVALID_OPERATION,
15624         func_name, "Invalid unsized internal format.");
15625     return;
15626   }
15627 
15628   DCHECK(texture_manager()->ValidateTextureParameters(
15629       error_state_.get(), func_name, true, format, type, internal_format,
15630       level));
15631 
15632   // Only target image size is validated here.
15633   if (!GLES2Util::ComputeImageDataSizes(width, height, 1, format, type,
15634                                         state_.unpack_alignment, &pixels_size,
15635                                         nullptr, nullptr)) {
15636     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "dimensions too large");
15637     return;
15638   }
15639 
15640   if (FormsTextureCopyingFeedbackLoop(texture_ref, level, 0)) {
15641     LOCAL_SET_GL_ERROR(
15642         GL_INVALID_OPERATION,
15643         func_name, "source and destination textures are the same");
15644     return;
15645   }
15646 
15647   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
15648   ScopedResolvedFramebufferBinder binder(this, false, true);
15649   gfx::Size size = GetBoundReadFramebufferSize();
15650 
15651   if (texture->IsAttachedToFramebuffer()) {
15652     framebuffer_state_.clear_state_dirty = true;
15653   }
15654 
15655   bool requires_luma_blit =
15656       CopyTexImageResourceManager::CopyTexImageRequiresBlit(feature_info_.get(),
15657                                                             format);
15658   if (requires_luma_blit &&
15659       !InitializeCopyTexImageBlitter(func_name)) {
15660     return;
15661   }
15662 
15663   // If fbo's read buffer and the target texture are the same texture, but
15664   // different levels, and if the read buffer is non-base texture level,
15665   // then following internal glTexImage2D() calls may change the target texture
15666   // and make the originally mipmap complete texture mipmap incomplete, which
15667   // in turn make the fbo incomplete.
15668   // In order to avoid that, we clamp the BASE_LEVEL and MAX_LEVEL to the same
15669   // texture level that's attached to the fbo's read buffer.
15670   bool reset_source_texture_base_level_max_level = false;
15671   GLint attached_texture_level = -1;
15672   Framebuffer* framebuffer = GetBoundReadFramebuffer();
15673   if (framebuffer) {
15674     const Framebuffer::Attachment* attachment =
15675         framebuffer->GetReadBufferAttachment();
15676     if (attachment->IsTexture(texture_ref)) {
15677       DCHECK(attachment->IsTextureAttachment());
15678       attached_texture_level = attachment->level();
15679       DCHECK_GE(attached_texture_level, 0);
15680       if (attached_texture_level != texture->base_level())
15681         reset_source_texture_base_level_max_level = true;
15682     }
15683   }
15684   if (reset_source_texture_base_level_max_level) {
15685     api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
15686                              attached_texture_level);
15687     api()->glTexParameteriFn(target, GL_TEXTURE_MAX_LEVEL,
15688                              attached_texture_level);
15689   }
15690 
15691   // Clip to size to source dimensions
15692   gfx::Rect src(x, y, width, height);
15693   const gfx::Rect dst(0, 0, size.width(), size.height());
15694   src.Intersect(dst);
15695 
15696   GLenum final_internal_format = TextureManager::AdjustTexInternalFormat(
15697       feature_info_.get(), internal_format, type);
15698   if (workarounds().force_int_or_srgb_cube_texture_complete &&
15699       texture->target() == GL_TEXTURE_CUBE_MAP &&
15700       (GLES2Util::IsIntegerFormat(final_internal_format) ||
15701        GLES2Util::GetColorEncodingFromInternalFormat(final_internal_format) ==
15702            GL_SRGB)) {
15703     TextureManager::DoTexImageArguments args = {
15704         target,
15705         level,
15706         final_internal_format,
15707         width,
15708         height,
15709         1,
15710         border,
15711         format,
15712         type,
15713         nullptr,
15714         pixels_size,
15715         0,
15716         TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
15717     texture_manager()->WorkaroundCopyTexImageCubeMap(
15718         &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
15719         texture_ref, func_name, args);
15720   }
15721 
15722   if (src.x() != x || src.y() != y ||
15723       src.width() != width || src.height() != height ||
15724       final_internal_format == GL_BGRA_EXT) {
15725     // GL_BGRA_EXT is not allowed as internalformat for glCopyTexImage2D,
15726     // which is a bit of a quirk in the spec, but this path works.
15727     {
15728       // Add extra scope to destroy zero and the object it owns right
15729       // after its usage.
15730       // some part was clipped so clear the rect.
15731 
15732       std::unique_ptr<char[]> zero(new char[pixels_size]);
15733       memset(zero.get(), 0, pixels_size);
15734       ScopedPixelUnpackState reset_restore(&state_);
15735       api()->glTexImage2DFn(target, level, final_internal_format, width, height,
15736                             border, format, type, zero.get());
15737     }
15738 
15739     if (!src.IsEmpty()) {
15740       GLint destX = src.x() - x;
15741       GLint destY = src.y() - y;
15742       if (requires_luma_blit) {
15743         copy_tex_image_blit_->DoCopyTexSubImageToLUMACompatibilityTexture(
15744             this, texture->service_id(), texture->target(), target, format,
15745             type, level, destX, destY, 0,
15746             src.x(), src.y(), src.width(), src.height(),
15747             GetBoundReadFramebufferServiceId(),
15748             GetBoundReadFramebufferInternalFormat());
15749       } else {
15750         api()->glCopyTexSubImage2DFn(target, level, destX, destY, src.x(),
15751                                      src.y(), src.width(), src.height());
15752       }
15753     }
15754   } else {
15755     if (workarounds().init_two_cube_map_levels_before_copyteximage &&
15756         texture->target() == GL_TEXTURE_CUBE_MAP &&
15757         target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) {
15758       for (int i = 0; i < 2; ++i) {
15759         TextureManager::DoTexImageArguments args = {
15760             target,
15761             i,
15762             final_internal_format,
15763             width,
15764             height,
15765             1,
15766             border,
15767             format,
15768             type,
15769             nullptr,
15770             pixels_size,
15771             0,
15772             TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
15773         texture_manager()->WorkaroundCopyTexImageCubeMap(
15774             &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
15775             texture_ref, func_name, args);
15776       }
15777     }
15778 
15779     // The service id and target of the texture attached to READ_FRAMEBUFFER.
15780     GLuint source_texture_service_id = 0;
15781     GLenum source_texture_target = 0;
15782     uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
15783     bool use_workaround = NeedsCopyTextureImageWorkaround(
15784         final_internal_format, channels_exist, &source_texture_service_id,
15785         &source_texture_target);
15786     if (requires_luma_blit) {
15787       copy_tex_image_blit_->DoCopyTexImage2DToLUMACompatibilityTexture(
15788           this, texture->service_id(), texture->target(), target, format,
15789           type, level, internal_format, x, y, width, height,
15790           GetBoundReadFramebufferServiceId(),
15791           GetBoundReadFramebufferInternalFormat());
15792     } else if (use_workaround) {
15793       GLenum dest_texture_target = target;
15794       GLenum framebuffer_target = GetReadFramebufferTarget();
15795 
15796       GLenum temp_internal_format = 0;
15797       if (channels_exist == GLES2Util::kRGBA) {
15798         temp_internal_format = GL_RGBA;
15799       } else if (channels_exist == GLES2Util::kRGB) {
15800         temp_internal_format = GL_RGB;
15801       } else {
15802         NOTREACHED();
15803       }
15804 
15805       if (workarounds().clear_pixel_unpack_buffer_before_copyteximage)
15806         state_.PushTextureUnpackState();
15807       GLuint temp_texture;
15808       {
15809         // Copy from the read framebuffer into |temp_texture|.
15810         api()->glGenTexturesFn(1, &temp_texture);
15811         ScopedTextureBinder texture_binder(&state_, error_state_.get(),
15812                                            temp_texture, source_texture_target);
15813         api()->glCopyTexImage2DFn(source_texture_target, 0,
15814                                   temp_internal_format, x, y, width, height,
15815                                   border);
15816 
15817         // Attach the temp texture to the read framebuffer.
15818         api()->glFramebufferTexture2DEXTFn(
15819             framebuffer_target, GL_COLOR_ATTACHMENT0, source_texture_target,
15820             temp_texture, 0);
15821       }
15822 
15823       // Copy to the final texture.
15824       DCHECK_EQ(static_cast<GLuint>(GL_TEXTURE_2D), dest_texture_target);
15825       api()->glCopyTexImage2DFn(dest_texture_target, level,
15826                                 final_internal_format, 0, 0, width, height, 0);
15827 
15828       // Rebind source texture.
15829       api()->glFramebufferTexture2DEXTFn(
15830           framebuffer_target, GL_COLOR_ATTACHMENT0, source_texture_target,
15831           source_texture_service_id, 0);
15832       if (workarounds().clear_pixel_unpack_buffer_before_copyteximage)
15833         state_.RestoreUnpackState();
15834 
15835       api()->glDeleteTexturesFn(1, &temp_texture);
15836     } else {
15837       if (workarounds().init_one_cube_map_level_before_copyteximage &&
15838           texture->target() == GL_TEXTURE_CUBE_MAP &&
15839           target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) {
15840         TextureManager::DoTexImageArguments args = {
15841             target,
15842             level,
15843             final_internal_format,
15844             width,
15845             height,
15846             1,
15847             border,
15848             format,
15849             type,
15850             nullptr,
15851             pixels_size,
15852             0,
15853             TextureManager::DoTexImageArguments::CommandType::kTexImage2D};
15854         texture_manager()->WorkaroundCopyTexImageCubeMap(
15855             &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
15856             texture_ref, func_name, args);
15857       }
15858       if (workarounds().clear_pixel_unpack_buffer_before_copyteximage)
15859         state_.PushTextureUnpackState();
15860       api()->glCopyTexImage2DFn(target, level, final_internal_format, x, y,
15861                                 width, height, border);
15862       if (workarounds().clear_pixel_unpack_buffer_before_copyteximage)
15863         state_.RestoreUnpackState();
15864     }
15865   }
15866   if (reset_source_texture_base_level_max_level) {
15867     api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
15868                              texture->base_level());
15869     api()->glTexParameteriFn(target, GL_TEXTURE_MAX_LEVEL,
15870                              texture->max_level());
15871   }
15872   GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
15873   if (error == GL_NO_ERROR) {
15874     texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
15875                                     width, height, 1, border, format,
15876                                     type, gfx::Rect(width, height));
15877     texture->ApplyFormatWorkarounds(feature_info_.get());
15878   }
15879 
15880   // This may be a slow command.  Exit command processing to allow for
15881   // context preemption and GPU watchdog checks.
15882   ExitCommandProcessingEarly();
15883 }
15884 
DoCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)15885 void GLES2DecoderImpl::DoCopyTexSubImage2D(
15886     GLenum target,
15887     GLint level,
15888     GLint xoffset,
15889     GLint yoffset,
15890     GLint x,
15891     GLint y,
15892     GLsizei width,
15893     GLsizei height) {
15894   const char* func_name = "glCopyTexSubImage2D";
15895   DCHECK(!ShouldDeferReads());
15896   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
15897       &state_, target);
15898   if (!texture_ref) {
15899     LOCAL_SET_GL_ERROR(
15900         GL_INVALID_OPERATION, func_name, "unknown texture for target");
15901     return;
15902   }
15903   Texture* texture = texture_ref->texture();
15904   GLenum type = 0;
15905   GLenum internal_format = 0;
15906   if (!texture->GetLevelType(target, level, &type, &internal_format) ||
15907       !texture->ValidForTexture(
15908           target, level, xoffset, yoffset, 0, width, height, 1)) {
15909     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions.");
15910     return;
15911   }
15912 
15913   if (!CheckBoundReadFramebufferValid(func_name,
15914                                       GL_INVALID_FRAMEBUFFER_OPERATION)) {
15915     return;
15916   }
15917 
15918   GLenum read_format = GetBoundReadFramebufferInternalFormat();
15919   GLenum read_type = GetBoundReadFramebufferTextureType();
15920   if (!ValidateCopyTexFormat(func_name, internal_format,
15921                              read_format, read_type)) {
15922     return;
15923   }
15924 
15925   if (FormsTextureCopyingFeedbackLoop(texture_ref, level, 0)) {
15926     LOCAL_SET_GL_ERROR(
15927         GL_INVALID_OPERATION,
15928         func_name, "source and destination textures are the same");
15929     return;
15930   }
15931 
15932   ScopedResolvedFramebufferBinder binder(this, false, true);
15933   gfx::Size size = GetBoundReadFramebufferSize();
15934 
15935   gfx::Rect src(x, y, width, height);
15936   const gfx::Rect dst(0, 0, size.width(), size.height());
15937   src.Intersect(dst);
15938 
15939   if (src.IsEmpty())
15940     return;
15941 
15942   GLint dx = src.x() - x;
15943   GLint dy = src.y() - y;
15944   GLint destX = xoffset + dx;
15945   GLint destY = yoffset + dy;
15946   // It's only legal to skip clearing the level of the target texture
15947   // if the entire level is being redefined.
15948   GLsizei level_width = 0;
15949   GLsizei level_height = 0;
15950   GLsizei level_depth = 0;
15951   bool have_level = texture->GetLevelSize(
15952       target, level, &level_width, &level_height, &level_depth);
15953   // Validated above.
15954   DCHECK(have_level);
15955   if (destX == 0 && destY == 0 &&
15956       src.width() == level_width && src.height() == level_height) {
15957     // Write all pixels in below.
15958     texture_manager()->SetLevelCleared(texture_ref, target, level, true);
15959   } else {
15960     gfx::Rect cleared_rect;
15961     if (TextureManager::CombineAdjacentRects(
15962             texture->GetLevelClearedRect(target, level),
15963             gfx::Rect(destX, destY, src.width(), src.height()),
15964             &cleared_rect)) {
15965       DCHECK_GE(cleared_rect.size().GetArea(),
15966                 texture->GetLevelClearedRect(target, level).size().GetArea());
15967       texture_manager()->SetLevelClearedRect(texture_ref, target, level,
15968                                              cleared_rect);
15969     } else {
15970       // Otherwise clear part of texture level that is not already cleared.
15971       if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
15972                                                 level)) {
15973         LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "dimensions too big");
15974         return;
15975       }
15976     }
15977   }
15978 
15979   if (CopyTexImageResourceManager::CopyTexImageRequiresBlit(
15980           feature_info_.get(), internal_format)) {
15981     if (!InitializeCopyTexImageBlitter("glCopyTexSubImage2D")) {
15982       return;
15983     }
15984     copy_tex_image_blit_->DoCopyTexSubImageToLUMACompatibilityTexture(
15985         this, texture->service_id(), texture->target(), target,
15986         internal_format, type, level, destX, destY, 0,
15987         src.x(), src.y(), src.width(), src.height(),
15988         GetBoundReadFramebufferServiceId(),
15989         GetBoundReadFramebufferInternalFormat());
15990   } else {
15991     api()->glCopyTexSubImage2DFn(target, level, destX, destY, src.x(), src.y(),
15992                                  src.width(), src.height());
15993   }
15994 
15995   // This may be a slow command.  Exit command processing to allow for
15996   // context preemption and GPU watchdog checks.
15997   ExitCommandProcessingEarly();
15998 }
15999 
DoCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)16000 void GLES2DecoderImpl::DoCopyTexSubImage3D(
16001     GLenum target,
16002     GLint level,
16003     GLint xoffset,
16004     GLint yoffset,
16005     GLint zoffset,
16006     GLint x,
16007     GLint y,
16008     GLsizei width,
16009     GLsizei height) {
16010   const char* func_name = "glCopyTexSubImage3D";
16011   DCHECK(!ShouldDeferReads());
16012   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
16013       &state_, target);
16014   if (!texture_ref) {
16015     LOCAL_SET_GL_ERROR(
16016         GL_INVALID_OPERATION, func_name, "unknown texture for target");
16017     return;
16018   }
16019   Texture* texture = texture_ref->texture();
16020   GLenum type = 0;
16021   GLenum internal_format = 0;
16022   if (!texture->GetLevelType(target, level, &type, &internal_format) ||
16023       !texture->ValidForTexture(
16024           target, level, xoffset, yoffset, zoffset, width, height, 1)) {
16025     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions.");
16026     return;
16027   }
16028 
16029   if (!CheckBoundReadFramebufferValid(func_name,
16030                                       GL_INVALID_FRAMEBUFFER_OPERATION)) {
16031     return;
16032   }
16033 
16034   GLenum read_format = GetBoundReadFramebufferInternalFormat();
16035   GLenum read_type = GetBoundReadFramebufferTextureType();
16036   if (!ValidateCopyTexFormat(func_name, internal_format,
16037                              read_format, read_type)) {
16038     return;
16039   }
16040 
16041   if (FormsTextureCopyingFeedbackLoop(texture_ref, level, zoffset)) {
16042     LOCAL_SET_GL_ERROR(
16043         GL_INVALID_OPERATION,
16044         func_name, "source and destination textures are the same");
16045     return;
16046   }
16047 
16048   ScopedResolvedFramebufferBinder binder(this, false, true);
16049   gfx::Size size = GetBoundReadFramebufferSize();
16050 
16051   gfx::Rect src(x, y, width, height);
16052   const gfx::Rect dst(0, 0, size.width(), size.height());
16053   src.Intersect(dst);
16054   if (src.IsEmpty())
16055     return;
16056 
16057   GLint dx = src.x() - x;
16058   GLint dy = src.y() - y;
16059   GLint destX = xoffset + dx;
16060   GLint destY = yoffset + dy;
16061   // For 3D textures, we always clear the entire texture to 0 if it is not
16062   // cleared. See the code in TextureManager::ValidateAndDoTexSubImage
16063   // for TexSubImage3D.
16064   if (!texture->IsLevelCleared(target, level)) {
16065     if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
16066                                               level)) {
16067       LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "dimensions too big");
16068       return;
16069     }
16070     DCHECK(texture->IsLevelCleared(target, level));
16071   }
16072 
16073   if (CopyTexImageResourceManager::CopyTexImageRequiresBlit(
16074           feature_info_.get(), internal_format)) {
16075     if (!InitializeCopyTexImageBlitter(func_name)) {
16076       return;
16077     }
16078     copy_tex_image_blit_->DoCopyTexSubImageToLUMACompatibilityTexture(
16079         this, texture->service_id(), texture->target(), target,
16080         internal_format, type, level, destX, destY, zoffset,
16081         src.x(), src.y(), src.width(), src.height(),
16082         GetBoundReadFramebufferServiceId(),
16083         GetBoundReadFramebufferInternalFormat());
16084   } else {
16085     api()->glCopyTexSubImage3DFn(target, level, destX, destY, zoffset, src.x(),
16086                                  src.y(), src.width(), src.height());
16087   }
16088 
16089   // This may be a slow command.  Exit command processing to allow for
16090   // context preemption and GPU watchdog checks.
16091   ExitCommandProcessingEarly();
16092 }
16093 
HandleTexSubImage2D(uint32_t immediate_data_size,const volatile void * cmd_data)16094 error::Error GLES2DecoderImpl::HandleTexSubImage2D(
16095     uint32_t immediate_data_size, const volatile void* cmd_data) {
16096   const char* func_name = "glTexSubImage2D";
16097   const volatile gles2::cmds::TexSubImage2D& c =
16098       *static_cast<const volatile gles2::cmds::TexSubImage2D*>(cmd_data);
16099   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
16100       "width", c.width, "height", c.height);
16101   GLboolean internal = static_cast<GLboolean>(c.internal);
16102   if (internal == GL_TRUE && texture_state_.tex_image_failed)
16103     return error::kNoError;
16104 
16105   GLenum target = static_cast<GLenum>(c.target);
16106   GLint level = static_cast<GLint>(c.level);
16107   GLint xoffset = static_cast<GLint>(c.xoffset);
16108   GLint yoffset = static_cast<GLint>(c.yoffset);
16109   GLsizei width = static_cast<GLsizei>(c.width);
16110   GLsizei height = static_cast<GLsizei>(c.height);
16111   GLenum format = static_cast<GLenum>(c.format);
16112   GLenum type = static_cast<GLenum>(c.type);
16113   uint32_t pixels_shm_id = static_cast<uint32_t>(c.pixels_shm_id);
16114   uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset);
16115 
16116   if (width < 0 || height < 0) {
16117     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
16118     return error::kNoError;
16119   }
16120 
16121   PixelStoreParams params;
16122   Buffer* buffer = state_.bound_pixel_unpack_buffer.get();
16123   if (buffer) {
16124     if (pixels_shm_id)
16125       return error::kInvalidArguments;
16126     if (buffer->GetMappedRange()) {
16127       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16128           "pixel unpack buffer should not be mapped to client memory");
16129       return error::kNoError;
16130     }
16131     params = state_.GetUnpackParams(ContextState::k2D);
16132   } else {
16133     if (!pixels_shm_id && pixels_shm_offset)
16134       return error::kInvalidArguments;
16135     // When reading from client buffer, the command buffer client side took
16136     // the responsibility to take the pixels from the client buffer and
16137     // unpack them according to the full ES3 pack parameters as source, all
16138     // parameters for 0 (except for alignment) as destination mem for the
16139     // service side.
16140     params.alignment = state_.unpack_alignment;
16141   }
16142   uint32_t pixels_size;
16143   uint32_t skip_size;
16144   uint32_t padding;
16145   if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1,
16146                                            format, type,
16147                                            params,
16148                                            &pixels_size,
16149                                            nullptr,
16150                                            nullptr,
16151                                            &skip_size,
16152                                            &padding)) {
16153     return error::kOutOfBounds;
16154   }
16155   DCHECK_EQ(0u, skip_size);
16156 
16157   const void* pixels;
16158   if (pixels_shm_id) {
16159     pixels = GetSharedMemoryAs<const void*>(
16160         pixels_shm_id, pixels_shm_offset, pixels_size);
16161     if (!pixels)
16162       return error::kOutOfBounds;
16163   } else {
16164     DCHECK(buffer || !pixels_shm_offset);
16165     pixels = reinterpret_cast<const void*>(pixels_shm_offset);
16166   }
16167 
16168   TextureManager::DoTexSubImageArguments args = {
16169       target,
16170       level,
16171       xoffset,
16172       yoffset,
16173       0,
16174       width,
16175       height,
16176       1,
16177       format,
16178       type,
16179       pixels,
16180       pixels_size,
16181       padding,
16182       TextureManager::DoTexSubImageArguments::CommandType::kTexSubImage2D};
16183   texture_manager()->ValidateAndDoTexSubImage(
16184       this, &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
16185       func_name, args);
16186 
16187   // This may be a slow command.  Exit command processing to allow for
16188   // context preemption and GPU watchdog checks.
16189   ExitCommandProcessingEarly();
16190   return error::kNoError;
16191 }
16192 
HandleTexSubImage3D(uint32_t immediate_data_size,const volatile void * cmd_data)16193 error::Error GLES2DecoderImpl::HandleTexSubImage3D(
16194     uint32_t immediate_data_size,
16195     const volatile void* cmd_data) {
16196   if (!feature_info_->IsWebGL2OrES3Context())
16197     return error::kUnknownCommand;
16198 
16199   const char* func_name = "glTexSubImage3D";
16200   const volatile gles2::cmds::TexSubImage3D& c =
16201       *static_cast<const volatile gles2::cmds::TexSubImage3D*>(cmd_data);
16202   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
16203       "widthXheight", c.width * c.height, "depth", c.depth);
16204   GLboolean internal = static_cast<GLboolean>(c.internal);
16205   if (internal == GL_TRUE && texture_state_.tex_image_failed)
16206     return error::kNoError;
16207 
16208   GLenum target = static_cast<GLenum>(c.target);
16209   GLint level = static_cast<GLint>(c.level);
16210   GLint xoffset = static_cast<GLint>(c.xoffset);
16211   GLint yoffset = static_cast<GLint>(c.yoffset);
16212   GLint zoffset = static_cast<GLint>(c.zoffset);
16213   GLsizei width = static_cast<GLsizei>(c.width);
16214   GLsizei height = static_cast<GLsizei>(c.height);
16215   GLsizei depth = static_cast<GLsizei>(c.depth);
16216   GLenum format = static_cast<GLenum>(c.format);
16217   GLenum type = static_cast<GLenum>(c.type);
16218   uint32_t pixels_shm_id = static_cast<uint32_t>(c.pixels_shm_id);
16219   uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset);
16220 
16221   if (width < 0 || height < 0 || depth < 0) {
16222     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
16223     return error::kNoError;
16224   }
16225 
16226   PixelStoreParams params;
16227   Buffer* buffer = state_.bound_pixel_unpack_buffer.get();
16228   if (buffer) {
16229     if (pixels_shm_id)
16230       return error::kInvalidArguments;
16231     if (buffer->GetMappedRange()) {
16232       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16233           "pixel unpack buffer should not be mapped to client memory");
16234       return error::kNoError;
16235     }
16236     params = state_.GetUnpackParams(ContextState::k3D);
16237   } else {
16238     if (!pixels_shm_id && pixels_shm_offset)
16239       return error::kInvalidArguments;
16240     // When reading from client buffer, the command buffer client side took
16241     // the responsibility to take the pixels from the client buffer and
16242     // unpack them according to the full ES3 pack parameters as source, all
16243     // parameters for 0 (except for alignment) as destination mem for the
16244     // service side.
16245     params.alignment = state_.unpack_alignment;
16246   }
16247   uint32_t pixels_size;
16248   uint32_t skip_size;
16249   uint32_t padding;
16250   if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth,
16251                                            format, type,
16252                                            params,
16253                                            &pixels_size,
16254                                            nullptr,
16255                                            nullptr,
16256                                            &skip_size,
16257                                            &padding)) {
16258     return error::kOutOfBounds;
16259   }
16260   DCHECK_EQ(0u, skip_size);
16261 
16262   const void* pixels;
16263   if (pixels_shm_id) {
16264     pixels = GetSharedMemoryAs<const void*>(
16265         pixels_shm_id, pixels_shm_offset, pixels_size);
16266     if (!pixels)
16267       return error::kOutOfBounds;
16268   } else {
16269     DCHECK(buffer || !pixels_shm_offset);
16270     pixels = reinterpret_cast<const void*>(pixels_shm_offset);
16271   }
16272 
16273   TextureManager::DoTexSubImageArguments args = {
16274       target,
16275       level,
16276       xoffset,
16277       yoffset,
16278       zoffset,
16279       width,
16280       height,
16281       depth,
16282       format,
16283       type,
16284       pixels,
16285       pixels_size,
16286       padding,
16287       TextureManager::DoTexSubImageArguments::CommandType::kTexSubImage3D};
16288   texture_manager()->ValidateAndDoTexSubImage(
16289       this, &texture_state_, &state_, error_state_.get(), &framebuffer_state_,
16290       func_name, args);
16291 
16292   // This may be a slow command.  Exit command processing to allow for
16293   // context preemption and GPU watchdog checks.
16294   ExitCommandProcessingEarly();
16295   return error::kNoError;
16296 }
16297 
HandleGetVertexAttribPointerv(uint32_t immediate_data_size,const volatile void * cmd_data)16298 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
16299     uint32_t immediate_data_size,
16300     const volatile void* cmd_data) {
16301   const volatile gles2::cmds::GetVertexAttribPointerv& c =
16302       *static_cast<const volatile gles2::cmds::GetVertexAttribPointerv*>(
16303           cmd_data);
16304   GLuint index = static_cast<GLuint>(c.index);
16305   GLenum pname = static_cast<GLenum>(c.pname);
16306   typedef cmds::GetVertexAttribPointerv::Result Result;
16307   Result* result =
16308       GetSharedMemoryAs<Result*>(c.pointer_shm_id, c.pointer_shm_offset,
16309                                  Result::ComputeSize(1).ValueOrDie());
16310   if (!result) {
16311     return error::kOutOfBounds;
16312   }
16313   // Check that the client initialized the result.
16314   if (result->size != 0) {
16315     return error::kInvalidArguments;
16316   }
16317   if (!validators_->vertex_pointer.IsValid(pname)) {
16318     LOCAL_SET_GL_ERROR_INVALID_ENUM(
16319         "glGetVertexAttribPointerv", pname, "pname");
16320     return error::kNoError;
16321   }
16322   if (index >= group_->max_vertex_attribs()) {
16323     LOCAL_SET_GL_ERROR(
16324         GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
16325     return error::kNoError;
16326   }
16327   result->SetNumResults(1);
16328   *result->GetData() =
16329       state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
16330   return error::kNoError;
16331 }
16332 
16333 template <class T>
GetUniformSetup(GLuint program_id,GLint fake_location,uint32_t shm_id,uint32_t shm_offset,error::Error * error,GLint * real_location,GLuint * service_id,SizedResult<T> ** result_pointer,GLenum * result_type,GLsizei * result_size)16334 bool GLES2DecoderImpl::GetUniformSetup(GLuint program_id,
16335                                        GLint fake_location,
16336                                        uint32_t shm_id,
16337                                        uint32_t shm_offset,
16338                                        error::Error* error,
16339                                        GLint* real_location,
16340                                        GLuint* service_id,
16341                                        SizedResult<T>** result_pointer,
16342                                        GLenum* result_type,
16343                                        GLsizei* result_size) {
16344   DCHECK(error);
16345   DCHECK(service_id);
16346   DCHECK(result_pointer);
16347   DCHECK(result_type);
16348   DCHECK(result_size);
16349   DCHECK(real_location);
16350   *error = error::kNoError;
16351   // Make sure we have enough room for the result on failure.
16352   SizedResult<T>* result;
16353   result = GetSharedMemoryAs<SizedResult<T>*>(
16354       shm_id, shm_offset, SizedResult<T>::ComputeSize(0).ValueOrDie());
16355   if (!result) {
16356     *error = error::kOutOfBounds;
16357     return false;
16358   }
16359   *result_pointer = result;
16360   // Set the result size to 0 so the client does not have to check for success.
16361   result->SetNumResults(0);
16362   Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
16363   if (!program) {
16364     return false;
16365   }
16366   if (!program->IsValid()) {
16367     // Program was not linked successfully. (ie, glLinkProgram)
16368     LOCAL_SET_GL_ERROR(
16369         GL_INVALID_OPERATION, "glGetUniform", "program not linked");
16370     return false;
16371   }
16372   *service_id = program->service_id();
16373   GLint array_index = -1;
16374   const Program::UniformInfo* uniform_info =
16375       program->GetUniformInfoByFakeLocation(
16376           fake_location, real_location, &array_index);
16377   if (!uniform_info) {
16378     // No such location.
16379     LOCAL_SET_GL_ERROR(
16380         GL_INVALID_OPERATION, "glGetUniform", "unknown location");
16381     return false;
16382   }
16383   GLenum type = uniform_info->type;
16384   uint32_t num_elements = GLES2Util::GetElementCountForUniformType(type);
16385   if (num_elements == 0) {
16386     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
16387     return false;
16388   }
16389   uint32_t checked_size = 0;
16390   if (!SizedResult<T>::ComputeSize(num_elements).AssignIfValid(&checked_size)) {
16391     *error = error::kOutOfBounds;
16392     return false;
16393   }
16394   result = GetSharedMemoryAs<SizedResult<T>*>(shm_id, shm_offset, checked_size);
16395   if (!result) {
16396     *error = error::kOutOfBounds;
16397     return false;
16398   }
16399   result->SetNumResults(num_elements);
16400   *result_size = num_elements * sizeof(T);
16401   *result_type = type;
16402   return true;
16403 }
16404 
HandleGetUniformiv(uint32_t immediate_data_size,const volatile void * cmd_data)16405 error::Error GLES2DecoderImpl::HandleGetUniformiv(
16406     uint32_t immediate_data_size,
16407     const volatile void* cmd_data) {
16408   const volatile gles2::cmds::GetUniformiv& c =
16409       *static_cast<const volatile gles2::cmds::GetUniformiv*>(cmd_data);
16410   GLuint program = c.program;
16411   GLint fake_location = c.location;
16412   GLuint service_id;
16413   GLenum result_type;
16414   GLsizei result_size;
16415   GLint real_location = -1;
16416   Error error;
16417   cmds::GetUniformiv::Result* result;
16418   if (GetUniformSetup<GLint>(program, fake_location, c.params_shm_id,
16419                              c.params_shm_offset, &error, &real_location,
16420                              &service_id, &result, &result_type,
16421                              &result_size)) {
16422     api()->glGetUniformivFn(service_id, real_location, result->GetData());
16423   }
16424   return error;
16425 }
16426 
HandleGetUniformuiv(uint32_t immediate_data_size,const volatile void * cmd_data)16427 error::Error GLES2DecoderImpl::HandleGetUniformuiv(
16428     uint32_t immediate_data_size,
16429     const volatile void* cmd_data) {
16430   if (!feature_info_->IsWebGL2OrES3Context())
16431     return error::kUnknownCommand;
16432 
16433   const volatile gles2::cmds::GetUniformuiv& c =
16434       *static_cast<const volatile gles2::cmds::GetUniformuiv*>(cmd_data);
16435   GLuint program = c.program;
16436   GLint fake_location = c.location;
16437   GLuint service_id;
16438   GLenum result_type;
16439   GLsizei result_size;
16440   GLint real_location = -1;
16441   Error error;
16442   cmds::GetUniformuiv::Result* result;
16443   if (GetUniformSetup<GLuint>(program, fake_location, c.params_shm_id,
16444                               c.params_shm_offset, &error, &real_location,
16445                               &service_id, &result, &result_type,
16446                               &result_size)) {
16447     api()->glGetUniformuivFn(service_id, real_location, result->GetData());
16448   }
16449   return error;
16450 }
16451 
HandleGetUniformfv(uint32_t immediate_data_size,const volatile void * cmd_data)16452 error::Error GLES2DecoderImpl::HandleGetUniformfv(
16453     uint32_t immediate_data_size,
16454     const volatile void* cmd_data) {
16455   const volatile gles2::cmds::GetUniformfv& c =
16456       *static_cast<const volatile gles2::cmds::GetUniformfv*>(cmd_data);
16457   GLuint program = c.program;
16458   GLint fake_location = c.location;
16459   GLuint service_id;
16460   GLint real_location = -1;
16461   Error error;
16462   cmds::GetUniformfv::Result* result;
16463   GLenum result_type;
16464   GLsizei result_size;
16465   if (GetUniformSetup<GLfloat>(program, fake_location, c.params_shm_id,
16466                                c.params_shm_offset, &error, &real_location,
16467                                &service_id, &result, &result_type,
16468                                &result_size)) {
16469     if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
16470         result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
16471       GLsizei num_values = result_size / sizeof(GLfloat);
16472       std::unique_ptr<GLint[]> temp(new GLint[num_values]);
16473       api()->glGetUniformivFn(service_id, real_location, temp.get());
16474       GLfloat* dst = result->GetData();
16475       for (GLsizei ii = 0; ii < num_values; ++ii) {
16476         dst[ii] = (temp[ii] != 0);
16477       }
16478     } else {
16479       api()->glGetUniformfvFn(service_id, real_location, result->GetData());
16480     }
16481   }
16482   return error;
16483 }
16484 
HandleGetShaderPrecisionFormat(uint32_t immediate_data_size,const volatile void * cmd_data)16485 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
16486     uint32_t immediate_data_size,
16487     const volatile void* cmd_data) {
16488   const volatile gles2::cmds::GetShaderPrecisionFormat& c =
16489       *static_cast<const volatile gles2::cmds::GetShaderPrecisionFormat*>(
16490           cmd_data);
16491   GLenum shader_type = static_cast<GLenum>(c.shadertype);
16492   GLenum precision_type = static_cast<GLenum>(c.precisiontype);
16493   typedef cmds::GetShaderPrecisionFormat::Result Result;
16494   Result* result = GetSharedMemoryAs<Result*>(
16495       c.result_shm_id, c.result_shm_offset, sizeof(*result));
16496   if (!result) {
16497     return error::kOutOfBounds;
16498   }
16499   // Check that the client initialized the result.
16500   if (result->success != 0) {
16501     return error::kInvalidArguments;
16502   }
16503   if (!validators_->shader_type.IsValid(shader_type)) {
16504     LOCAL_SET_GL_ERROR_INVALID_ENUM(
16505         "glGetShaderPrecisionFormat", shader_type, "shader_type");
16506     return error::kNoError;
16507   }
16508   if (!validators_->shader_precision.IsValid(precision_type)) {
16509     LOCAL_SET_GL_ERROR_INVALID_ENUM(
16510         "glGetShaderPrecisionFormat", precision_type, "precision_type");
16511     return error::kNoError;
16512   }
16513 
16514   result->success = 1;  // true
16515 
16516   GLint range[2] = { 0, 0 };
16517   GLint precision = 0;
16518   QueryShaderPrecisionFormat(gl_version_info(), shader_type, precision_type,
16519                              range, &precision);
16520 
16521   result->min_range = range[0];
16522   result->max_range = range[1];
16523   result->precision = precision;
16524 
16525   return error::kNoError;
16526 }
16527 
HandleGetAttachedShaders(uint32_t immediate_data_size,const volatile void * cmd_data)16528 error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
16529     uint32_t immediate_data_size,
16530     const volatile void* cmd_data) {
16531   const volatile gles2::cmds::GetAttachedShaders& c =
16532       *static_cast<const volatile gles2::cmds::GetAttachedShaders*>(cmd_data);
16533   uint32_t result_size = c.result_size;
16534   GLuint program_id = static_cast<GLuint>(c.program);
16535   Program* program = GetProgramInfoNotShader(
16536       program_id, "glGetAttachedShaders");
16537   if (!program) {
16538     return error::kNoError;
16539   }
16540   typedef cmds::GetAttachedShaders::Result Result;
16541   uint32_t max_count = Result::ComputeMaxResults(result_size);
16542   uint32_t checked_size = 0;
16543   if (!Result::ComputeSize(max_count).AssignIfValid(&checked_size)) {
16544     return error::kOutOfBounds;
16545   }
16546   Result* result = GetSharedMemoryAs<Result*>(
16547       c.result_shm_id, c.result_shm_offset, checked_size);
16548   if (!result) {
16549     return error::kOutOfBounds;
16550   }
16551   // Check that the client initialized the result.
16552   if (result->size != 0) {
16553     return error::kInvalidArguments;
16554   }
16555   GLsizei count = 0;
16556   api()->glGetAttachedShadersFn(program->service_id(), max_count, &count,
16557                                 result->GetData());
16558   for (GLsizei ii = 0; ii < count; ++ii) {
16559     if (!shader_manager()->GetClientId(result->GetData()[ii],
16560                                        &result->GetData()[ii])) {
16561       NOTREACHED();
16562       return error::kGenericError;
16563     }
16564   }
16565   result->SetNumResults(count);
16566   return error::kNoError;
16567 }
16568 
HandleGetActiveUniform(uint32_t immediate_data_size,const volatile void * cmd_data)16569 error::Error GLES2DecoderImpl::HandleGetActiveUniform(
16570     uint32_t immediate_data_size,
16571     const volatile void* cmd_data) {
16572   const volatile gles2::cmds::GetActiveUniform& c =
16573       *static_cast<const volatile gles2::cmds::GetActiveUniform*>(cmd_data);
16574   GLuint program_id = c.program;
16575   GLuint index = c.index;
16576   uint32_t name_bucket_id = c.name_bucket_id;
16577   typedef cmds::GetActiveUniform::Result Result;
16578   Result* result = GetSharedMemoryAs<Result*>(
16579       c.result_shm_id, c.result_shm_offset, sizeof(*result));
16580   if (!result) {
16581     return error::kOutOfBounds;
16582   }
16583   // Check that the client initialized the result.
16584   if (result->success != 0) {
16585     return error::kInvalidArguments;
16586   }
16587   Program* program = GetProgramInfoNotShader(
16588       program_id, "glGetActiveUniform");
16589   if (!program) {
16590     return error::kNoError;
16591   }
16592   const Program::UniformInfo* uniform_info =
16593       program->GetUniformInfo(index);
16594   if (!uniform_info) {
16595     LOCAL_SET_GL_ERROR(
16596         GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
16597     return error::kNoError;
16598   }
16599   result->success = 1;  // true.
16600   result->size = uniform_info->size;
16601   result->type = uniform_info->type;
16602   Bucket* bucket = CreateBucket(name_bucket_id);
16603   bucket->SetFromString(uniform_info->name.c_str());
16604   return error::kNoError;
16605 }
16606 
HandleGetActiveUniformBlockiv(uint32_t immediate_data_size,const volatile void * cmd_data)16607 error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
16608     uint32_t immediate_data_size,
16609     const volatile void* cmd_data) {
16610   if (!feature_info_->IsWebGL2OrES3Context())
16611     return error::kUnknownCommand;
16612   const volatile gles2::cmds::GetActiveUniformBlockiv& c =
16613       *static_cast<const volatile gles2::cmds::GetActiveUniformBlockiv*>(
16614           cmd_data);
16615   GLuint program_id = c.program;
16616   GLuint index = static_cast<GLuint>(c.index);
16617   GLenum pname = static_cast<GLenum>(c.pname);
16618   Program* program = GetProgramInfoNotShader(
16619       program_id, "glGetActiveUniformBlockiv");
16620   if (!program) {
16621     return error::kNoError;
16622   }
16623   GLuint service_id = program->service_id();
16624   GLint link_status = GL_FALSE;
16625   api()->glGetProgramivFn(service_id, GL_LINK_STATUS, &link_status);
16626   if (link_status != GL_TRUE) {
16627     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
16628         "glGetActiveActiveUniformBlockiv", "program not linked");
16629     return error::kNoError;
16630   }
16631   if (index >= program->uniform_block_size_info().size()) {
16632     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glGetActiveUniformBlockiv",
16633                        "uniformBlockIndex >= active uniform blocks");
16634     return error::kNoError;
16635   }
16636   GLsizei num_values = 1;
16637   if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
16638     GLint num = 0;
16639     api()->glGetActiveUniformBlockivFn(service_id, index,
16640                                        GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
16641     GLenum error = api()->glGetErrorFn();
16642     if (error != GL_NO_ERROR) {
16643       // Assume this will the same error if calling with pname.
16644       LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
16645       return error::kNoError;
16646     }
16647     num_values = static_cast<GLsizei>(num);
16648   }
16649   typedef cmds::GetActiveUniformBlockiv::Result Result;
16650   uint32_t checked_size = 0;
16651   if (!Result::ComputeSize(num_values).AssignIfValid(&checked_size)) {
16652     return error::kOutOfBounds;
16653   }
16654   Result* result = GetSharedMemoryAs<Result*>(
16655       c.params_shm_id, c.params_shm_offset, checked_size);
16656   GLint* params = result ? result->GetData() : nullptr;
16657   if (params == nullptr) {
16658     return error::kOutOfBounds;
16659   }
16660   // Check that the client initialized the result.
16661   if (result->size != 0) {
16662     return error::kInvalidArguments;
16663   }
16664   api()->glGetActiveUniformBlockivFn(service_id, index, pname, params);
16665   result->SetNumResults(num_values);
16666   return error::kNoError;
16667 }
16668 
HandleGetActiveUniformBlockName(uint32_t immediate_data_size,const volatile void * cmd_data)16669 error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
16670     uint32_t immediate_data_size,
16671     const volatile void* cmd_data) {
16672   if (!feature_info_->IsWebGL2OrES3Context())
16673     return error::kUnknownCommand;
16674   const volatile gles2::cmds::GetActiveUniformBlockName& c =
16675       *static_cast<const volatile gles2::cmds::GetActiveUniformBlockName*>(
16676           cmd_data);
16677   GLuint program_id = c.program;
16678   GLuint index = c.index;
16679   uint32_t name_bucket_id = c.name_bucket_id;
16680   typedef cmds::GetActiveUniformBlockName::Result Result;
16681   Result* result = GetSharedMemoryAs<Result*>(
16682       c.result_shm_id, c.result_shm_offset, sizeof(*result));
16683   if (!result) {
16684     return error::kOutOfBounds;
16685   }
16686   // Check that the client initialized the result.
16687   if (*result != 0) {
16688     return error::kInvalidArguments;
16689   }
16690   Program* program = GetProgramInfoNotShader(
16691       program_id, "glGetActiveUniformBlockName");
16692   if (!program) {
16693     return error::kNoError;
16694   }
16695   GLuint service_id = program->service_id();
16696   GLint link_status = GL_FALSE;
16697   api()->glGetProgramivFn(service_id, GL_LINK_STATUS, &link_status);
16698   if (link_status != GL_TRUE) {
16699     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
16700         "glGetActiveActiveUniformBlockName", "program not linked");
16701     return error::kNoError;
16702   }
16703   if (index >= program->uniform_block_size_info().size()) {
16704     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glGetActiveUniformBlockName",
16705                        "uniformBlockIndex >= active uniform blocks");
16706     return error::kNoError;
16707   }
16708   GLint max_length = 0;
16709   api()->glGetProgramivFn(service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH,
16710                           &max_length);
16711   // Increase one so &buffer[0] is always valid.
16712   GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
16713   std::vector<char> buffer(buf_size);
16714   GLsizei length = 0;
16715   api()->glGetActiveUniformBlockNameFn(service_id, index, buf_size, &length,
16716                                        &buffer[0]);
16717   if (length == 0) {
16718     *result = 0;
16719     return error::kNoError;
16720   }
16721   *result = 1;
16722   Bucket* bucket = CreateBucket(name_bucket_id);
16723   DCHECK_GT(buf_size, length);
16724   DCHECK_EQ(0, buffer[length]);
16725   bucket->SetFromString(&buffer[0]);
16726   return error::kNoError;
16727 }
16728 
HandleGetActiveUniformsiv(uint32_t immediate_data_size,const volatile void * cmd_data)16729 error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
16730     uint32_t immediate_data_size,
16731     const volatile void* cmd_data) {
16732   if (!feature_info_->IsWebGL2OrES3Context())
16733     return error::kUnknownCommand;
16734   const volatile gles2::cmds::GetActiveUniformsiv& c =
16735       *static_cast<const volatile gles2::cmds::GetActiveUniformsiv*>(cmd_data);
16736   GLuint program_id = c.program;
16737   GLenum pname = static_cast<GLenum>(c.pname);
16738   Bucket* bucket = GetBucket(c.indices_bucket_id);
16739   if (!bucket) {
16740     return error::kInvalidArguments;
16741   }
16742   if (!validators_->uniform_parameter.IsValid(pname)) {
16743     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetActiveUniformsiv", pname, "pname");
16744     return error::kNoError;
16745   }
16746   GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
16747   const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
16748   typedef cmds::GetActiveUniformsiv::Result Result;
16749   uint32_t checked_size = 0;
16750   if (!Result::ComputeSize(count).AssignIfValid(&checked_size)) {
16751     return error::kOutOfBounds;
16752   }
16753   Result* result = GetSharedMemoryAs<Result*>(
16754       c.params_shm_id, c.params_shm_offset, checked_size);
16755   GLint* params = result ? result->GetData() : nullptr;
16756   if (params == nullptr) {
16757     return error::kOutOfBounds;
16758   }
16759   // Check that the client initialized the result.
16760   if (result->size != 0) {
16761     return error::kInvalidArguments;
16762   }
16763   Program* program = GetProgramInfoNotShader(
16764       program_id, "glGetActiveUniformsiv");
16765   if (!program) {
16766     return error::kNoError;
16767   }
16768   GLint activeUniforms = 0;
16769   program->GetProgramiv(GL_ACTIVE_UNIFORMS, &activeUniforms);
16770   for (int i = 0; i < count; i++) {
16771     if (indices[i] >= static_cast<GLuint>(activeUniforms)) {
16772       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
16773           "glGetActiveUniformsiv", "index >= active uniforms");
16774       return error::kNoError;
16775     }
16776   }
16777   GLuint service_id = program->service_id();
16778   GLint link_status = GL_FALSE;
16779   api()->glGetProgramivFn(service_id, GL_LINK_STATUS, &link_status);
16780   if (link_status != GL_TRUE) {
16781     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
16782         "glGetActiveUniformsiv", "program not linked");
16783     return error::kNoError;
16784   }
16785   api()->glGetActiveUniformsivFn(service_id, count, indices, pname, params);
16786   result->SetNumResults(count);
16787   return error::kNoError;
16788 }
16789 
HandleGetActiveAttrib(uint32_t immediate_data_size,const volatile void * cmd_data)16790 error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
16791     uint32_t immediate_data_size,
16792     const volatile void* cmd_data) {
16793   const volatile gles2::cmds::GetActiveAttrib& c =
16794       *static_cast<const volatile gles2::cmds::GetActiveAttrib*>(cmd_data);
16795   GLuint program_id = c.program;
16796   GLuint index = c.index;
16797   uint32_t name_bucket_id = c.name_bucket_id;
16798   typedef cmds::GetActiveAttrib::Result Result;
16799   Result* result = GetSharedMemoryAs<Result*>(
16800       c.result_shm_id, c.result_shm_offset, sizeof(*result));
16801   if (!result) {
16802     return error::kOutOfBounds;
16803   }
16804   // Check that the client initialized the result.
16805   if (result->success != 0) {
16806     return error::kInvalidArguments;
16807   }
16808   Program* program = GetProgramInfoNotShader(
16809       program_id, "glGetActiveAttrib");
16810   if (!program) {
16811     return error::kNoError;
16812   }
16813   const Program::VertexAttrib* attrib_info =
16814       program->GetAttribInfo(index);
16815   if (!attrib_info) {
16816     LOCAL_SET_GL_ERROR(
16817         GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
16818     return error::kNoError;
16819   }
16820   result->success = 1;  // true.
16821   result->size = attrib_info->size;
16822   result->type = attrib_info->type;
16823   Bucket* bucket = CreateBucket(name_bucket_id);
16824   bucket->SetFromString(attrib_info->name.c_str());
16825   return error::kNoError;
16826 }
16827 
HandleShaderBinary(uint32_t immediate_data_size,const volatile void * cmd_data)16828 error::Error GLES2DecoderImpl::HandleShaderBinary(
16829     uint32_t immediate_data_size,
16830     const volatile void* cmd_data) {
16831 #if 1  // No binary shader support.
16832   LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
16833   return error::kNoError;
16834 #else
16835   GLsizei n = static_cast<GLsizei>(c.n);
16836   if (n < 0) {
16837     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
16838     return error::kNoError;
16839   }
16840   GLsizei length = static_cast<GLsizei>(c.length);
16841   if (length < 0) {
16842     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
16843     return error::kNoError;
16844   }
16845   uint32_t data_size;
16846   if (!base::CheckMul(n, sizeof(GLuint)).AssignIfValid(&data_size)) {
16847     return error::kOutOfBounds;
16848   }
16849   const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
16850       c.shaders_shm_id, c.shaders_shm_offset, data_size);
16851   GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
16852   const void* binary = GetSharedMemoryAs<const void*>(
16853       c.binary_shm_id, c.binary_shm_offset, length);
16854   if (shaders == nullptr || binary == nullptr) {
16855     return error::kOutOfBounds;
16856   }
16857   std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
16858   for (GLsizei ii = 0; ii < n; ++ii) {
16859     Shader* shader = GetShader(shaders[ii]);
16860     if (!shader) {
16861       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
16862       return error::kNoError;
16863     }
16864     service_ids[ii] = shader->service_id();
16865   }
16866   // TODO(gman): call glShaderBinary
16867   return error::kNoError;
16868 #endif
16869 }
16870 
DoSwapBuffers(uint64_t swap_id,GLbitfield flags)16871 void GLES2DecoderImpl::DoSwapBuffers(uint64_t swap_id, GLbitfield flags) {
16872   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
16873 
16874   int this_frame_number = frame_number_++;
16875   // TRACE_EVENT for gpu tests:
16876   TRACE_EVENT_INSTANT2(
16877       "test_gpu", "SwapBuffersLatency", TRACE_EVENT_SCOPE_THREAD, "GLImpl",
16878       static_cast<int>(gl::GetGLImplementation()), "width",
16879       (is_offscreen ? offscreen_size_.width() : surface_->GetSize().width()));
16880   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
16881                "offscreen", is_offscreen,
16882                "frame", this_frame_number);
16883 
16884   ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
16885                                   "GLES2Decoder", "SwapBuffer");
16886 
16887   bool is_tracing;
16888   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
16889                                      &is_tracing);
16890   if (is_tracing) {
16891     ScopedFramebufferBinder binder(this, GetBoundDrawFramebufferServiceId());
16892     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
16893         is_offscreen ? offscreen_size_ : surface_->GetSize());
16894   }
16895 
16896   ClearScheduleCALayerState();
16897 
16898   // If offscreen then don't actually SwapBuffers to the display. Just copy
16899   // the rendered frame to another frame buffer.
16900   if (is_offscreen) {
16901     TRACE_EVENT2("gpu", "Offscreen",
16902         "width", offscreen_size_.width(), "height", offscreen_size_.height());
16903 
16904     if (offscreen_single_buffer_)
16905       return;
16906 
16907     if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
16908       // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
16909       // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
16910       // fix this.
16911       if (workarounds().needs_offscreen_buffer_workaround) {
16912         offscreen_saved_frame_buffer_->Create();
16913         api()->glFinishFn();
16914       }
16915 
16916       // The size has changed, so none of the cached BackTextures are useful
16917       // anymore.
16918       ReleaseNotInUseBackTextures();
16919 
16920       // Allocate the offscreen saved color texture.
16921       DCHECK(offscreen_saved_color_format_);
16922       offscreen_saved_color_texture_->AllocateStorage(
16923           offscreen_size_, offscreen_saved_color_format_, false);
16924 
16925       offscreen_saved_frame_buffer_->AttachRenderTexture(
16926           offscreen_saved_color_texture_.get());
16927       if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
16928         if (offscreen_saved_frame_buffer_->CheckStatus() !=
16929             GL_FRAMEBUFFER_COMPLETE) {
16930           LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
16931                      << "because offscreen saved FBO was incomplete.";
16932           MarkContextLost(error::kUnknown);
16933           group_->LoseContexts(error::kUnknown);
16934           return;
16935         }
16936 
16937         // Clear the offscreen color texture.
16938         // TODO(piman): Is this still necessary?
16939         {
16940           ScopedFramebufferBinder binder(this,
16941                                          offscreen_saved_frame_buffer_->id());
16942           api()->glClearColorFn(0, 0, 0, BackBufferAlphaClearColor());
16943           state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
16944           state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
16945           ClearDeviceWindowRectangles();
16946           api()->glClearFn(GL_COLOR_BUFFER_BIT);
16947           RestoreClearState();
16948         }
16949       }
16950     }
16951 
16952     if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
16953       return;
16954     ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::DoSwapBuffers",
16955                                        error_state_.get());
16956 
16957     if (IsOffscreenBufferMultisampled()) {
16958       // For multisampled buffers, resolve the frame buffer.
16959       ScopedResolvedFramebufferBinder binder(this, true, false);
16960     } else {
16961       ScopedFramebufferBinder binder(this,
16962                                      offscreen_target_frame_buffer_->id());
16963 
16964       if (offscreen_target_buffer_preserved_) {
16965         // Copy the target frame buffer to the saved offscreen texture.
16966         offscreen_saved_color_texture_->Copy();
16967       } else {
16968         offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
16969         offscreen_target_frame_buffer_->AttachRenderTexture(
16970             offscreen_target_color_texture_.get());
16971         offscreen_saved_frame_buffer_->AttachRenderTexture(
16972             offscreen_saved_color_texture_.get());
16973       }
16974 
16975       // Ensure the side effects of the copy are visible to the parent
16976       // context. There is no need to do this for ANGLE because it uses a
16977       // single underlying device/context for all contexts.
16978       if (!gl_version_info().is_angle)
16979         api()->glFlushFn();
16980     }
16981   } else if (supports_async_swap_) {
16982     TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id);
16983 
16984     client()->OnSwapBuffers(swap_id, flags);
16985     surface_->SwapBuffersAsync(
16986         base::BindOnce(&GLES2DecoderImpl::FinishAsyncSwapBuffers,
16987                        weak_ptr_factory_.GetWeakPtr(), swap_id),
16988         base::DoNothing());
16989   } else {
16990     client()->OnSwapBuffers(swap_id, flags);
16991     FinishSwapBuffers(surface_->SwapBuffers(base::DoNothing()));
16992   }
16993 
16994   // This may be a slow command.  Exit command processing to allow for
16995   // context preemption and GPU watchdog checks.
16996   ExitCommandProcessingEarly();
16997 }
16998 
FinishAsyncSwapBuffers(uint64_t swap_id,gfx::SwapResult result,std::unique_ptr<gfx::GpuFence> gpu_fence)16999 void GLES2DecoderImpl::FinishAsyncSwapBuffers(
17000     uint64_t swap_id,
17001     gfx::SwapResult result,
17002     std::unique_ptr<gfx::GpuFence> gpu_fence) {
17003   TRACE_EVENT_ASYNC_END0("gpu", "AsyncSwapBuffers", swap_id);
17004   // Handling of the out-fence should have already happened before reaching
17005   // this function, so we don't expect to get a valid fence here.
17006   DCHECK(!gpu_fence);
17007 
17008   FinishSwapBuffers(result);
17009 }
17010 
FinishSwapBuffers(gfx::SwapResult result)17011 void GLES2DecoderImpl::FinishSwapBuffers(gfx::SwapResult result) {
17012   if (result == gfx::SwapResult::SWAP_FAILED) {
17013     // If SwapBuffers/SwapBuffersWithBounds/PostSubBuffer failed, we may not
17014     // have a current context any more.
17015     LOG(ERROR) << "Context lost because SwapBuffers failed.";
17016     if (!context_->IsCurrent(surface_.get()) || !CheckResetStatus()) {
17017       MarkContextLost(error::kUnknown);
17018       group_->LoseContexts(error::kUnknown);
17019     }
17020   }
17021   ++swaps_since_resize_;
17022   if (swaps_since_resize_ == 1 && surface_->BuffersFlipped()) {
17023     // The second buffer after a resize is new and needs to be cleared to
17024     // known values.
17025     backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
17026   }
17027 }
17028 
DoCommitOverlayPlanes(uint64_t swap_id,GLbitfield flags)17029 void GLES2DecoderImpl::DoCommitOverlayPlanes(uint64_t swap_id,
17030                                              GLbitfield flags) {
17031   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCommitOverlayPlanes");
17032   if (!supports_commit_overlay_planes_) {
17033     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCommitOverlayPlanes",
17034                        "command not supported by surface");
17035     return;
17036   }
17037   ClearScheduleCALayerState();
17038   if (supports_async_swap_) {
17039     client()->OnSwapBuffers(swap_id, flags);
17040     surface_->CommitOverlayPlanesAsync(
17041         base::BindOnce(&GLES2DecoderImpl::FinishAsyncSwapBuffers,
17042                        weak_ptr_factory_.GetWeakPtr(), swap_id),
17043         base::DoNothing());
17044   } else {
17045     client()->OnSwapBuffers(swap_id, flags);
17046     FinishSwapBuffers(surface_->CommitOverlayPlanes(base::DoNothing()));
17047   }
17048 }
17049 
HandleEnableFeatureCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17050 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
17051     uint32_t immediate_data_size,
17052     const volatile void* cmd_data) {
17053   const volatile gles2::cmds::EnableFeatureCHROMIUM& c =
17054       *static_cast<const volatile gles2::cmds::EnableFeatureCHROMIUM*>(
17055           cmd_data);
17056   Bucket* bucket = GetBucket(c.bucket_id);
17057   if (!bucket || bucket->size() == 0) {
17058     return error::kInvalidArguments;
17059   }
17060   typedef cmds::EnableFeatureCHROMIUM::Result Result;
17061   Result* result = GetSharedMemoryAs<Result*>(
17062       c.result_shm_id, c.result_shm_offset, sizeof(*result));
17063   if (!result) {
17064     return error::kOutOfBounds;
17065   }
17066   // Check that the client initialized the result.
17067   if (*result != 0) {
17068     return error::kInvalidArguments;
17069   }
17070   std::string feature_str;
17071   if (!bucket->GetAsString(&feature_str)) {
17072     return error::kInvalidArguments;
17073   }
17074 
17075   // TODO(gman): make this some kind of table to function pointer thingy.
17076   if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
17077     buffer_manager()->set_allow_buffers_on_multiple_targets(true);
17078   } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
17079     buffer_manager()->set_allow_fixed_attribs(true);
17080     // TODO(gman): decide how to remove the need for this const_cast.
17081     // I could make validators_ non const but that seems bad as this is the only
17082     // place it is needed. I could make some special friend class of validators
17083     // just to allow this to set them. That seems silly. I could refactor this
17084     // code to use the extension mechanism or the initialization attributes to
17085     // turn this feature on. Given that the only real point of this is to make
17086     // the conformance tests pass and given that there is lots of real work that
17087     // needs to be done it seems like refactoring for one to one of those
17088     // methods is a very low priority.
17089     const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
17090   } else {
17091     return error::kNoError;
17092   }
17093 
17094   *result = 1;  // true.
17095   return error::kNoError;
17096 }
17097 
HandleGetRequestableExtensionsCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17098 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
17099     uint32_t immediate_data_size,
17100     const volatile void* cmd_data) {
17101   const volatile gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
17102       *static_cast<
17103           const volatile gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
17104           cmd_data);
17105   Bucket* bucket = CreateBucket(c.bucket_id);
17106   scoped_refptr<FeatureInfo> info(
17107       new FeatureInfo(workarounds(), group_->gpu_feature_info()));
17108   DisallowedFeatures disallowed_features = feature_info_->disallowed_features();
17109   disallowed_features.AllowExtensions();
17110   info->Initialize(feature_info_->context_type(),
17111                    false /* is_passthrough_cmd_decoder */, disallowed_features);
17112   bucket->SetFromString(gfx::MakeExtensionString(info->extensions()).c_str());
17113   return error::kNoError;
17114 }
17115 
HandleRequestExtensionCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17116 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
17117     uint32_t immediate_data_size,
17118     const volatile void* cmd_data) {
17119   const volatile gles2::cmds::RequestExtensionCHROMIUM& c =
17120       *static_cast<const volatile gles2::cmds::RequestExtensionCHROMIUM*>(
17121           cmd_data);
17122   Bucket* bucket = GetBucket(c.bucket_id);
17123   if (!bucket || bucket->size() == 0) {
17124     return error::kInvalidArguments;
17125   }
17126   std::string feature_str;
17127   if (!bucket->GetAsString(&feature_str)) {
17128     return error::kInvalidArguments;
17129   }
17130   feature_str = feature_str + " ";
17131 
17132   bool desire_standard_derivatives = false;
17133   bool desire_fbo_render_mipmap = false;
17134   bool desire_frag_depth = false;
17135   bool desire_draw_buffers = false;
17136   bool desire_shader_texture_lod = false;
17137   bool desire_multi_draw = false;
17138   bool desire_draw_instanced_base_vertex_base_instance = false;
17139   bool desire_multi_draw_instanced_base_vertex_base_instance = false;
17140   if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL1) {
17141     desire_standard_derivatives =
17142         feature_str.find("GL_OES_standard_derivatives ") != std::string::npos;
17143     desire_fbo_render_mipmap =
17144         feature_str.find("GL_OES_fbo_render_mipmap ") != std::string::npos;
17145     desire_frag_depth =
17146         feature_str.find("GL_EXT_frag_depth ") != std::string::npos;
17147     desire_draw_buffers =
17148         feature_str.find("GL_EXT_draw_buffers ") != std::string::npos;
17149     desire_shader_texture_lod =
17150         feature_str.find("GL_EXT_shader_texture_lod ") != std::string::npos;
17151   } else if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2) {
17152     desire_draw_instanced_base_vertex_base_instance =
17153         feature_str.find(
17154             "GL_WEBGL_draw_instanced_base_vertex_base_instance ") !=
17155         std::string::npos;
17156     ;
17157     desire_multi_draw_instanced_base_vertex_base_instance =
17158         feature_str.find(
17159             "GL_WEBGL_multi_draw_instanced_base_vertex_base_instance ") !=
17160         std::string::npos;
17161     ;
17162   }
17163   if (feature_info_->IsWebGLContext()) {
17164     desire_multi_draw =
17165         feature_str.find("GL_WEBGL_multi_draw ") != std::string::npos;
17166   }
17167   if (desire_standard_derivatives != derivatives_explicitly_enabled_ ||
17168       desire_fbo_render_mipmap != fbo_render_mipmap_explicitly_enabled_ ||
17169       desire_frag_depth != frag_depth_explicitly_enabled_ ||
17170       desire_draw_buffers != draw_buffers_explicitly_enabled_ ||
17171       desire_shader_texture_lod != shader_texture_lod_explicitly_enabled_ ||
17172       desire_multi_draw != multi_draw_explicitly_enabled_ ||
17173       desire_draw_instanced_base_vertex_base_instance !=
17174           draw_instanced_base_vertex_base_instance_explicitly_enabled_ ||
17175       desire_multi_draw_instanced_base_vertex_base_instance !=
17176           multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_) {
17177     derivatives_explicitly_enabled_ |= desire_standard_derivatives;
17178     fbo_render_mipmap_explicitly_enabled_ |= desire_fbo_render_mipmap;
17179     frag_depth_explicitly_enabled_ |= desire_frag_depth;
17180     draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
17181     shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
17182     multi_draw_explicitly_enabled_ |= desire_multi_draw;
17183     draw_instanced_base_vertex_base_instance_explicitly_enabled_ |=
17184         desire_draw_instanced_base_vertex_base_instance;
17185     multi_draw_instanced_base_vertex_base_instance_explicitly_enabled_ |=
17186         desire_multi_draw_instanced_base_vertex_base_instance;
17187     DestroyShaderTranslator();
17188   }
17189 
17190   if (feature_str.find("GL_CHROMIUM_color_buffer_float_rgba ") !=
17191       std::string::npos) {
17192     feature_info_->EnableCHROMIUMColorBufferFloatRGBA();
17193   }
17194   if (feature_str.find("GL_CHROMIUM_color_buffer_float_rgb ") !=
17195       std::string::npos) {
17196     feature_info_->EnableCHROMIUMColorBufferFloatRGB();
17197   }
17198   if (feature_str.find("GL_EXT_color_buffer_float ") != std::string::npos) {
17199     feature_info_->EnableEXTColorBufferFloat();
17200   }
17201   if (feature_str.find("GL_EXT_color_buffer_half_float ") !=
17202       std::string::npos) {
17203     feature_info_->EnableEXTColorBufferHalfFloat();
17204   }
17205   if (feature_str.find("GL_EXT_texture_filter_anisotropic ") !=
17206       std::string::npos) {
17207     feature_info_->EnableEXTTextureFilterAnisotropic();
17208   }
17209   if (feature_str.find("GL_OES_texture_float_linear ") != std::string::npos) {
17210     feature_info_->EnableOESTextureFloatLinear();
17211   }
17212   if (feature_str.find("GL_OES_texture_half_float_linear ") !=
17213       std::string::npos) {
17214     feature_info_->EnableOESTextureHalfFloatLinear();
17215   }
17216   if (feature_str.find("GL_EXT_float_blend ") != std::string::npos) {
17217     feature_info_->EnableEXTFloatBlend();
17218   }
17219   if (feature_str.find("GL_OES_fbo_render_mipmap ") != std::string::npos) {
17220     feature_info_->EnableOESFboRenderMipmap();
17221   }
17222 
17223   UpdateCapabilities();
17224 
17225   return error::kNoError;
17226 }
17227 
HandleGetProgramInfoCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17228 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
17229     uint32_t immediate_data_size,
17230     const volatile void* cmd_data) {
17231   const volatile gles2::cmds::GetProgramInfoCHROMIUM& c =
17232       *static_cast<const volatile gles2::cmds::GetProgramInfoCHROMIUM*>(
17233           cmd_data);
17234   GLuint program_id = static_cast<GLuint>(c.program);
17235   uint32_t bucket_id = c.bucket_id;
17236   Bucket* bucket = CreateBucket(bucket_id);
17237   bucket->SetSize(sizeof(ProgramInfoHeader));  // in case we fail.
17238   Program* program = nullptr;
17239   program = GetProgram(program_id);
17240   if (!program || !program->IsValid()) {
17241     return error::kNoError;
17242   }
17243   program->GetProgramInfo(program_manager(), bucket);
17244   return error::kNoError;
17245 }
17246 
HandleGetUniformBlocksCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17247 error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
17248     uint32_t immediate_data_size,
17249     const volatile void* cmd_data) {
17250   if (!feature_info_->IsWebGL2OrES3Context())
17251     return error::kUnknownCommand;
17252   const volatile gles2::cmds::GetUniformBlocksCHROMIUM& c =
17253       *static_cast<const volatile gles2::cmds::GetUniformBlocksCHROMIUM*>(
17254           cmd_data);
17255   GLuint program_id = static_cast<GLuint>(c.program);
17256   uint32_t bucket_id = c.bucket_id;
17257   Bucket* bucket = CreateBucket(bucket_id);
17258   bucket->SetSize(sizeof(UniformBlocksHeader));  // in case we fail.
17259   Program* program = nullptr;
17260   program = GetProgram(program_id);
17261   if (!program || !program->IsValid()) {
17262     return error::kNoError;
17263   }
17264   program->GetUniformBlocks(bucket);
17265   return error::kNoError;
17266 }
17267 
HandleGetUniformsES3CHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17268 error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
17269     uint32_t immediate_data_size,
17270     const volatile void* cmd_data) {
17271   if (!feature_info_->IsWebGL2OrES3Context())
17272     return error::kUnknownCommand;
17273   const volatile gles2::cmds::GetUniformsES3CHROMIUM& c =
17274       *static_cast<const volatile gles2::cmds::GetUniformsES3CHROMIUM*>(
17275           cmd_data);
17276   GLuint program_id = static_cast<GLuint>(c.program);
17277   uint32_t bucket_id = c.bucket_id;
17278   Bucket* bucket = CreateBucket(bucket_id);
17279   bucket->SetSize(sizeof(UniformsES3Header));  // in case we fail.
17280   Program* program = nullptr;
17281   program = GetProgram(program_id);
17282   if (!program || !program->IsValid()) {
17283     return error::kNoError;
17284   }
17285   program->GetUniformsES3(bucket);
17286   return error::kNoError;
17287 }
17288 
HandleGetTransformFeedbackVarying(uint32_t immediate_data_size,const volatile void * cmd_data)17289 error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
17290     uint32_t immediate_data_size,
17291     const volatile void* cmd_data) {
17292   if (!feature_info_->IsWebGL2OrES3Context())
17293     return error::kUnknownCommand;
17294   const volatile gles2::cmds::GetTransformFeedbackVarying& c =
17295       *static_cast<const volatile gles2::cmds::GetTransformFeedbackVarying*>(
17296           cmd_data);
17297   GLuint program_id = c.program;
17298   GLuint index = c.index;
17299   uint32_t name_bucket_id = c.name_bucket_id;
17300   typedef cmds::GetTransformFeedbackVarying::Result Result;
17301   Result* result = GetSharedMemoryAs<Result*>(
17302       c.result_shm_id, c.result_shm_offset, sizeof(*result));
17303   if (!result) {
17304     return error::kOutOfBounds;
17305   }
17306   // Check that the client initialized the result.
17307   if (result->success != 0) {
17308     return error::kInvalidArguments;
17309   }
17310   Program* program = GetProgramInfoNotShader(
17311       program_id, "glGetTransformFeedbackVarying");
17312   if (!program) {
17313     // An error is already set.
17314     return error::kNoError;
17315   }
17316   GLuint service_id = program->service_id();
17317   GLint link_status = GL_FALSE;
17318   api()->glGetProgramivFn(service_id, GL_LINK_STATUS, &link_status);
17319   if (link_status != GL_TRUE) {
17320     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
17321         "glGetTransformFeedbackVarying", "program not linked");
17322     return error::kNoError;
17323   }
17324   GLint num_varyings = 0;
17325   api()->glGetProgramivFn(service_id, GL_TRANSFORM_FEEDBACK_VARYINGS,
17326                           &num_varyings);
17327   if (index >= static_cast<GLuint>(num_varyings)) {
17328     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
17329         "glGetTransformFeedbackVarying", "index out of bounds");
17330     return error::kNoError;
17331   }
17332   GLint max_length = 0;
17333   api()->glGetProgramivFn(service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH,
17334                           &max_length);
17335   max_length = std::max(1, max_length);
17336   std::vector<char> buffer(max_length);
17337   GLsizei length = 0;
17338   GLsizei size = 0;
17339   GLenum type = 0;
17340   api()->glGetTransformFeedbackVaryingFn(service_id, index, max_length, &length,
17341                                          &size, &type, &buffer[0]);
17342   result->success = 1;  // true.
17343   result->size = static_cast<int32_t>(size);
17344   result->type = static_cast<uint32_t>(type);
17345   Bucket* bucket = CreateBucket(name_bucket_id);
17346   DCHECK(length >= 0 && length < max_length);
17347   buffer[length] = '\0';  // Just to be safe.
17348   bucket->SetFromString(&buffer[0]);
17349   return error::kNoError;
17350 }
17351 
HandleGetTransformFeedbackVaryingsCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17352 error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
17353     uint32_t immediate_data_size,
17354     const volatile void* cmd_data) {
17355   if (!feature_info_->IsWebGL2OrES3Context())
17356     return error::kUnknownCommand;
17357   const volatile gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
17358       *static_cast<
17359           const volatile gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
17360           cmd_data);
17361   GLuint program_id = static_cast<GLuint>(c.program);
17362   uint32_t bucket_id = c.bucket_id;
17363   Bucket* bucket = CreateBucket(bucket_id);
17364   bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader));  // in case we fail.
17365   Program* program = nullptr;
17366   program = GetProgram(program_id);
17367   if (!program || !program->IsValid()) {
17368     return error::kNoError;
17369   }
17370   program->GetTransformFeedbackVaryings(bucket);
17371   return error::kNoError;
17372 }
17373 
WasContextLost() const17374 bool GLES2DecoderImpl::WasContextLost() const {
17375   return context_was_lost_;
17376 }
17377 
WasContextLostByRobustnessExtension() const17378 bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() const {
17379   return WasContextLost() && reset_by_robustness_extension_;
17380 }
17381 
MarkContextLost(error::ContextLostReason reason)17382 void GLES2DecoderImpl::MarkContextLost(error::ContextLostReason reason) {
17383   // Only lose the context once.
17384   if (WasContextLost())
17385     return;
17386 
17387   // Don't make GL calls in here, the context might not be current.
17388   command_buffer_service()->SetContextLostReason(reason);
17389   current_decoder_error_ = error::kLostContext;
17390   context_was_lost_ = true;
17391 
17392   if (transform_feedback_manager_.get()) {
17393     transform_feedback_manager_->MarkContextLost();
17394   }
17395   if (vertex_array_manager_.get()) {
17396     vertex_array_manager_->MarkContextLost();
17397   }
17398   state_.MarkContextLost();
17399 }
17400 
CheckResetStatus()17401 bool GLES2DecoderImpl::CheckResetStatus() {
17402   DCHECK(!WasContextLost());
17403   DCHECK(context_->IsCurrent(nullptr));
17404 
17405   // If the reason for the call was a GL error, we can try to determine the
17406   // reset status more accurately.
17407   GLenum driver_status = context_->CheckStickyGraphicsResetStatus();
17408   if (driver_status == GL_NO_ERROR)
17409     return false;
17410 
17411   LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
17412              << " context lost via ARB/EXT_robustness. Reset status = "
17413              << GLES2Util::GetStringEnum(driver_status);
17414 
17415   switch (driver_status) {
17416     case GL_GUILTY_CONTEXT_RESET_ARB:
17417       MarkContextLost(error::kGuilty);
17418       break;
17419     case GL_INNOCENT_CONTEXT_RESET_ARB:
17420       MarkContextLost(error::kInnocent);
17421       break;
17422     case GL_UNKNOWN_CONTEXT_RESET_ARB:
17423       MarkContextLost(error::kUnknown);
17424       break;
17425     default:
17426       NOTREACHED();
17427       return false;
17428   }
17429   reset_by_robustness_extension_ = true;
17430   return true;
17431 }
17432 
HandleDescheduleUntilFinishedCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17433 error::Error GLES2DecoderImpl::HandleDescheduleUntilFinishedCHROMIUM(
17434     uint32_t immediate_data_size,
17435     const volatile void* cmd_data) {
17436   if (!gl::GLFence::IsSupported())
17437     return error::kNoError;
17438   std::unique_ptr<gl::GLFence> fence = gl::GLFence::Create();
17439   if (fence)
17440     deschedule_until_finished_fences_.push_back(std::move(fence));
17441 
17442   if (deschedule_until_finished_fences_.size() == 1)
17443     return error::kNoError;
17444 
17445   DCHECK_EQ(2u, deschedule_until_finished_fences_.size());
17446   if (deschedule_until_finished_fences_[0]->HasCompleted()) {
17447     deschedule_until_finished_fences_.erase(
17448         deschedule_until_finished_fences_.begin());
17449     return error::kNoError;
17450   }
17451 
17452   TRACE_EVENT_ASYNC_BEGIN0("cc", "GLES2DecoderImpl::DescheduleUntilFinished",
17453                            this);
17454   client()->OnDescheduleUntilFinished();
17455   return error::kDeferLaterCommands;
17456 }
17457 
HandleDiscardBackbufferCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17458 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
17459     uint32_t immediate_data_size,
17460     const volatile void* cmd_data) {
17461   if (surface_->DeferDraws())
17462     return error::kDeferCommandUntilLater;
17463   if (!surface_->SetBackbufferAllocation(false))
17464     return error::kLostContext;
17465   backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
17466   backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
17467   backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
17468   return error::kNoError;
17469 }
17470 
GenQueriesEXTHelper(GLsizei n,const GLuint * client_ids)17471 bool GLES2DecoderImpl::GenQueriesEXTHelper(
17472     GLsizei n, const GLuint* client_ids) {
17473   for (GLsizei ii = 0; ii < n; ++ii) {
17474     if (query_manager_->IsValidQuery(client_ids[ii])) {
17475       return false;
17476     }
17477   }
17478   query_manager_->GenQueries(n, client_ids);
17479   return true;
17480 }
17481 
DeleteQueriesEXTHelper(GLsizei n,const volatile GLuint * client_ids)17482 void GLES2DecoderImpl::DeleteQueriesEXTHelper(
17483     GLsizei n,
17484     const volatile GLuint* client_ids) {
17485   for (GLsizei ii = 0; ii < n; ++ii) {
17486     GLuint client_id = client_ids[ii];
17487     query_manager_->RemoveQuery(client_id);
17488   }
17489 }
17490 
SetQueryCallback(unsigned int query_client_id,base::OnceClosure callback)17491 void GLES2DecoderImpl::SetQueryCallback(unsigned int query_client_id,
17492                                         base::OnceClosure callback) {
17493   QueryManager::Query* query = query_manager_->GetQuery(query_client_id);
17494   if (query) {
17495     query->AddCallback(std::move(callback));
17496   } else {
17497     VLOG(1) << "GLES2DecoderImpl::SetQueryCallback: No query with ID "
17498             << query_client_id << ". Running the callback immediately.";
17499     std::move(callback).Run();
17500   }
17501 }
17502 
HasPendingQueries() const17503 bool GLES2DecoderImpl::HasPendingQueries() const {
17504   return query_manager_.get() && query_manager_->HavePendingQueries();
17505 }
17506 
ProcessPendingQueries(bool did_finish)17507 void GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
17508   if (!query_manager_.get())
17509     return;
17510   query_manager_->ProcessPendingQueries(did_finish);
17511 }
17512 
17513 // Note that if there are no pending readpixels right now,
17514 // this function will call the callback immediately.
WaitForReadPixels(base::OnceClosure callback)17515 void GLES2DecoderImpl::WaitForReadPixels(base::OnceClosure callback) {
17516   if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
17517     pending_readpixel_fences_.back().callbacks.push_back(std::move(callback));
17518   } else {
17519     std::move(callback).Run();
17520   }
17521 }
17522 
ProcessPendingReadPixels(bool did_finish)17523 void GLES2DecoderImpl::ProcessPendingReadPixels(bool did_finish) {
17524   // Note: |did_finish| guarantees that the GPU has passed the fence but
17525   // we cannot assume that GLFence::HasCompleted() will return true yet as
17526   // that's not guaranteed by all GLFence implementations.
17527   while (!pending_readpixel_fences_.empty() &&
17528          (did_finish ||
17529           pending_readpixel_fences_.front().fence->HasCompleted())) {
17530     std::vector<base::OnceClosure> callbacks =
17531         std::move(pending_readpixel_fences_.front().callbacks);
17532     pending_readpixel_fences_.pop();
17533     for (size_t i = 0; i < callbacks.size(); i++) {
17534       std::move(callbacks[i]).Run();
17535     }
17536   }
17537 }
17538 
ProcessDescheduleUntilFinished()17539 void GLES2DecoderImpl::ProcessDescheduleUntilFinished() {
17540   if (deschedule_until_finished_fences_.size() < 2)
17541     return;
17542   DCHECK_EQ(2u, deschedule_until_finished_fences_.size());
17543 
17544   if (!deschedule_until_finished_fences_[0]->HasCompleted())
17545     return;
17546 
17547   TRACE_EVENT_ASYNC_END0("cc", "GLES2DecoderImpl::DescheduleUntilFinished",
17548                          this);
17549   deschedule_until_finished_fences_.erase(
17550       deschedule_until_finished_fences_.begin());
17551   client()->OnRescheduleAfterFinished();
17552 }
17553 
HasMoreIdleWork() const17554 bool GLES2DecoderImpl::HasMoreIdleWork() const {
17555   return !pending_readpixel_fences_.empty() ||
17556          gpu_tracer_->HasTracesToProcess() ||
17557          !texture_refs_pending_destruction_.empty();
17558 }
17559 
PerformIdleWork()17560 void GLES2DecoderImpl::PerformIdleWork() {
17561   gpu_tracer_->ProcessTraces();
17562   ProcessPendingReadPixels(false);
17563 }
17564 
HasPollingWork() const17565 bool GLES2DecoderImpl::HasPollingWork() const {
17566   return deschedule_until_finished_fences_.size() >= 2;
17567 }
17568 
PerformPollingWork()17569 void GLES2DecoderImpl::PerformPollingWork() {
17570   ProcessDescheduleUntilFinished();
17571 }
17572 
HandleBeginQueryEXT(uint32_t immediate_data_size,const volatile void * cmd_data)17573 error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
17574     uint32_t immediate_data_size,
17575     const volatile void* cmd_data) {
17576   const volatile gles2::cmds::BeginQueryEXT& c =
17577       *static_cast<const volatile gles2::cmds::BeginQueryEXT*>(cmd_data);
17578   GLenum target = static_cast<GLenum>(c.target);
17579   GLuint client_id = static_cast<GLuint>(c.id);
17580   int32_t sync_shm_id = static_cast<int32_t>(c.sync_data_shm_id);
17581   uint32_t sync_shm_offset = static_cast<uint32_t>(c.sync_data_shm_offset);
17582 
17583   switch (target) {
17584     case GL_COMMANDS_ISSUED_CHROMIUM:
17585     case GL_LATENCY_QUERY_CHROMIUM:
17586     case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
17587     case GL_GET_ERROR_QUERY_CHROMIUM:
17588       break;
17589     case GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM:
17590     case GL_COMMANDS_COMPLETED_CHROMIUM:
17591       if (!features().chromium_sync_query) {
17592         LOCAL_SET_GL_ERROR(
17593             GL_INVALID_OPERATION, "glBeginQueryEXT",
17594             "not enabled for commands completed queries");
17595         return error::kNoError;
17596       }
17597       break;
17598     case GL_PROGRAM_COMPLETION_QUERY_CHROMIUM:
17599       if (!features().chromium_completion_query) {
17600         LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT",
17601                            "not enabled for program completion queries");
17602         return error::kNoError;
17603       }
17604       break;
17605     case GL_SAMPLES_PASSED_ARB:
17606       if (!features().occlusion_query) {
17607         LOCAL_SET_GL_ERROR(
17608             GL_INVALID_OPERATION, "glBeginQueryEXT",
17609             "not enabled for occlusion queries");
17610         return error::kNoError;
17611       }
17612       break;
17613     case GL_ANY_SAMPLES_PASSED:
17614     case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
17615       if (!features().occlusion_query_boolean) {
17616         LOCAL_SET_GL_ERROR(
17617             GL_INVALID_OPERATION, "glBeginQueryEXT",
17618             "not enabled for boolean occlusion queries");
17619         return error::kNoError;
17620       }
17621       break;
17622     case GL_TIME_ELAPSED:
17623       if (!query_manager_->GPUTimingAvailable()) {
17624         LOCAL_SET_GL_ERROR(
17625             GL_INVALID_OPERATION, "glBeginQueryEXT",
17626             "not enabled for timing queries");
17627         return error::kNoError;
17628       }
17629       break;
17630     case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
17631       if (feature_info_->IsWebGL2OrES3Context()) {
17632         break;
17633       }
17634       FALLTHROUGH;
17635     default:
17636       LOCAL_SET_GL_ERROR(
17637           GL_INVALID_ENUM, "glBeginQueryEXT",
17638           "unknown query target");
17639       return error::kNoError;
17640   }
17641 
17642   if (query_manager_->GetActiveQuery(target)) {
17643     LOCAL_SET_GL_ERROR(
17644         GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
17645     return error::kNoError;
17646   }
17647 
17648   if (client_id == 0) {
17649     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
17650     return error::kNoError;
17651   }
17652 
17653   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
17654   if (!buffer)
17655     return error::kInvalidArguments;
17656   QuerySync* sync = static_cast<QuerySync*>(
17657       buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
17658   if (!sync)
17659     return error::kOutOfBounds;
17660 
17661   QueryManager::Query* query = query_manager_->GetQuery(client_id);
17662   if (!query) {
17663     if (!query_manager_->IsValidQuery(client_id)) {
17664       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
17665                          "glBeginQueryEXT",
17666                          "id not made by glGenQueriesEXT");
17667       return error::kNoError;
17668     }
17669 
17670     query =
17671         query_manager_->CreateQuery(target, client_id, std::move(buffer), sync);
17672   } else {
17673     if (query->target() != target) {
17674       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT",
17675                          "target does not match");
17676       return error::kNoError;
17677     } else if (query->sync() != sync) {
17678       DLOG(ERROR) << "Shared memory used by query not the same as before";
17679       return error::kInvalidArguments;
17680     }
17681   }
17682 
17683   query_manager_->BeginQuery(query);
17684   return error::kNoError;
17685 }
17686 
ReadBackBuffersIntoShadowCopies(base::flat_set<scoped_refptr<Buffer>> buffers_to_shadow_copy)17687 void GLES2DecoderImpl::ReadBackBuffersIntoShadowCopies(
17688     base::flat_set<scoped_refptr<Buffer>> buffers_to_shadow_copy) {
17689   GLuint old_binding =
17690       state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0;
17691 
17692   for (scoped_refptr<Buffer>& buffer : buffers_to_shadow_copy) {
17693     if (buffer->IsDeleted()) {
17694       continue;
17695     }
17696     void* shadow = nullptr;
17697     scoped_refptr<gpu::Buffer> gpu_buffer =
17698         buffer->TakeReadbackShadowAllocation(&shadow);
17699     if (!shadow) {
17700       continue;
17701     }
17702 
17703     if (buffer->GetMappedRange()) {
17704       // The buffer is already mapped by the client. It's okay that the shadow
17705       // copy will be out-of-date, because the client will never read it:
17706       // * Client issues READBACK_SHADOW_COPIES_UPDATED_CHROMIUM query
17707       // * Client maps buffer
17708       // * Client receives signal that the query completed
17709       // * Client unmaps buffer - invalidating the shadow copy
17710       // * Client maps buffer to read back - hits the round-trip path
17711       continue;
17712     }
17713 
17714     api()->glBindBufferFn(GL_ARRAY_BUFFER, buffer->service_id());
17715     void* mapped = api()->glMapBufferRangeFn(GL_ARRAY_BUFFER, 0, buffer->size(),
17716                                              GL_MAP_READ_BIT);
17717     if (!mapped) {
17718       DLOG(ERROR) << "glMapBufferRange unexpectedly returned nullptr";
17719       MarkContextLost(error::kOutOfMemory);
17720       group_->LoseContexts(error::kUnknown);
17721       return;
17722     }
17723     memcpy(shadow, mapped, buffer->size());
17724     bool unmap_ok = api()->glUnmapBufferFn(GL_ARRAY_BUFFER);
17725     if (unmap_ok == GL_FALSE) {
17726       DLOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
17727       MarkContextLost(error::kUnknown);
17728       group_->LoseContexts(error::kUnknown);
17729       return;
17730     }
17731   }
17732 
17733   // Restore original GL_ARRAY_BUFFER binding
17734   api()->glBindBufferFn(GL_ARRAY_BUFFER, old_binding);
17735 }
17736 
HandleEndQueryEXT(uint32_t immediate_data_size,const volatile void * cmd_data)17737 error::Error GLES2DecoderImpl::HandleEndQueryEXT(
17738     uint32_t immediate_data_size,
17739     const volatile void* cmd_data) {
17740   const volatile gles2::cmds::EndQueryEXT& c =
17741       *static_cast<const volatile gles2::cmds::EndQueryEXT*>(cmd_data);
17742   GLenum target = static_cast<GLenum>(c.target);
17743   uint32_t submit_count = static_cast<GLuint>(c.submit_count);
17744 
17745   QueryManager::Query* query = query_manager_->GetActiveQuery(target);
17746   if (!query) {
17747     LOCAL_SET_GL_ERROR(
17748         GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
17749     return error::kNoError;
17750   }
17751 
17752   if (target == GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM &&
17753       !writes_submitted_but_not_completed_.empty()) {
17754     // - This callback will be called immediately by MarkAsCompleted, so it's
17755     //   okay that it's called after UnmarkAsPending. (It's guaranteed to not be
17756     //   called immediately here, because the query has not even ended yet.)
17757     //
17758     // - It's okay to capture Unretained(this) because the callback is called by
17759     //   the query, which is owned by query_manager_, which is owned by `this`.
17760     query->AddCallback(
17761         base::BindOnce(&GLES2DecoderImpl::ReadBackBuffersIntoShadowCopies,
17762                        base::Unretained(this),
17763                        std::move(writes_submitted_but_not_completed_)));
17764     writes_submitted_but_not_completed_.clear();
17765   }
17766 
17767   query_manager_->EndQuery(query, submit_count);
17768   return error::kNoError;
17769 }
17770 
HandleQueryCounterEXT(uint32_t immediate_data_size,const volatile void * cmd_data)17771 error::Error GLES2DecoderImpl::HandleQueryCounterEXT(
17772     uint32_t immediate_data_size,
17773     const volatile void* cmd_data) {
17774   const volatile gles2::cmds::QueryCounterEXT& c =
17775       *static_cast<const volatile gles2::cmds::QueryCounterEXT*>(cmd_data);
17776   GLuint client_id = static_cast<GLuint>(c.id);
17777   GLenum target = static_cast<GLenum>(c.target);
17778   int32_t sync_shm_id = static_cast<int32_t>(c.sync_data_shm_id);
17779   uint32_t sync_shm_offset = static_cast<uint32_t>(c.sync_data_shm_offset);
17780   uint32_t submit_count = static_cast<GLuint>(c.submit_count);
17781 
17782   switch (target) {
17783     case GL_COMMANDS_ISSUED_TIMESTAMP_CHROMIUM:
17784       break;
17785     case GL_TIMESTAMP:
17786       if (!query_manager_->GPUTimingAvailable()) {
17787         LOCAL_SET_GL_ERROR(
17788             GL_INVALID_OPERATION, "glQueryCounterEXT",
17789             "not enabled for timing queries");
17790         return error::kNoError;
17791       }
17792       break;
17793     default:
17794       LOCAL_SET_GL_ERROR(
17795           GL_INVALID_ENUM, "glQueryCounterEXT",
17796           "unknown query target");
17797       return error::kNoError;
17798   }
17799 
17800   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
17801   if (!buffer)
17802     return error::kInvalidArguments;
17803   QuerySync* sync = static_cast<QuerySync*>(
17804       buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
17805   if (!sync)
17806     return error::kOutOfBounds;
17807 
17808   QueryManager::Query* query = query_manager_->GetQuery(client_id);
17809   if (!query) {
17810     if (!query_manager_->IsValidQuery(client_id)) {
17811       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
17812                          "glQueryCounterEXT",
17813                          "id not made by glGenQueriesEXT");
17814       return error::kNoError;
17815     }
17816     query =
17817         query_manager_->CreateQuery(target, client_id, std::move(buffer), sync);
17818   } else {
17819     if (query->target() != target) {
17820       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glQueryCounterEXT",
17821                          "target does not match");
17822       return error::kNoError;
17823     } else if (query->sync() != sync) {
17824       DLOG(ERROR) << "Shared memory used by query not the same as before";
17825       return error::kInvalidArguments;
17826     }
17827   }
17828   query_manager_->QueryCounter(query, submit_count);
17829 
17830   return error::kNoError;
17831 }
17832 
HandleSetDisjointValueSyncCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)17833 error::Error GLES2DecoderImpl::HandleSetDisjointValueSyncCHROMIUM(
17834     uint32_t immediate_data_size,
17835     const volatile void* cmd_data) {
17836   const volatile gles2::cmds::SetDisjointValueSyncCHROMIUM& c =
17837       *static_cast<const volatile gles2::cmds::SetDisjointValueSyncCHROMIUM*>(
17838           cmd_data);
17839   int32_t sync_shm_id = static_cast<int32_t>(c.sync_data_shm_id);
17840   uint32_t sync_shm_offset = static_cast<uint32_t>(c.sync_data_shm_offset);
17841 
17842   return query_manager_->SetDisjointSync(sync_shm_id, sync_shm_offset);
17843 }
17844 
GenVertexArraysOESHelper(GLsizei n,const GLuint * client_ids)17845 bool GLES2DecoderImpl::GenVertexArraysOESHelper(
17846     GLsizei n, const GLuint* client_ids) {
17847   for (GLsizei ii = 0; ii < n; ++ii) {
17848     if (GetVertexAttribManager(client_ids[ii])) {
17849       return false;
17850     }
17851   }
17852 
17853   if (!features().native_vertex_array_object) {
17854     // Emulated VAO
17855     for (GLsizei ii = 0; ii < n; ++ii) {
17856       CreateVertexAttribManager(client_ids[ii], 0, true);
17857     }
17858   } else {
17859     std::unique_ptr<GLuint[]> service_ids(new GLuint[n]);
17860 
17861     api()->glGenVertexArraysOESFn(n, service_ids.get());
17862     for (GLsizei ii = 0; ii < n; ++ii) {
17863       CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
17864     }
17865   }
17866 
17867   return true;
17868 }
17869 
DeleteVertexArraysOESHelper(GLsizei n,const volatile GLuint * client_ids)17870 void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
17871     GLsizei n,
17872     const volatile GLuint* client_ids) {
17873   for (GLsizei ii = 0; ii < n; ++ii) {
17874     GLuint client_id = client_ids[ii];
17875     VertexAttribManager* vao = GetVertexAttribManager(client_id);
17876     if (vao && !vao->IsDeleted()) {
17877       if (state_.vertex_attrib_manager.get() == vao) {
17878         DoBindVertexArrayOES(0);
17879       }
17880       RemoveVertexAttribManager(client_id);
17881     }
17882   }
17883 }
17884 
DoBindVertexArrayOES(GLuint client_id)17885 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
17886   VertexAttribManager* vao = nullptr;
17887   if (client_id != 0) {
17888     vao = GetVertexAttribManager(client_id);
17889     if (!vao) {
17890       // Unlike most Bind* methods, the spec explicitly states that VertexArray
17891       // only allows names that have been previously generated. As such, we do
17892       // not generate new names here.
17893       LOCAL_SET_GL_ERROR(
17894           GL_INVALID_OPERATION,
17895           "glBindVertexArrayOES", "bad vertex array id.");
17896       current_decoder_error_ = error::kNoError;
17897       return;
17898     }
17899   } else {
17900     vao = state_.default_vertex_attrib_manager.get();
17901   }
17902 
17903   // Only set the VAO state if it's changed
17904   if (state_.vertex_attrib_manager.get() != vao) {
17905     if (state_.vertex_attrib_manager)
17906       state_.vertex_attrib_manager->SetIsBound(false);
17907     state_.vertex_attrib_manager = vao;
17908     if (vao)
17909       vao->SetIsBound(true);
17910     if (!features().native_vertex_array_object) {
17911       EmulateVertexArrayState();
17912     } else {
17913       GLuint service_id = vao->service_id();
17914       api()->glBindVertexArrayOESFn(service_id);
17915     }
17916   }
17917 }
17918 
17919 // Used when OES_vertex_array_object isn't natively supported
EmulateVertexArrayState()17920 void GLES2DecoderImpl::EmulateVertexArrayState() {
17921   // Setup the Vertex attribute state
17922   for (uint32_t vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
17923     RestoreStateForAttrib(vv, true);
17924   }
17925 
17926   // Setup the element buffer
17927   Buffer* element_array_buffer =
17928       state_.vertex_attrib_manager->element_array_buffer();
17929   api()->glBindBufferFn(
17930       GL_ELEMENT_ARRAY_BUFFER,
17931       element_array_buffer ? element_array_buffer->service_id() : 0);
17932 }
17933 
DoIsVertexArrayOES(GLuint client_id)17934 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
17935   const VertexAttribManager* vao =
17936       GetVertexAttribManager(client_id);
17937   return vao && vao->IsValid() && !vao->IsDeleted();
17938 }
17939 
DoIsSync(GLuint client_id)17940 bool GLES2DecoderImpl::DoIsSync(GLuint client_id) {
17941   GLsync service_sync = 0;
17942   return group_->GetSyncServiceId(client_id, &service_sync);
17943 }
17944 
ValidateCopyTextureCHROMIUMTextures(const char * function_name,GLenum dest_target,TextureRef * source_texture_ref,TextureRef * dest_texture_ref)17945 bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMTextures(
17946     const char* function_name,
17947     GLenum dest_target,
17948     TextureRef* source_texture_ref,
17949     TextureRef* dest_texture_ref) {
17950   if (!source_texture_ref || !dest_texture_ref) {
17951     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
17952     return false;
17953   }
17954 
17955   Texture* source_texture = source_texture_ref->texture();
17956   Texture* dest_texture = dest_texture_ref->texture();
17957   if (source_texture == dest_texture) {
17958     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
17959                        "source and destination textures are the same");
17960     return false;
17961   }
17962 
17963   if (dest_texture->target() !=
17964       GLES2Util::GLFaceTargetToTextureTarget(dest_target)) {
17965     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
17966                        "target should be aligned with dest target");
17967     return false;
17968   }
17969   switch (dest_texture->target()) {
17970     case GL_TEXTURE_2D:
17971     case GL_TEXTURE_CUBE_MAP:
17972     case GL_TEXTURE_RECTANGLE_ARB:
17973       break;
17974     default:
17975     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
17976                        "invalid dest texture target binding");
17977     return false;
17978   }
17979 
17980   switch (source_texture->target()) {
17981     case GL_TEXTURE_2D:
17982     case GL_TEXTURE_RECTANGLE_ARB:
17983     case GL_TEXTURE_EXTERNAL_OES:
17984       break;
17985     default:
17986     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
17987                        "invalid source texture target binding");
17988     return false;
17989   }
17990   return true;
17991 }
17992 
CanUseCopyTextureCHROMIUMInternalFormat(GLenum dest_internal_format)17993 bool GLES2DecoderImpl::CanUseCopyTextureCHROMIUMInternalFormat(
17994     GLenum dest_internal_format) {
17995   switch (dest_internal_format) {
17996     case GL_RGB:
17997     case GL_RGBA:
17998     case GL_RGB8:
17999     case GL_RGBA8:
18000     case GL_BGRA_EXT:
18001     case GL_BGRA8_EXT:
18002     case GL_SRGB_EXT:
18003     case GL_SRGB_ALPHA_EXT:
18004     case GL_R8:
18005     case GL_R8UI:
18006     case GL_RG8:
18007     case GL_RG8UI:
18008     case GL_SRGB8:
18009     case GL_RGB565:
18010     case GL_RGB8UI:
18011     case GL_SRGB8_ALPHA8:
18012     case GL_RGB5_A1:
18013     case GL_RGBA4:
18014     case GL_RGBA8UI:
18015     case GL_RGB9_E5:
18016     case GL_R16F:
18017     case GL_R32F:
18018     case GL_RG16F:
18019     case GL_RG32F:
18020     case GL_RGB16F:
18021     case GL_RGB32F:
18022     case GL_RGBA16F:
18023     case GL_RGBA32F:
18024     case GL_R11F_G11F_B10F:
18025       return true;
18026     default:
18027       return false;
18028   }
18029 }
18030 
DoCopyTextureCHROMIUM(GLuint source_id,GLint source_level,GLenum dest_target,GLuint dest_id,GLint dest_level,GLenum internal_format,GLenum dest_type,GLboolean unpack_flip_y,GLboolean unpack_premultiply_alpha,GLboolean unpack_unmultiply_alpha)18031 void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
18032     GLuint source_id,
18033     GLint source_level,
18034     GLenum dest_target,
18035     GLuint dest_id,
18036     GLint dest_level,
18037     GLenum internal_format,
18038     GLenum dest_type,
18039     GLboolean unpack_flip_y,
18040     GLboolean unpack_premultiply_alpha,
18041     GLboolean unpack_unmultiply_alpha) {
18042   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
18043   static const char kFunctionName[] = "glCopyTextureCHROMIUM";
18044 
18045   TextureRef* source_texture_ref = GetTexture(source_id);
18046   TextureRef* dest_texture_ref = GetTexture(dest_id);
18047 
18048   if (!ValidateCopyTextureCHROMIUMTextures(
18049           kFunctionName, dest_target, source_texture_ref, dest_texture_ref)) {
18050     return;
18051   }
18052 
18053   if (source_level < 0 || dest_level < 0 ||
18054       (feature_info_->IsWebGL1OrES2Context() && source_level > 0)) {
18055     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
18056                        "source_level or dest_level out of range");
18057     return;
18058   }
18059 
18060   Texture* source_texture = source_texture_ref->texture();
18061   Texture* dest_texture = dest_texture_ref->texture();
18062   GLenum source_target = source_texture->target();
18063   GLenum dest_binding_target = dest_texture->target();
18064 
18065   GLenum source_type = 0;
18066   GLenum source_internal_format = 0;
18067   source_texture->GetLevelType(source_target, source_level, &source_type,
18068                                &source_internal_format);
18069   GLenum format =
18070       TextureManager::ExtractFormatFromStorageFormat(internal_format);
18071   if (!texture_manager()->ValidateTextureParameters(
18072           error_state_.get(), kFunctionName, true, format, dest_type,
18073           internal_format, dest_level)) {
18074     return;
18075   }
18076 
18077   std::string output_error_msg;
18078   if (!ValidateCopyTextureCHROMIUMInternalFormats(
18079           GetFeatureInfo(), source_internal_format, internal_format,
18080           &output_error_msg)) {
18081     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
18082                        output_error_msg.c_str());
18083     return;
18084   }
18085 
18086   if (source_target == GL_TEXTURE_EXTERNAL_OES &&
18087       CopyTextureCHROMIUMNeedsESSL3(internal_format) &&
18088       !feature_info_->feature_flags().oes_egl_image_external_essl3) {
18089     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
18090                        "Copy*TextureCHROMIUM from EXTERNAL_OES to integer "
18091                        "format requires OES_EGL_image_external_essl3");
18092     return;
18093   }
18094 
18095   if (feature_info_->feature_flags().desktop_srgb_support) {
18096     bool enable_framebuffer_srgb =
18097         GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
18098             GL_SRGB ||
18099         GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ==
18100             GL_SRGB;
18101     state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
18102   }
18103 
18104   int source_width = 0;
18105   int source_height = 0;
18106   gl::GLImage* image =
18107       source_texture->GetLevelImage(source_target, source_level);
18108   if (image) {
18109     gfx::Size size = image->GetSize();
18110     source_width = size.width();
18111     source_height = size.height();
18112     if (source_width <= 0 || source_height <= 0) {
18113       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size");
18114       return;
18115     }
18116   } else {
18117     if (!source_texture->GetLevelSize(source_target, source_level,
18118                                       &source_width, &source_height, nullptr)) {
18119       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
18120                          "source texture has no data for level");
18121       return;
18122     }
18123 
18124     // Check that this type of texture is allowed.
18125     if (!texture_manager()->ValidForTarget(source_target, source_level,
18126                                            source_width, source_height, 1)) {
18127       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
18128       return;
18129     }
18130   }
18131 
18132   if (dest_texture->IsImmutable()) {
18133     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
18134                        "texture is immutable");
18135     return;
18136   }
18137 
18138   // Clear the source texture if necessary.
18139   if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
18140                                             source_target, source_level)) {
18141     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, "dimensions too big");
18142     return;
18143   }
18144 
18145   if (!InitializeCopyTextureCHROMIUM(kFunctionName))
18146     return;
18147 
18148   GLenum dest_type_previous = dest_type;
18149   GLenum dest_internal_format = internal_format;
18150   int dest_width = 0;
18151   int dest_height = 0;
18152   bool dest_level_defined = dest_texture->GetLevelSize(
18153       dest_target, dest_level, &dest_width, &dest_height, nullptr);
18154 
18155   if (dest_level_defined) {
18156     dest_texture->GetLevelType(dest_target, dest_level, &dest_type_previous,
18157                                &dest_internal_format);
18158   }
18159 
18160   // Resize the destination texture to the dimensions of the source texture.
18161   if (!dest_level_defined || dest_width != source_width ||
18162       dest_height != source_height ||
18163       dest_internal_format != internal_format ||
18164       dest_type_previous != dest_type) {
18165     // Ensure that the glTexImage2D succeeds.
18166     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName);
18167     api()->glBindTextureFn(dest_binding_target, dest_texture->service_id());
18168     ScopedPixelUnpackState reset_restore(&state_);
18169     api()->glTexImage2DFn(
18170         dest_target, dest_level,
18171         TextureManager::AdjustTexInternalFormat(feature_info_.get(),
18172                                                 internal_format, dest_type),
18173         source_width, source_height, 0,
18174         TextureManager::AdjustTexFormat(feature_info_.get(), format), dest_type,
18175         nullptr);
18176     GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName);
18177     if (error != GL_NO_ERROR) {
18178       RestoreCurrentTextureBindings(&state_, dest_binding_target,
18179                                     state_.active_texture_unit);
18180       return;
18181     }
18182 
18183     texture_manager()->SetLevelInfo(dest_texture_ref, dest_target, dest_level,
18184                                     internal_format, source_width,
18185                                     source_height, 1, 0, format, dest_type,
18186                                     gfx::Rect(source_width, source_height));
18187     dest_texture->ApplyFormatWorkarounds(feature_info_.get());
18188   } else {
18189     texture_manager()->SetLevelCleared(dest_texture_ref, dest_target,
18190                                        dest_level, true);
18191   }
18192 
18193   // Try using GLImage::CopyTexImage when possible.
18194   bool unpack_premultiply_alpha_change =
18195       (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
18196   // TODO(qiankun.miao@intel.com): Support level > 0 for CopyTexImage.
18197   if (image && internal_format == source_internal_format && dest_level == 0 &&
18198       !unpack_flip_y && !unpack_premultiply_alpha_change) {
18199     api()->glBindTextureFn(dest_binding_target, dest_texture->service_id());
18200     if (image->ShouldBindOrCopy() == gl::GLImage::COPY &&
18201         image->CopyTexImage(dest_target)) {
18202       return;
18203     }
18204   }
18205 
18206   DoBindOrCopyTexImageIfNeeded(source_texture, source_target, 0);
18207 
18208   CopyTextureMethod method = GetCopyTextureCHROMIUMMethod(
18209       GetFeatureInfo(), source_target, source_level, source_internal_format,
18210       source_type, dest_binding_target, dest_level, internal_format,
18211       unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18212       unpack_unmultiply_alpha == GL_TRUE, false /* dither */);
18213 
18214   // GL_TEXTURE_EXTERNAL_OES texture requires that we apply a transform matrix
18215   // before presenting.
18216   if (source_target == GL_TEXTURE_EXTERNAL_OES) {
18217     if (GLStreamTextureImage* texture_image =
18218             source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
18219                                                        source_level)) {
18220       GLfloat transform_matrix[16];
18221       texture_image->GetTextureMatrix(transform_matrix);
18222       copy_texture_chromium_->DoCopyTextureWithTransform(
18223           this, source_target, source_texture->service_id(), source_level,
18224           source_internal_format, dest_target, dest_texture->service_id(),
18225           dest_level, internal_format, source_width, source_height,
18226           unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18227           unpack_unmultiply_alpha == GL_TRUE, false /* dither */,
18228           transform_matrix, method, copy_tex_image_blit_.get());
18229       return;
18230     }
18231   }
18232   copy_texture_chromium_->DoCopyTexture(
18233       this, source_target, source_texture->service_id(), source_level,
18234       source_internal_format, dest_target, dest_texture->service_id(),
18235       dest_level, internal_format, source_width, source_height,
18236       unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18237       unpack_unmultiply_alpha == GL_TRUE, false /* dither */, method,
18238       copy_tex_image_blit_.get());
18239 }
18240 
CopySubTextureHelper(const char * function_name,GLuint source_id,GLint source_level,GLenum dest_target,GLuint dest_id,GLint dest_level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLboolean unpack_flip_y,GLboolean unpack_premultiply_alpha,GLboolean unpack_unmultiply_alpha,GLboolean dither)18241 void GLES2DecoderImpl::CopySubTextureHelper(const char* function_name,
18242                                             GLuint source_id,
18243                                             GLint source_level,
18244                                             GLenum dest_target,
18245                                             GLuint dest_id,
18246                                             GLint dest_level,
18247                                             GLint xoffset,
18248                                             GLint yoffset,
18249                                             GLint x,
18250                                             GLint y,
18251                                             GLsizei width,
18252                                             GLsizei height,
18253                                             GLboolean unpack_flip_y,
18254                                             GLboolean unpack_premultiply_alpha,
18255                                             GLboolean unpack_unmultiply_alpha,
18256                                             GLboolean dither) {
18257   TextureRef* source_texture_ref = GetTexture(source_id);
18258   TextureRef* dest_texture_ref = GetTexture(dest_id);
18259 
18260   if (!ValidateCopyTextureCHROMIUMTextures(
18261           function_name, dest_target, source_texture_ref, dest_texture_ref)) {
18262     return;
18263   }
18264 
18265   if (source_level < 0 || dest_level < 0 ||
18266       (feature_info_->IsWebGL1OrES2Context() && source_level > 0)) {
18267     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18268                        "source_level or dest_level out of range");
18269     return;
18270   }
18271 
18272   Texture* source_texture = source_texture_ref->texture();
18273   Texture* dest_texture = dest_texture_ref->texture();
18274   GLenum source_target = source_texture->target();
18275   GLenum dest_binding_target = dest_texture->target();
18276   int source_width = 0;
18277   int source_height = 0;
18278   gl::GLImage* image =
18279       source_texture->GetLevelImage(source_target, source_level);
18280   if (image) {
18281     gfx::Size size = image->GetSize();
18282     source_width = size.width();
18283     source_height = size.height();
18284     if (source_width <= 0 || source_height <= 0) {
18285       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid image size");
18286       return;
18287     }
18288 
18289     // Ideally we should not need to check that the sub-texture copy rectangle
18290     // is valid in two different ways, here and below. However currently there
18291     // is no guarantee that a texture backed by a GLImage will have sensible
18292     // level info. If this synchronization were to be enforced then this and
18293     // other functions in this file could be cleaned up.
18294     // See: https://crbug.com/586476
18295     int32_t max_x;
18296     int32_t max_y;
18297     if (!base::CheckAdd(x, width).AssignIfValid(&max_x) ||
18298         !base::CheckAdd(y, height).AssignIfValid(&max_y) || x < 0 || y < 0 ||
18299         max_x > source_width || max_y > source_height) {
18300       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18301                          "source texture bad dimensions");
18302       return;
18303     }
18304   } else {
18305     if (!source_texture->GetLevelSize(source_target, source_level,
18306                                       &source_width, &source_height, nullptr)) {
18307       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18308                          "source texture has no data for level");
18309       return;
18310     }
18311 
18312     // Check that this type of texture is allowed.
18313     if (!texture_manager()->ValidForTarget(source_target, source_level,
18314                                            source_width, source_height, 1)) {
18315       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18316                          "source texture bad dimensions");
18317       return;
18318     }
18319 
18320     if (!source_texture->ValidForTexture(source_target, source_level, x, y, 0,
18321                                          width, height, 1)) {
18322       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18323                          "source texture bad dimensions.");
18324       return;
18325     }
18326   }
18327 
18328   GLenum source_type = 0;
18329   GLenum source_internal_format = 0;
18330   source_texture->GetLevelType(source_target, source_level, &source_type,
18331                                &source_internal_format);
18332 
18333   GLenum dest_type = 0;
18334   GLenum dest_internal_format = 0;
18335   bool dest_level_defined = dest_texture->GetLevelType(
18336       dest_target, dest_level, &dest_type, &dest_internal_format);
18337   if (!dest_level_defined) {
18338     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
18339                        "destination texture is not defined");
18340     return;
18341   }
18342   if (!dest_texture->ValidForTexture(dest_target, dest_level, xoffset, yoffset,
18343                                      0, width, height, 1)) {
18344     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
18345                        "destination texture bad dimensions.");
18346     return;
18347   }
18348 
18349   std::string output_error_msg;
18350   if (!ValidateCopyTextureCHROMIUMInternalFormats(
18351           GetFeatureInfo(), source_internal_format, dest_internal_format,
18352           &output_error_msg)) {
18353     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
18354                        output_error_msg.c_str());
18355     return;
18356   }
18357 
18358   if (source_target == GL_TEXTURE_EXTERNAL_OES &&
18359       CopyTextureCHROMIUMNeedsESSL3(dest_internal_format) &&
18360       !feature_info_->feature_flags().oes_egl_image_external_essl3) {
18361     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
18362                        "Copy*TextureCHROMIUM from EXTERNAL_OES to integer "
18363                        "format requires OES_EGL_image_external_essl3");
18364     return;
18365   }
18366 
18367   if (feature_info_->feature_flags().desktop_srgb_support) {
18368     bool enable_framebuffer_srgb =
18369         GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
18370             GL_SRGB ||
18371         GLES2Util::GetColorEncodingFromInternalFormat(dest_internal_format) ==
18372             GL_SRGB;
18373     state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
18374   }
18375 
18376   // Clear the source texture if necessary.
18377   if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
18378                                             source_target, source_level)) {
18379     LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name,
18380                        "source texture dimensions too big");
18381     return;
18382   }
18383 
18384   if (!InitializeCopyTextureCHROMIUM(function_name))
18385     return;
18386 
18387   int dest_width = 0;
18388   int dest_height = 0;
18389   bool ok = dest_texture->GetLevelSize(dest_target, dest_level, &dest_width,
18390                                        &dest_height, nullptr);
18391   DCHECK(ok);
18392   if (xoffset != 0 || yoffset != 0 || width != dest_width ||
18393       height != dest_height) {
18394     gfx::Rect cleared_rect;
18395     if (TextureManager::CombineAdjacentRects(
18396             dest_texture->GetLevelClearedRect(dest_target, dest_level),
18397             gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
18398       DCHECK_GE(cleared_rect.size().GetArea(),
18399                 dest_texture->GetLevelClearedRect(dest_target, dest_level)
18400                     .size()
18401                     .GetArea());
18402       texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target,
18403                                              dest_level, cleared_rect);
18404     } else {
18405       // Otherwise clear part of texture level that is not already cleared.
18406       if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref,
18407                                                 dest_target, dest_level)) {
18408         LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name,
18409                            "destination texture dimensions too big");
18410         return;
18411       }
18412     }
18413   } else {
18414     texture_manager()->SetLevelCleared(dest_texture_ref, dest_target,
18415                                        dest_level, true);
18416   }
18417 
18418   // Try using GLImage::CopyTexSubImage when possible.
18419   bool unpack_premultiply_alpha_change =
18420       (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
18421   // TODO(qiankun.miao@intel.com): Support level > 0 for CopyTexSubImage.
18422   if (image && dest_internal_format == source_internal_format &&
18423       dest_level == 0 && !unpack_flip_y && !unpack_premultiply_alpha_change &&
18424       !dither) {
18425     ScopedTextureBinder binder(&state_, error_state_.get(),
18426                                dest_texture->service_id(), dest_binding_target);
18427     if (image->CopyTexSubImage(dest_target, gfx::Point(xoffset, yoffset),
18428                                gfx::Rect(x, y, width, height))) {
18429       return;
18430     }
18431   }
18432 
18433   DoBindOrCopyTexImageIfNeeded(source_texture, source_target, 0);
18434 
18435   // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
18436   // before presenting.
18437   if (source_target == GL_TEXTURE_EXTERNAL_OES) {
18438     if (GLStreamTextureImage* texture_image =
18439             source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
18440                                                        source_level)) {
18441       GLfloat transform_matrix[16];
18442       texture_image->GetTextureMatrix(transform_matrix);
18443       copy_texture_chromium_->DoCopySubTextureWithTransform(
18444           this, source_target, source_texture->service_id(), source_level,
18445           source_internal_format, dest_target, dest_texture->service_id(),
18446           dest_level, dest_internal_format, xoffset, yoffset, x, y, width,
18447           height, dest_width, dest_height, source_width, source_height,
18448           unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18449           unpack_unmultiply_alpha == GL_TRUE, dither == GL_TRUE,
18450           transform_matrix, copy_tex_image_blit_.get());
18451       return;
18452     }
18453   }
18454 
18455   CopyTextureMethod method = GetCopyTextureCHROMIUMMethod(
18456       GetFeatureInfo(), source_target, source_level, source_internal_format,
18457       source_type, dest_binding_target, dest_level, dest_internal_format,
18458       unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18459       unpack_unmultiply_alpha == GL_TRUE, dither == GL_TRUE);
18460 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
18461   // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver,
18462   // although opposite in Android.
18463   // TODO(dshwang): After Mesa fixes this issue, remove this hack.
18464   // https://bugs.freedesktop.org/show_bug.cgi?id=98478,
18465   // https://crbug.com/535198.
18466   if (Texture::ColorRenderable(GetFeatureInfo(), dest_internal_format,
18467                                dest_texture->IsImmutable()) &&
18468       method == CopyTextureMethod::DIRECT_COPY) {
18469     method = CopyTextureMethod::DIRECT_DRAW;
18470   }
18471 #endif
18472 
18473   // Use DRAW instead of COPY if the workaround is enabled.
18474   if (method == CopyTextureMethod::DIRECT_COPY &&
18475       workarounds().prefer_draw_to_copy) {
18476     method = CopyTextureMethod::DIRECT_DRAW;
18477   }
18478 
18479   copy_texture_chromium_->DoCopySubTexture(
18480       this, source_target, source_texture->service_id(), source_level,
18481       source_internal_format, dest_target, dest_texture->service_id(),
18482       dest_level, dest_internal_format, xoffset, yoffset, x, y, width, height,
18483       dest_width, dest_height, source_width, source_height,
18484       unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
18485       unpack_unmultiply_alpha == GL_TRUE, dither == GL_TRUE, method,
18486       copy_tex_image_blit_.get());
18487 }
18488 
DoCopySubTextureCHROMIUM(GLuint source_id,GLint source_level,GLenum dest_target,GLuint dest_id,GLint dest_level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLboolean unpack_flip_y,GLboolean unpack_premultiply_alpha,GLboolean unpack_unmultiply_alpha)18489 void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
18490     GLuint source_id,
18491     GLint source_level,
18492     GLenum dest_target,
18493     GLuint dest_id,
18494     GLint dest_level,
18495     GLint xoffset,
18496     GLint yoffset,
18497     GLint x,
18498     GLint y,
18499     GLsizei width,
18500     GLsizei height,
18501     GLboolean unpack_flip_y,
18502     GLboolean unpack_premultiply_alpha,
18503     GLboolean unpack_unmultiply_alpha) {
18504   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
18505   static const char kFunctionName[] = "glCopySubTextureCHROMIUM";
18506   CopySubTextureHelper(kFunctionName, source_id, source_level, dest_target,
18507                        dest_id, dest_level, xoffset, yoffset, x, y, width,
18508                        height, unpack_flip_y, unpack_premultiply_alpha,
18509                        unpack_unmultiply_alpha, GL_FALSE /* dither */);
18510 }
18511 
InitializeCopyTexImageBlitter(const char * function_name)18512 bool GLES2DecoderImpl::InitializeCopyTexImageBlitter(
18513     const char* function_name) {
18514   if (!copy_tex_image_blit_.get()) {
18515     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
18516     copy_tex_image_blit_.reset(
18517         new CopyTexImageResourceManager(feature_info_.get()));
18518     copy_tex_image_blit_->Initialize(this);
18519     if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR)
18520       return false;
18521   }
18522   return true;
18523 }
18524 
InitializeCopyTextureCHROMIUM(const char * function_name)18525 bool GLES2DecoderImpl::InitializeCopyTextureCHROMIUM(
18526     const char* function_name) {
18527   // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
18528   // needed because it takes 10s of milliseconds to initialize.
18529   if (!copy_texture_chromium_.get()) {
18530     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
18531     copy_texture_chromium_.reset(CopyTextureCHROMIUMResourceManager::Create());
18532     copy_texture_chromium_->Initialize(this, features());
18533     if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR)
18534       return false;
18535 
18536     // On the desktop core profile this also needs emulation of
18537     // CopyTex{Sub}Image2D for luminance, alpha, and luminance_alpha
18538     // textures.
18539     if (CopyTexImageResourceManager::CopyTexImageRequiresBlit(
18540             feature_info_.get(), GL_LUMINANCE)) {
18541       if (!InitializeCopyTexImageBlitter(function_name))
18542         return false;
18543     }
18544   }
18545   return true;
18546 }
18547 
TexStorageImpl(GLenum target,GLsizei levels,GLenum internal_format,GLsizei width,GLsizei height,GLsizei depth,ContextState::Dimension dimension,const char * function_name)18548 void GLES2DecoderImpl::TexStorageImpl(GLenum target,
18549                                       GLsizei levels,
18550                                       GLenum internal_format,
18551                                       GLsizei width,
18552                                       GLsizei height,
18553                                       GLsizei depth,
18554                                       ContextState::Dimension dimension,
18555                                       const char* function_name) {
18556   if (levels == 0) {
18557     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "levels == 0");
18558     return;
18559   }
18560   bool is_compressed_format = IsCompressedTextureFormat(internal_format);
18561   if (is_compressed_format) {
18562     if (target == GL_TEXTURE_3D &&
18563         !feature_info_->feature_flags().ext_texture_format_astc_hdr &&
18564         ::gpu::gles2::IsASTCFormat(internal_format)) {
18565       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
18566                          "target invalid for format");
18567       return;
18568     }
18569     if (!::gpu::gles2::ValidateCompressedFormatTarget(target,
18570                                                       internal_format)) {
18571       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
18572                          "target invalid for format");
18573       return;
18574     }
18575   }
18576   // The glTexStorage entry points require width, height, and depth to be
18577   // at least 1, but the other texture entry points (those which use
18578   // ValidForTarget) do not. So we have to add an extra check here.
18579   bool is_invalid_texstorage_size = width < 1 || height < 1 || depth < 1;
18580   if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
18581       is_invalid_texstorage_size) {
18582     LOCAL_SET_GL_ERROR(
18583         GL_INVALID_VALUE, function_name, "dimensions out of range");
18584     return;
18585   }
18586   // glTexStorage generates GL_INVALID_OPERATION for out of bounds level
18587   // which is a bit different from other GL calls generating GL_INVALID_VALUE
18588   if (TextureManager::ComputeMipMapCount(target, width, height, depth) <
18589       levels) {
18590     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "too many levels");
18591     return;
18592   }
18593   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
18594       &state_, target);
18595   if (!texture_ref) {
18596     LOCAL_SET_GL_ERROR(
18597         GL_INVALID_OPERATION, function_name, "unknown texture for target");
18598     return;
18599   }
18600   Texture* texture = texture_ref->texture();
18601   if (texture->IsAttachedToFramebuffer()) {
18602     framebuffer_state_.clear_state_dirty = true;
18603   }
18604   if (texture->IsImmutable()) {
18605     LOCAL_SET_GL_ERROR(
18606         GL_INVALID_OPERATION, function_name, "texture is immutable");
18607     return;
18608   }
18609 
18610   GLenum format = TextureManager::ExtractFormatFromStorageFormat(
18611       internal_format);
18612   GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
18613 
18614   {
18615     GLsizei level_width = width;
18616     GLsizei level_height = height;
18617     GLsizei level_depth = depth;
18618     base::CheckedNumeric<uint32_t> estimated_size(0);
18619     PixelStoreParams params;
18620     params.alignment = 1;
18621     for (int ii = 0; ii < levels; ++ii) {
18622       uint32_t size;
18623       if (is_compressed_format) {
18624         GLsizei level_size;
18625         if (!GetCompressedTexSizeInBytes(
18626                 function_name, level_width, level_height, level_depth,
18627                 internal_format, &level_size, error_state_.get())) {
18628           // GetCompressedTexSizeInBytes() already generates a GL error.
18629           return;
18630         }
18631         size = static_cast<uint32_t>(level_size);
18632       } else {
18633         if (!GLES2Util::ComputeImageDataSizesES3(level_width,
18634                                                  level_height,
18635                                                  level_depth,
18636                                                  format, type,
18637                                                  params,
18638                                                  &size,
18639                                                  nullptr, nullptr,
18640                                                  nullptr, nullptr)) {
18641           LOCAL_SET_GL_ERROR(
18642               GL_OUT_OF_MEMORY, function_name, "dimensions too large");
18643           return;
18644         }
18645       }
18646       estimated_size += size;
18647       level_width = std::max(1, level_width >> 1);
18648       level_height = std::max(1, level_height >> 1);
18649       if (target == GL_TEXTURE_3D)
18650         level_depth = std::max(1, level_depth >> 1);
18651     }
18652     if (!estimated_size.IsValid()) {
18653       LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory");
18654       return;
18655     }
18656   }
18657 
18658   // First lookup compatibility format via texture manager for swizzling legacy
18659   // LUMINANCE/ALPHA formats.
18660   GLenum compatibility_internal_format =
18661       texture_manager()->AdjustTexStorageFormat(feature_info_.get(),
18662                                                 internal_format);
18663 
18664   // Then lookup compatibility format for compressed formats.
18665   const CompressedFormatInfo* format_info =
18666       GetCompressedFormatInfo(internal_format);
18667   if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
18668     compatibility_internal_format = format_info->decompressed_internal_format;
18669   }
18670 
18671   {
18672     GLsizei level_width = width;
18673     GLsizei level_height = height;
18674     GLsizei level_depth = depth;
18675 
18676     GLenum adjusted_internal_format =
18677         feature_info_->IsWebGL1OrES2Context() ? format : internal_format;
18678     for (int ii = 0; ii < levels; ++ii) {
18679       if (target == GL_TEXTURE_CUBE_MAP) {
18680         for (int jj = 0; jj < 6; ++jj) {
18681           GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + jj;
18682           texture_manager()->SetLevelInfo(
18683               texture_ref, face, ii, adjusted_internal_format, level_width,
18684               level_height, 1, 0, format, type, gfx::Rect());
18685         }
18686       } else {
18687         texture_manager()->SetLevelInfo(
18688             texture_ref, target, ii, adjusted_internal_format, level_width,
18689             level_height, level_depth, 0, format, type, gfx::Rect());
18690       }
18691       level_width = std::max(1, level_width >> 1);
18692       level_height = std::max(1, level_height >> 1);
18693       if (target == GL_TEXTURE_3D)
18694         level_depth = std::max(1, level_depth >> 1);
18695     }
18696     texture->ApplyFormatWorkarounds(feature_info_.get());
18697     texture->SetImmutable(true, true);
18698   }
18699 
18700   if (workarounds().reset_base_mipmap_level_before_texstorage &&
18701       texture->base_level() > 0)
18702     api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL, 0);
18703 
18704   // TODO(zmo): We might need to emulate TexStorage using TexImage or
18705   // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying
18706   // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
18707   if (dimension == ContextState::k2D) {
18708     api()->glTexStorage2DEXTFn(target, levels, compatibility_internal_format,
18709                                width, height);
18710   } else {
18711     api()->glTexStorage3DFn(target, levels, compatibility_internal_format,
18712                             width, height, depth);
18713   }
18714   if (workarounds().reset_base_mipmap_level_before_texstorage &&
18715       texture->base_level() > 0) {
18716     // Note base_level is already clamped due to texture->SetImmutable(true).
18717     // This is necessary for certain NVidia Linux drivers; otherwise they
18718     // may trigger segmentation fault. See https://crbug.com/877874.
18719     api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
18720                              texture->base_level());
18721   }
18722 }
18723 
DoTexStorage2DEXT(GLenum target,GLsizei levels,GLenum internal_format,GLsizei width,GLsizei height)18724 void GLES2DecoderImpl::DoTexStorage2DEXT(GLenum target,
18725                                          GLsizei levels,
18726                                          GLenum internal_format,
18727                                          GLsizei width,
18728                                          GLsizei height) {
18729   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2D",
18730       "width", width, "height", height);
18731   TexStorageImpl(target, levels, internal_format, width, height, 1,
18732                  ContextState::k2D, "glTexStorage2D");
18733 }
18734 
DoTexStorage3D(GLenum target,GLsizei levels,GLenum internal_format,GLsizei width,GLsizei height,GLsizei depth)18735 void GLES2DecoderImpl::DoTexStorage3D(GLenum target,
18736                                       GLsizei levels,
18737                                       GLenum internal_format,
18738                                       GLsizei width,
18739                                       GLsizei height,
18740                                       GLsizei depth) {
18741   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage3D",
18742       "widthXheight", width * height, "depth", depth);
18743   TexStorageImpl(target, levels, internal_format, width, height, depth,
18744                  ContextState::k3D, "glTexStorage3D");
18745 }
18746 
DoTexStorage2DImageCHROMIUM(GLenum target,GLenum internal_format,GLenum buffer_usage,GLsizei width,GLsizei height)18747 void GLES2DecoderImpl::DoTexStorage2DImageCHROMIUM(GLenum target,
18748                                                    GLenum internal_format,
18749                                                    GLenum buffer_usage,
18750                                                    GLsizei width,
18751                                                    GLsizei height) {
18752   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DImageCHROMIUM", "width",
18753                width, "height", height);
18754 
18755   ScopedGLErrorSuppressor suppressor(
18756       "GLES2CmdDecoder::DoTexStorage2DImageCHROMIUM", error_state_.get());
18757 
18758   if (!texture_manager()->ValidForTarget(target, 0, width, height, 1)) {
18759     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DImageCHROMIUM",
18760                        "dimensions out of range");
18761     return;
18762   }
18763 
18764   TextureRef* texture_ref =
18765       texture_manager()->GetTextureInfoForTarget(&state_, target);
18766   if (!texture_ref) {
18767     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImageCHROMIUM",
18768                        "unknown texture for target");
18769     return;
18770   }
18771 
18772   Texture* texture = texture_ref->texture();
18773   if (texture->IsImmutable()) {
18774     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImageCHROMIUM",
18775                        "texture is immutable");
18776     return;
18777   }
18778 
18779   gfx::BufferFormat buffer_format;
18780   if (!GetGFXBufferFormat(internal_format, &buffer_format)) {
18781     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, "glTexStorage2DImageCHROMIUM",
18782                        "Invalid buffer format");
18783     return;
18784   }
18785 
18786   gfx::BufferUsage gfx_buffer_usage;
18787   if (!GetGFXBufferUsage(buffer_usage, &gfx_buffer_usage)) {
18788     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, "glTexStorage2DImageCHROMIUM",
18789                        "Invalid buffer usage");
18790     return;
18791   }
18792 
18793   if (!GetContextGroup()->image_factory()) {
18794     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImageCHROMIUM",
18795                        "Cannot create GL image");
18796     return;
18797   }
18798 
18799   bool is_cleared = false;
18800   scoped_refptr<gl::GLImage> image =
18801       GetContextGroup()->image_factory()->CreateAnonymousImage(
18802           gfx::Size(width, height), buffer_format, gfx_buffer_usage,
18803           gpu::kNullSurfaceHandle, &is_cleared);
18804   if (!image || !image->BindTexImage(target)) {
18805     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImageCHROMIUM",
18806                        "Failed to create or bind GL Image");
18807     return;
18808   }
18809 
18810   gfx::Rect cleared_rect;
18811   if (is_cleared)
18812     cleared_rect = gfx::Rect(width, height);
18813 
18814   texture_manager()->SetLevelInfo(
18815       texture_ref, target, 0, image->GetInternalFormat(), width, height, 1, 0,
18816       image->GetDataFormat(), image->GetDataType(), cleared_rect);
18817   texture_manager()->SetLevelImage(texture_ref, target, 0, image.get(),
18818                                    Texture::BOUND);
18819 
18820   if (texture->IsAttachedToFramebuffer())
18821     framebuffer_state_.clear_state_dirty = true;
18822 
18823   texture->SetImmutable(true, false);
18824 }
18825 
DoProduceTextureDirectCHROMIUM(GLuint client_id,const volatile GLbyte * data)18826 void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(
18827     GLuint client_id,
18828     const volatile GLbyte* data) {
18829   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
18830       "context", logger_.GetLogPrefix(),
18831       "mailbox[0]", static_cast<unsigned char>(data[0]));
18832   Mailbox mailbox =
18833       Mailbox::FromVolatile(*reinterpret_cast<const volatile Mailbox*>(data));
18834   DLOG_IF(ERROR, !mailbox.Verify())
18835       << "ProduceTextureDirectCHROMIUM was not passed a crypto-random mailbox.";
18836 
18837   TextureRef* texture_ref = GetTexture(client_id);
18838   if (!texture_ref) {
18839     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glProduceTextureDirectCHROMIUM",
18840                        "unknown texture");
18841     return;
18842   }
18843 
18844   group_->mailbox_manager()->ProduceTexture(mailbox, texture_ref->texture());
18845 }
18846 
DoCreateAndConsumeTextureINTERNAL(GLuint client_id,const volatile GLbyte * data)18847 void GLES2DecoderImpl::DoCreateAndConsumeTextureINTERNAL(
18848     GLuint client_id,
18849     const volatile GLbyte* data) {
18850   TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureINTERNAL",
18851       "context", logger_.GetLogPrefix(),
18852       "mailbox[0]", static_cast<unsigned char>(data[0]));
18853   Mailbox mailbox =
18854       Mailbox::FromVolatile(*reinterpret_cast<const volatile Mailbox*>(data));
18855   DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
18856                                        "passed a mailbox that was not "
18857                                        "generated by GenMailboxCHROMIUM.";
18858   if (!client_id) {
18859     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
18860                        "glCreateAndConsumeTextureCHROMIUM",
18861                        "invalid client id");
18862     return;
18863   }
18864 
18865   TextureRef* texture_ref = GetTexture(client_id);
18866   if (texture_ref) {
18867     // No need to create texture here, the client_id already has an associated
18868     // texture.
18869     LOCAL_SET_GL_ERROR(
18870         GL_INVALID_OPERATION,
18871         "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
18872     return;
18873   }
18874   Texture* texture =
18875       Texture::CheckedCast(group_->mailbox_manager()->ConsumeTexture(mailbox));
18876   if (!texture) {
18877     // Create texture to handle invalid mailbox (see http://crbug.com/472465).
18878     bool result = GenTexturesHelper(1, &client_id);
18879     DCHECK(result);
18880     LOCAL_SET_GL_ERROR(
18881         GL_INVALID_OPERATION,
18882         "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
18883     return;
18884   }
18885 
18886   texture_ref = texture_manager()->Consume(client_id, texture);
18887 }
18888 
DoCreateAndTexStorage2DSharedImageINTERNAL(GLuint client_id,GLenum internal_format,const volatile GLbyte * mailbox_data)18889 void GLES2DecoderImpl::DoCreateAndTexStorage2DSharedImageINTERNAL(
18890     GLuint client_id,
18891     GLenum internal_format,
18892     const volatile GLbyte* mailbox_data) {
18893   TRACE_EVENT2("gpu",
18894                "GLES2DecoderImpl::DoCreateAndTexStorage2DSharedImageCHROMIUM",
18895                "context", logger_.GetLogPrefix(), "mailbox[0]",
18896                static_cast<unsigned char>(mailbox_data[0]));
18897   Mailbox mailbox = Mailbox::FromVolatile(
18898       *reinterpret_cast<const volatile Mailbox*>(mailbox_data));
18899   DLOG_IF(ERROR, !mailbox.Verify())
18900       << "DoCreateAndTexStorage2DSharedImageCHROMIUM was passed an invalid "
18901          "mailbox.";
18902   if (!client_id) {
18903     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
18904                        "DoCreateAndTexStorage2DSharedImageINTERNAL",
18905                        "invalid client id");
18906     return;
18907   }
18908 
18909   TextureRef* texture_ref = GetTexture(client_id);
18910   if (texture_ref) {
18911     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
18912                        "DoCreateAndTexStorage2DSharedImageINTERNAL",
18913                        "client id already in use");
18914     return;
18915   }
18916 
18917   std::unique_ptr<SharedImageRepresentationGLTexture> shared_image;
18918   if (internal_format == GL_RGB) {
18919     shared_image = group_->shared_image_representation_factory()
18920                        ->ProduceRGBEmulationGLTexture(mailbox);
18921   } else if (internal_format == GL_NONE) {
18922     shared_image =
18923         group_->shared_image_representation_factory()->ProduceGLTexture(
18924             mailbox);
18925   } else {
18926     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
18927                        "DoCreateAndTexStorage2DSharedImageINTERNAL",
18928                        "invalid internal format");
18929     return;
18930   }
18931 
18932   if (!shared_image) {
18933     // Mailbox missing, generate a texture.
18934     bool result = GenTexturesHelper(1, &client_id);
18935     DCHECK(result);
18936     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
18937                        "DoCreateAndTexStorage2DSharedImageINTERNAL",
18938                        "invalid mailbox name");
18939     return;
18940   }
18941 
18942   texture_ref =
18943       texture_manager()->ConsumeSharedImage(client_id, std::move(shared_image));
18944 }
18945 
DoBeginSharedImageAccessDirectCHROMIUM(GLuint client_id,GLenum mode)18946 void GLES2DecoderImpl::DoBeginSharedImageAccessDirectCHROMIUM(GLuint client_id,
18947                                                               GLenum mode) {
18948   TextureRef* texture_ref = GetTexture(client_id);
18949   if (!texture_ref) {
18950     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoBeginSharedImageAccessCHROMIUM",
18951                        "invalid texture id");
18952     return;
18953   }
18954 
18955   SharedImageRepresentationGLTexture* shared_image =
18956       texture_ref->shared_image();
18957   if (!shared_image) {
18958     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoBeginSharedImageAccessCHROMIUM",
18959                        "bound texture is not a shared image");
18960     return;
18961   }
18962 
18963   if (texture_ref->shared_image_scoped_access()) {
18964     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoBeginSharedImageAccessCHROMIUM",
18965                        "shared image is being accessed");
18966     return;
18967   }
18968 
18969   if (!texture_ref->BeginAccessSharedImage(mode)) {
18970     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoBeginSharedImageAccessCHROMIUM",
18971                        "Unable to begin access");
18972     return;
18973   }
18974 }
18975 
DoEndSharedImageAccessDirectCHROMIUM(GLuint client_id)18976 void GLES2DecoderImpl::DoEndSharedImageAccessDirectCHROMIUM(GLuint client_id) {
18977   TextureRef* texture_ref = GetTexture(client_id);
18978   if (!texture_ref) {
18979     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoBeginSharedImageAccessCHROMIUM",
18980                        "invalid texture id");
18981     return;
18982   }
18983 
18984   SharedImageRepresentationGLTexture* shared_image =
18985       texture_ref->shared_image();
18986   if (!shared_image) {
18987     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoEndSharedImageAccessCHROMIUM",
18988                        "bound texture is not a shared image");
18989     return;
18990   }
18991 
18992   if (!texture_ref->shared_image_scoped_access()) {
18993     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "DoEndSharedImageAccessCHROMIUM",
18994                        "shared image is not being accessed");
18995     return;
18996   }
18997 
18998   texture_ref->EndAccessSharedImage();
18999 }
19000 
DoBeginBatchReadAccessSharedImageCHROMIUM()19001 void GLES2DecoderImpl::DoBeginBatchReadAccessSharedImageCHROMIUM() {
19002   DCHECK(group_->shared_image_manager());
19003 
19004   if (!group_->shared_image_manager()->BeginBatchReadAccess()) {
19005     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
19006                        "DoBeginBatchReadAccessSharedImageCHROMIUM",
19007                        "shared image begin batch read access failed ");
19008     return;
19009   }
19010 }
19011 
DoEndBatchReadAccessSharedImageCHROMIUM()19012 void GLES2DecoderImpl::DoEndBatchReadAccessSharedImageCHROMIUM() {
19013   DCHECK(group_->shared_image_manager());
19014 
19015   if (!group_->shared_image_manager()->EndBatchReadAccess()) {
19016     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
19017                        "DoEndBatchReadAccessSharedImageCHROMIUM",
19018                        "shared image end batch read access failed ");
19019     return;
19020   }
19021 }
19022 
DoInsertEventMarkerEXT(GLsizei length,const GLchar * marker)19023 void GLES2DecoderImpl::DoInsertEventMarkerEXT(
19024     GLsizei length, const GLchar* marker) {
19025   if (!marker) {
19026     marker = "";
19027   }
19028   debug_marker_manager_.SetMarker(
19029       length ? std::string(marker, length) : std::string(marker));
19030 }
19031 
DoPushGroupMarkerEXT(GLsizei,const GLchar *)19032 void GLES2DecoderImpl::DoPushGroupMarkerEXT(
19033     GLsizei /*length*/, const GLchar* /*marker*/) {
19034 }
19035 
DoPopGroupMarkerEXT(void)19036 void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
19037 }
19038 
BindImage(uint32_t client_texture_id,uint32_t texture_target,gl::GLImage * image,bool can_bind_to_sampler)19039 void GLES2DecoderImpl::BindImage(uint32_t client_texture_id,
19040                                  uint32_t texture_target,
19041                                  gl::GLImage* image,
19042                                  bool can_bind_to_sampler) {
19043   TextureRef* ref = texture_manager()->GetTexture(client_texture_id);
19044   if (!ref) {
19045     return;
19046   }
19047 
19048   GLenum bind_target = GLES2Util::GLFaceTargetToTextureTarget(texture_target);
19049   if (ref->texture()->target() != bind_target) {
19050     return;
19051   }
19052 
19053   texture_manager()->SetLevelImage(ref, texture_target, 0, image,
19054                                    can_bind_to_sampler
19055                                        ? gpu::gles2::Texture::BOUND
19056                                        : gpu::gles2::Texture::UNBOUND);
19057 }
19058 
DoBindTexImage2DCHROMIUM(GLenum target,GLint image_id)19059 void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
19060     GLenum target, GLint image_id) {
19061   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
19062 
19063   BindTexImage2DCHROMIUMImpl("glBindTexImage2DCHROMIUM", target, 0, image_id);
19064 }
19065 
DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target,GLenum internalformat,GLint image_id)19066 void GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM(
19067     GLenum target,
19068     GLenum internalformat,
19069     GLint image_id) {
19070   TRACE_EVENT0("gpu",
19071                "GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM");
19072 
19073   BindTexImage2DCHROMIUMImpl("glBindTexImage2DWithInternalformatCHROMIUM",
19074                              target, internalformat, image_id);
19075 }
19076 
BindTexImage2DCHROMIUMImpl(const char * function_name,GLenum target,GLenum internalformat,GLint image_id)19077 void GLES2DecoderImpl::BindTexImage2DCHROMIUMImpl(const char* function_name,
19078                                                   GLenum target,
19079                                                   GLenum internalformat,
19080                                                   GLint image_id) {
19081   if (target == GL_TEXTURE_CUBE_MAP) {
19082     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, function_name, "invalid target");
19083     return;
19084   }
19085 
19086   // Default target might be conceptually valid, but disallow it to avoid
19087   // accidents.
19088   TextureRef* texture_ref =
19089       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
19090   if (!texture_ref) {
19091     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "no texture bound");
19092     return;
19093   }
19094 
19095   gl::GLImage* image = image_manager()->LookupImage(image_id);
19096   if (!image) {
19097     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
19098                        "no image found with the given ID");
19099     return;
19100   }
19101 
19102   Texture::ImageState image_state = Texture::UNBOUND;
19103 
19104   if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
19105     ScopedGLErrorSuppressor suppressor(
19106         "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", error_state_.get());
19107 
19108     // Note: We fallback to using CopyTexImage() before the texture is used
19109     // when BindTexImage() fails.
19110     if (internalformat) {
19111       if (image->BindTexImageWithInternalformat(target, internalformat))
19112         image_state = Texture::BOUND;
19113     } else {
19114       if (image->BindTexImage(target))
19115         image_state = Texture::BOUND;
19116     }
19117   }
19118 
19119   gfx::Size size = image->GetSize();
19120   GLenum texture_internalformat =
19121       internalformat ? internalformat : image->GetInternalFormat();
19122   texture_manager()->SetLevelInfo(texture_ref, target, 0,
19123                                   texture_internalformat, size.width(),
19124                                   size.height(), 1, 0, image->GetDataFormat(),
19125                                   image->GetDataType(), gfx::Rect(size));
19126   texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state);
19127 }
19128 
DoReleaseTexImage2DCHROMIUM(GLenum target,GLint image_id)19129 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
19130     GLenum target, GLint image_id) {
19131   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
19132 
19133   // Default target might be conceptually valid, but disallow it to avoid
19134   // accidents.
19135   TextureRef* texture_ref =
19136       texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
19137   if (!texture_ref) {
19138     LOCAL_SET_GL_ERROR(
19139         GL_INVALID_OPERATION,
19140         "glReleaseTexImage2DCHROMIUM", "no texture bound");
19141     return;
19142   }
19143 
19144   gl::GLImage* image = image_manager()->LookupImage(image_id);
19145   if (!image) {
19146     LOCAL_SET_GL_ERROR(
19147         GL_INVALID_OPERATION,
19148         "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
19149     return;
19150   }
19151 
19152   Texture::ImageState image_state;
19153 
19154   // Do nothing when image is not currently bound.
19155   if (texture_ref->texture()->GetLevelImage(target, 0, &image_state) != image)
19156     return;
19157 
19158   if (image_state == Texture::BOUND) {
19159     ScopedGLErrorSuppressor suppressor(
19160         "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", error_state_.get());
19161 
19162     image->ReleaseTexImage(target);
19163     texture_manager()->SetLevelInfo(texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
19164                                     GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
19165   }
19166 
19167   texture_manager()->SetLevelImage(texture_ref, target, 0, nullptr,
19168                                    Texture::UNBOUND);
19169 }
19170 
HandleTraceBeginCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)19171 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
19172     uint32_t immediate_data_size,
19173     const volatile void* cmd_data) {
19174   const volatile gles2::cmds::TraceBeginCHROMIUM& c =
19175       *static_cast<const volatile gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
19176   Bucket* category_bucket = GetBucket(c.category_bucket_id);
19177   Bucket* name_bucket = GetBucket(c.name_bucket_id);
19178   static constexpr size_t kMaxStrLen = 256;
19179   if (!category_bucket || category_bucket->size() == 0 ||
19180       category_bucket->size() > kMaxStrLen || !name_bucket ||
19181       name_bucket->size() == 0 || name_bucket->size() > kMaxStrLen) {
19182     return error::kInvalidArguments;
19183   }
19184 
19185   std::string category_name;
19186   std::string trace_name;
19187   if (!category_bucket->GetAsString(&category_name) ||
19188       !name_bucket->GetAsString(&trace_name)) {
19189     return error::kInvalidArguments;
19190   }
19191 
19192   debug_marker_manager_.PushGroup(trace_name);
19193   if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
19194     LOCAL_SET_GL_ERROR(
19195         GL_INVALID_OPERATION,
19196         "glTraceBeginCHROMIUM", "unable to create begin trace");
19197     return error::kNoError;
19198   }
19199   return error::kNoError;
19200 }
19201 
DoTraceEndCHROMIUM()19202 void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
19203   debug_marker_manager_.PopGroup();
19204   if (!gpu_tracer_->End(kTraceCHROMIUM)) {
19205     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
19206                        "glTraceEndCHROMIUM", "no trace begin found");
19207     return;
19208   }
19209 }
19210 
DoDrawBuffersEXT(GLsizei count,const volatile GLenum * bufs)19211 void GLES2DecoderImpl::DoDrawBuffersEXT(GLsizei count,
19212                                         const volatile GLenum* bufs) {
19213   DCHECK_LE(group_->max_draw_buffers(), 16u);
19214   if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
19215     LOCAL_SET_GL_ERROR(
19216         GL_INVALID_VALUE,
19217         "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
19218     return;
19219   }
19220 
19221   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
19222   if (framebuffer) {
19223     GLenum safe_bufs[16];
19224     for (GLsizei i = 0; i < count; ++i) {
19225       GLenum buf = bufs[i];
19226       if (buf != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
19227           buf != GL_NONE) {
19228         LOCAL_SET_GL_ERROR(
19229             GL_INVALID_OPERATION,
19230             "glDrawBuffersEXT",
19231             "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
19232         return;
19233       }
19234       safe_bufs[i] = buf;
19235     }
19236     api()->glDrawBuffersARBFn(count, safe_bufs);
19237     framebuffer->SetDrawBuffers(count, safe_bufs);
19238   } else {  // backbuffer
19239     if (count != 1) {
19240       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glDrawBuffersEXT",
19241                          "invalid number of buffers");
19242       return;
19243     }
19244     GLenum buf = bufs[0];
19245     if (buf != GL_BACK && buf != GL_NONE) {
19246       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glDrawBuffersEXT",
19247                          "buffer is not GL_NONE or GL_BACK");
19248       return;
19249     }
19250     back_buffer_draw_buffer_ = buf;
19251     if (buf == GL_BACK && GetBackbufferServiceId() != 0)  // emulated backbuffer
19252       buf = GL_COLOR_ATTACHMENT0;
19253     api()->glDrawBuffersARBFn(count, &buf);
19254   }
19255 }
19256 
DoLoseContextCHROMIUM(GLenum current,GLenum other)19257 void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
19258   MarkContextLost(GetContextLostReasonFromResetStatus(current));
19259   group_->LoseContexts(GetContextLostReasonFromResetStatus(other));
19260   reset_by_robustness_extension_ = true;
19261 }
19262 
DoFlushDriverCachesCHROMIUM(void)19263 void GLES2DecoderImpl::DoFlushDriverCachesCHROMIUM(void) {
19264   // On Adreno Android devices we need to use a workaround to force caches to
19265   // clear.
19266   if (workarounds().unbind_egl_context_to_flush_driver_caches) {
19267     context_->ReleaseCurrent(nullptr);
19268     context_->MakeCurrent(surface_.get());
19269   }
19270 }
19271 
HandleUniformBlockBinding(uint32_t immediate_data_size,const volatile void * cmd_data)19272 error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
19273     uint32_t immediate_data_size,
19274     const volatile void* cmd_data) {
19275   const char* func_name = "glUniformBlockBinding";
19276   if (!feature_info_->IsWebGL2OrES3Context())
19277     return error::kUnknownCommand;
19278   const volatile gles2::cmds::UniformBlockBinding& c =
19279       *static_cast<const volatile gles2::cmds::UniformBlockBinding*>(cmd_data);
19280   GLuint client_id = c.program;
19281   GLuint index = static_cast<GLuint>(c.index);
19282   GLuint binding = static_cast<GLuint>(c.binding);
19283   Program* program = GetProgramInfoNotShader(client_id, func_name);
19284   if (!program) {
19285     return error::kNoError;
19286   }
19287   if (index >= program->uniform_block_size_info().size()) {
19288     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
19289         "uniformBlockIndex is not an active uniform block index");
19290     return error::kNoError;
19291   }
19292   if (binding >= group_->max_uniform_buffer_bindings()) {
19293     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
19294         "uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS");
19295     return error::kNoError;
19296   }
19297   GLuint service_id = program->service_id();
19298   api()->glUniformBlockBindingFn(service_id, index, binding);
19299   program->SetUniformBlockBinding(index, binding);
19300   return error::kNoError;
19301 }
19302 
HandleClientWaitSync(uint32_t immediate_data_size,const volatile void * cmd_data)19303 error::Error GLES2DecoderImpl::HandleClientWaitSync(
19304     uint32_t immediate_data_size,
19305     const volatile void* cmd_data) {
19306   const char* function_name = "glClientWaitSync";
19307   if (!feature_info_->IsWebGL2OrES3Context())
19308     return error::kUnknownCommand;
19309   const volatile gles2::cmds::ClientWaitSync& c =
19310       *static_cast<const volatile gles2::cmds::ClientWaitSync*>(cmd_data);
19311   const GLuint sync = static_cast<GLuint>(c.sync);
19312   GLbitfield flags = static_cast<GLbitfield>(c.flags);
19313   const GLuint64 timeout = c.timeout();
19314   typedef cmds::ClientWaitSync::Result Result;
19315   Result* result_dst = GetSharedMemoryAs<Result*>(
19316       c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
19317   if (!result_dst) {
19318     return error::kOutOfBounds;
19319   }
19320   if (*result_dst != GL_WAIT_FAILED) {
19321     return error::kInvalidArguments;
19322   }
19323   GLsync service_sync = 0;
19324   if (!group_->GetSyncServiceId(sync, &service_sync)) {
19325     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid sync");
19326     return error::kNoError;
19327   }
19328   if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) {
19329     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid flags");
19330     return error::kNoError;
19331   }
19332   // Force GL_SYNC_FLUSH_COMMANDS_BIT to avoid infinite wait.
19333   flags |= GL_SYNC_FLUSH_COMMANDS_BIT;
19334 
19335   GLenum status = api()->glClientWaitSyncFn(service_sync, flags, timeout);
19336   switch (status) {
19337     case GL_ALREADY_SIGNALED:
19338     case GL_TIMEOUT_EXPIRED:
19339     case GL_CONDITION_SATISFIED:
19340       break;
19341     case GL_WAIT_FAILED:
19342       // Avoid leaking GL errors when using virtual contexts.
19343       LOCAL_PEEK_GL_ERROR(function_name);
19344       *result_dst = status;
19345       // If validation is complete, this only happens if the context is lost.
19346       return error::kLostContext;
19347     default:
19348       NOTREACHED();
19349       break;
19350   }
19351   *result_dst = status;
19352   return error::kNoError;
19353 }
19354 
HandleWaitSync(uint32_t immediate_data_size,const volatile void * cmd_data)19355 error::Error GLES2DecoderImpl::HandleWaitSync(uint32_t immediate_data_size,
19356                                               const volatile void* cmd_data) {
19357   const char* function_name = "glWaitSync";
19358   if (!feature_info_->IsWebGL2OrES3Context())
19359     return error::kUnknownCommand;
19360   const volatile gles2::cmds::WaitSync& c =
19361       *static_cast<const volatile gles2::cmds::WaitSync*>(cmd_data);
19362   const GLuint sync = static_cast<GLuint>(c.sync);
19363   const GLbitfield flags = static_cast<GLbitfield>(c.flags);
19364   const GLuint64 timeout = c.timeout();
19365   GLsync service_sync = 0;
19366   if (!group_->GetSyncServiceId(sync, &service_sync)) {
19367     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid sync");
19368     return error::kNoError;
19369   }
19370   if (flags != 0) {
19371     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid flags");
19372     return error::kNoError;
19373   }
19374   if (timeout != GL_TIMEOUT_IGNORED) {
19375     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid timeout");
19376     return error::kNoError;
19377   }
19378   api()->glWaitSyncFn(service_sync, flags, timeout);
19379   return error::kNoError;
19380 }
19381 
DoFenceSync(GLenum condition,GLbitfield flags)19382 GLsync GLES2DecoderImpl::DoFenceSync(GLenum condition, GLbitfield flags) {
19383   const char* function_name = "glFenceSync";
19384   if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) {
19385     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, function_name, "invalid condition");
19386     return 0;
19387   }
19388   if (flags != 0) {
19389     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid flags");
19390     return 0;
19391   }
19392   return api()->glFenceSyncFn(condition, flags);
19393 }
19394 
InternalFormatSampleCountsHelper(GLenum target,GLenum internalformat,std::vector<GLint> * out_sample_counts)19395 GLsizei GLES2DecoderImpl::InternalFormatSampleCountsHelper(
19396     GLenum target,
19397     GLenum internalformat,
19398     std::vector<GLint>* out_sample_counts) {
19399   DCHECK(out_sample_counts == nullptr || out_sample_counts->size() == 0);
19400 
19401   GLint num_sample_counts = 0;
19402   if (gl_version_info().IsLowerThanGL(4, 2)) {
19403     // No multisampling for integer formats.
19404     if (GLES2Util::IsIntegerFormat(internalformat)) {
19405       return 0;
19406     }
19407 
19408     GLint max_samples = renderbuffer_manager()->max_samples();
19409     num_sample_counts = max_samples;
19410 
19411     if (out_sample_counts != nullptr) {
19412       out_sample_counts->reserve(num_sample_counts);
19413       for (GLint sample_count = max_samples; sample_count > 0; --sample_count) {
19414         out_sample_counts->push_back(sample_count);
19415       }
19416     }
19417   } else {
19418     api()->glGetInternalformativFn(target, internalformat, GL_NUM_SAMPLE_COUNTS,
19419                                    1, &num_sample_counts);
19420 
19421     bool remove_nonconformant_sample_counts =
19422         feature_info_->IsWebGLContext() &&
19423         feature_info_->feature_flags().nv_internalformat_sample_query;
19424 
19425     if (out_sample_counts != nullptr || remove_nonconformant_sample_counts) {
19426       std::vector<GLint> sample_counts(num_sample_counts);
19427       api()->glGetInternalformativFn(target, internalformat, GL_SAMPLES,
19428                                      num_sample_counts, sample_counts.data());
19429 
19430       if (remove_nonconformant_sample_counts) {
19431         ScopedGLErrorSuppressor suppressor(
19432             "GLES2DecoderImpl::InternalFormatSampleCountsHelper",
19433             error_state_.get());
19434 
19435         auto is_nonconformant = [this, target,
19436                                  internalformat](GLint sample_count) {
19437           GLint conformant = GL_FALSE;
19438           api()->glGetInternalformatSampleivNVFn(target, internalformat,
19439                                                  sample_count, GL_CONFORMANT_NV,
19440                                                  1, &conformant);
19441 
19442           // getInternalformatSampleivNV does not work for all formats on NVIDIA
19443           // Shield TV drivers. Assume that formats with large sample counts are
19444           // non-conformant in case the query generates an error.
19445           if (api()->glGetErrorFn() != GL_NO_ERROR) {
19446             return sample_count > 8;
19447           }
19448           return conformant == GL_FALSE;
19449         };
19450 
19451         sample_counts.erase(
19452             std::remove_if(sample_counts.begin(), sample_counts.end(),
19453                            is_nonconformant),
19454             sample_counts.end());
19455         num_sample_counts = sample_counts.size();
19456       }
19457 
19458       if (out_sample_counts != nullptr) {
19459         *out_sample_counts = std::move(sample_counts);
19460       }
19461     }
19462   }
19463 
19464   DCHECK(out_sample_counts == nullptr ||
19465          out_sample_counts->size() == static_cast<size_t>(num_sample_counts));
19466   return num_sample_counts;
19467 }
19468 
HandleGetInternalformativ(uint32_t immediate_data_size,const volatile void * cmd_data)19469 error::Error GLES2DecoderImpl::HandleGetInternalformativ(
19470     uint32_t immediate_data_size,
19471     const volatile void* cmd_data) {
19472   if (!feature_info_->IsWebGL2OrES3Context())
19473     return error::kUnknownCommand;
19474   const volatile gles2::cmds::GetInternalformativ& c =
19475       *static_cast<const volatile gles2::cmds::GetInternalformativ*>(cmd_data);
19476   GLenum target = static_cast<GLenum>(c.target);
19477   GLenum format = static_cast<GLenum>(c.format);
19478   GLenum pname = static_cast<GLenum>(c.pname);
19479   if (!validators_->render_buffer_target.IsValid(target)) {
19480     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", target, "target");
19481     return error::kNoError;
19482   }
19483   if (!validators_->render_buffer_format.IsValid(format)) {
19484     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", format,
19485                                     "internalformat");
19486     return error::kNoError;
19487   }
19488   if (!validators_->internal_format_parameter.IsValid(pname)) {
19489     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", pname, "pname");
19490     return error::kNoError;
19491   }
19492 
19493   typedef cmds::GetInternalformativ::Result Result;
19494 
19495   GLsizei num_sample_counts = 0;
19496   std::vector<GLint> sample_counts;
19497 
19498   GLsizei num_values = 0;
19499   GLint* values = nullptr;
19500   switch (pname) {
19501     case GL_NUM_SAMPLE_COUNTS:
19502       num_sample_counts =
19503           InternalFormatSampleCountsHelper(target, format, nullptr);
19504       num_values = 1;
19505       values = &num_sample_counts;
19506       break;
19507     case GL_SAMPLES:
19508       num_sample_counts =
19509           InternalFormatSampleCountsHelper(target, format, &sample_counts);
19510       num_values = num_sample_counts;
19511       values = sample_counts.data();
19512       break;
19513     default:
19514       NOTREACHED();
19515       break;
19516   }
19517 
19518   uint32_t checked_size = 0;
19519   if (!Result::ComputeSize(num_values).AssignIfValid(&checked_size)) {
19520     return error::kOutOfBounds;
19521   }
19522   Result* result = GetSharedMemoryAs<Result*>(
19523       c.params_shm_id, c.params_shm_offset, checked_size);
19524 
19525   GLint* params = result ? result->GetData() : nullptr;
19526   if (params == nullptr) {
19527     return error::kOutOfBounds;
19528   }
19529   // Check that the client initialized the result.
19530   if (result->size != 0) {
19531     return error::kInvalidArguments;
19532   }
19533 
19534   std::copy(values, &values[num_values], params);
19535   result->SetNumResults(num_values);
19536   return error::kNoError;
19537 }
19538 
HandleMapBufferRange(uint32_t immediate_data_size,const volatile void * cmd_data)19539 error::Error GLES2DecoderImpl::HandleMapBufferRange(
19540     uint32_t immediate_data_size, const volatile void* cmd_data) {
19541   if (!feature_info_->IsWebGL2OrES3Context()) {
19542     return error::kUnknownCommand;
19543   }
19544 
19545   const char* func_name = "glMapBufferRange";
19546   const volatile gles2::cmds::MapBufferRange& c =
19547       *static_cast<const volatile gles2::cmds::MapBufferRange*>(cmd_data);
19548   GLenum target = static_cast<GLenum>(c.target);
19549   GLbitfield access = static_cast<GLbitfield>(c.access);
19550   GLintptr offset = static_cast<GLintptr>(c.offset);
19551   GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
19552   uint32_t data_shm_id = static_cast<uint32_t>(c.data_shm_id);
19553   uint32_t data_shm_offset = static_cast<uint32_t>(c.data_shm_offset);
19554 
19555   typedef cmds::MapBufferRange::Result Result;
19556   Result* result = GetSharedMemoryAs<Result*>(
19557       c.result_shm_id, c.result_shm_offset, sizeof(*result));
19558   if (!result) {
19559     return error::kOutOfBounds;
19560   }
19561   if (*result != 0) {
19562     *result = 0;
19563     return error::kInvalidArguments;
19564   }
19565   if (!validators_->buffer_target.IsValid(target)) {
19566     LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
19567     return error::kNoError;
19568   }
19569   if (size == 0) {
19570     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "length is zero");
19571     return error::kNoError;
19572   }
19573   Buffer* buffer = buffer_manager()->RequestBufferAccess(
19574       &state_, error_state_.get(), target, offset, size, func_name);
19575   if (!buffer) {
19576     // An error is already set.
19577     return error::kNoError;
19578   }
19579   if (state_.bound_transform_feedback->active() &&
19580       !state_.bound_transform_feedback->paused()) {
19581     size_t used_binding_count =
19582         state_.current_program->effective_transform_feedback_varyings().size();
19583     if (state_.bound_transform_feedback->UsesBuffer(
19584             used_binding_count, buffer)) {
19585       LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
19586                          "active transform feedback is using this buffer");
19587       return error::kNoError;
19588     }
19589   }
19590 
19591   int8_t* mem =
19592       GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
19593   if (!mem) {
19594     return error::kOutOfBounds;
19595   }
19596   if (AnyOtherBitsSet(access, (GL_MAP_READ_BIT |
19597                                GL_MAP_WRITE_BIT |
19598                                GL_MAP_INVALIDATE_RANGE_BIT |
19599                                GL_MAP_INVALIDATE_BUFFER_BIT |
19600                                GL_MAP_FLUSH_EXPLICIT_BIT |
19601                                GL_MAP_UNSYNCHRONIZED_BIT))) {
19602     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "invalid access bits");
19603     return error::kNoError;
19604   }
19605   if (!AnyBitsSet(access, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
19606     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
19607         "neither MAP_READ_BIT nor MAP_WRITE_BIT is set");
19608     return error::kNoError;
19609   }
19610   if (AllBitsSet(access, GL_MAP_READ_BIT) &&
19611       AnyBitsSet(access, (GL_MAP_INVALIDATE_RANGE_BIT |
19612                           GL_MAP_INVALIDATE_BUFFER_BIT |
19613                           GL_MAP_UNSYNCHRONIZED_BIT))) {
19614     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
19615         "incompatible access bits with MAP_READ_BIT");
19616     return error::kNoError;
19617   }
19618   if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) &&
19619       !AllBitsSet(access, GL_MAP_WRITE_BIT)) {
19620     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
19621         "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT");
19622     return error::kNoError;
19623   }
19624   GLbitfield filtered_access = access;
19625   if (AllBitsSet(filtered_access, GL_MAP_INVALIDATE_BUFFER_BIT)) {
19626     // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
19627     // GL_MAP_INVALIDATE_RANGE_BIT.
19628     filtered_access = (filtered_access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
19629     filtered_access = (filtered_access | GL_MAP_INVALIDATE_RANGE_BIT);
19630   }
19631   // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined
19632   // behaviors.
19633   filtered_access = (filtered_access & ~GL_MAP_UNSYNCHRONIZED_BIT);
19634   if (AllBitsSet(filtered_access, GL_MAP_WRITE_BIT) &&
19635       !AllBitsSet(filtered_access, GL_MAP_INVALIDATE_RANGE_BIT)) {
19636     filtered_access = (filtered_access | GL_MAP_READ_BIT);
19637   }
19638   void* ptr = api()->glMapBufferRangeFn(target, offset, size, filtered_access);
19639   if (ptr == nullptr) {
19640     // This should mean GL_OUT_OF_MEMORY (or context loss).
19641     LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
19642     return error::kNoError;
19643   }
19644   // The un-filtered bits in |access| are deliberately used here.
19645   buffer->SetMappedRange(offset, size, access, ptr,
19646                          GetSharedMemoryBuffer(data_shm_id),
19647                          static_cast<unsigned int>(data_shm_offset));
19648   if ((filtered_access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
19649     memcpy(mem, ptr, size);
19650   }
19651   *result = 1;
19652   return error::kNoError;
19653 }
19654 
UnmapBufferHelper(Buffer * buffer,GLenum target)19655 bool GLES2DecoderImpl::UnmapBufferHelper(Buffer* buffer, GLenum target) {
19656   DCHECK(buffer);
19657   const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
19658   if (!mapped_range)
19659     return true;
19660   if (!AllBitsSet(mapped_range->access, GL_MAP_WRITE_BIT) ||
19661       AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) {
19662     // If we don't need to write back, or explict flush is required, no copying
19663     // back is needed.
19664   } else if (!WasContextLost()) {
19665     void* mem = mapped_range->GetShmPointer();
19666     DCHECK(mem);
19667     DCHECK(mapped_range->pointer);
19668     memcpy(mapped_range->pointer, mem, mapped_range->size);
19669     if (buffer->shadowed()) {
19670       buffer->SetRange(mapped_range->offset, mapped_range->size, mem);
19671     }
19672   }
19673   buffer->RemoveMappedRange();
19674   if (WasContextLost())
19675     return true;
19676   GLboolean rt = api()->glUnmapBufferFn(target);
19677   if (rt == GL_FALSE) {
19678     // At this point, we have already done the necessary validation, so
19679     // GL_FALSE indicates data corruption.
19680     // TODO(zmo): We could redo the map / copy data / unmap to recover, but
19681     // the second unmap could still return GL_FALSE. For now, we simply lose
19682     // the contexts in the share group.
19683     LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
19684     // Need to lose current context before broadcasting!
19685     MarkContextLost(error::kGuilty);
19686     group_->LoseContexts(error::kInnocent);
19687     return false;
19688   }
19689   return true;
19690 }
19691 
HandleUnmapBuffer(uint32_t immediate_data_size,const volatile void * cmd_data)19692 error::Error GLES2DecoderImpl::HandleUnmapBuffer(
19693     uint32_t immediate_data_size, const volatile void* cmd_data) {
19694   if (!feature_info_->IsWebGL2OrES3Context()) {
19695     return error::kUnknownCommand;
19696   }
19697   const char* func_name = "glUnmapBuffer";
19698 
19699   const volatile gles2::cmds::UnmapBuffer& c =
19700       *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data);
19701   GLenum target = static_cast<GLenum>(c.target);
19702 
19703   if (!validators_->buffer_target.IsValid(target)) {
19704     LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
19705     return error::kNoError;
19706   }
19707 
19708   Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
19709   if (!buffer) {
19710     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
19711     return error::kNoError;
19712   }
19713   const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
19714   if (!mapped_range) {
19715     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
19716     return error::kNoError;
19717   }
19718   if (!UnmapBufferHelper(buffer, target))
19719     return error::kLostContext;
19720   return error::kNoError;
19721 }
19722 
DoFlushMappedBufferRange(GLenum target,GLintptr offset,GLsizeiptr size)19723 void GLES2DecoderImpl::DoFlushMappedBufferRange(
19724     GLenum target, GLintptr offset, GLsizeiptr size) {
19725   const char* func_name = "glFlushMappedBufferRange";
19726   // |size| is validated in HandleFlushMappedBufferRange().
19727   if (offset < 0) {
19728     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "offset < 0");
19729     return;
19730   }
19731   Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
19732   if (!buffer) {
19733     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
19734     return;
19735   }
19736   const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
19737   if (!mapped_range) {
19738     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
19739     return;
19740   }
19741   if (!AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) {
19742     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
19743         "buffer is mapped without MAP_FLUSH_EXPLICIT_BIT flag");
19744     return;
19745   }
19746   base::CheckedNumeric<int32_t> range_size = size;
19747   range_size += offset;
19748   if (!range_size.IsValid() ||
19749       range_size.ValueOrDefault(0) > mapped_range->size) {
19750     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
19751         "offset + size out of bounds");
19752     return;
19753   }
19754   char* client_data = reinterpret_cast<char*>(mapped_range->GetShmPointer());
19755   DCHECK(client_data);
19756   char* gpu_data = reinterpret_cast<char*>(mapped_range->pointer);
19757   DCHECK(gpu_data);
19758   memcpy(gpu_data + offset, client_data + offset, size);
19759   if (buffer->shadowed()) {
19760     buffer->SetRange(mapped_range->offset + offset, size, client_data + offset);
19761   }
19762   api()->glFlushMappedBufferRangeFn(target, offset, size);
19763 }
19764 
DoScheduleDCLayerCHROMIUM(GLuint texture_0,GLuint texture_1,GLint z_order,GLint content_x,GLint content_y,GLint content_width,GLint content_height,GLint quad_x,GLint quad_y,GLint quad_width,GLint quad_height,GLfloat transform_c1r1,GLfloat transform_c2r1,GLfloat transform_c1r2,GLfloat transform_c2r2,GLfloat transform_tx,GLfloat transform_ty,GLboolean is_clipped,GLint clip_x,GLint clip_y,GLint clip_width,GLint clip_height,GLuint protected_video_type)19765 void GLES2DecoderImpl::DoScheduleDCLayerCHROMIUM(GLuint texture_0,
19766                                                  GLuint texture_1,
19767                                                  GLint z_order,
19768                                                  GLint content_x,
19769                                                  GLint content_y,
19770                                                  GLint content_width,
19771                                                  GLint content_height,
19772                                                  GLint quad_x,
19773                                                  GLint quad_y,
19774                                                  GLint quad_width,
19775                                                  GLint quad_height,
19776                                                  GLfloat transform_c1r1,
19777                                                  GLfloat transform_c2r1,
19778                                                  GLfloat transform_c1r2,
19779                                                  GLfloat transform_c2r2,
19780                                                  GLfloat transform_tx,
19781                                                  GLfloat transform_ty,
19782                                                  GLboolean is_clipped,
19783                                                  GLint clip_x,
19784                                                  GLint clip_y,
19785                                                  GLint clip_width,
19786                                                  GLint clip_height,
19787                                                  GLuint protected_video_type) {
19788   if (protected_video_type >
19789       static_cast<GLuint>(gfx::ProtectedVideoType::kMaxValue)) {
19790     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM",
19791                        "invalid protected video type");
19792     return;
19793   }
19794 
19795   if (!texture_0) {
19796     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM",
19797                        "invalid texture");
19798     return;
19799   }
19800 
19801   ui::DCRendererLayerParams params;
19802   GLuint texture_ids[] = {texture_0, texture_1};
19803   size_t i = 0;
19804   for (GLuint texture_id : texture_ids) {
19805     if (!texture_id)
19806       break;
19807     TextureRef* ref = texture_manager()->GetTexture(texture_id);
19808     if (!ref) {
19809       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM",
19810                          "unknown texture");
19811       return;
19812     }
19813     gl::GLImage* image =
19814         ref->texture()->GetLevelImage(ref->texture()->target(), 0);
19815     if (!image) {
19816       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM",
19817                          "unsupported texture format");
19818       return;
19819     }
19820     params.images[i++] = scoped_refptr<gl::GLImage>(image);
19821   }
19822   params.z_order = z_order;
19823   params.content_rect =
19824       gfx::Rect(content_x, content_y, content_width, content_height);
19825   params.quad_rect = gfx::Rect(quad_x, quad_y, quad_width, quad_height);
19826   params.transform =
19827       gfx::Transform(transform_c1r1, transform_c2r1, transform_c1r2,
19828                      transform_c2r2, transform_tx, transform_ty);
19829   params.is_clipped = is_clipped;
19830   params.clip_rect = gfx::Rect(clip_x, clip_y, clip_width, clip_height);
19831   params.protected_video_type =
19832       static_cast<gfx::ProtectedVideoType>(protected_video_type);
19833 
19834   if (!surface_->ScheduleDCLayer(params)) {
19835     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleDCLayerCHROMIUM",
19836                        "failed to schedule DCLayer");
19837   }
19838 }
19839 
19840 // Note that GL_LOST_CONTEXT is specific to GLES.
19841 // For desktop GL we have to query the reset status proactively.
OnContextLostError()19842 void GLES2DecoderImpl::OnContextLostError() {
19843   if (!WasContextLost()) {
19844     // Need to lose current context before broadcasting!
19845     CheckResetStatus();
19846     group_->LoseContexts(error::kUnknown);
19847     reset_by_robustness_extension_ = true;
19848   }
19849 }
19850 
OnOutOfMemoryError()19851 void GLES2DecoderImpl::OnOutOfMemoryError() {
19852   if (lose_context_when_out_of_memory_ && !WasContextLost()) {
19853     error::ContextLostReason other = error::kOutOfMemory;
19854     if (CheckResetStatus()) {
19855       other = error::kUnknown;
19856     } else {
19857       // Need to lose current context before broadcasting!
19858       MarkContextLost(error::kOutOfMemory);
19859     }
19860     group_->LoseContexts(other);
19861   }
19862 }
19863 
GetSamplerStateForTextureUnit(GLenum target,GLuint unit)19864 const SamplerState& GLES2DecoderImpl::GetSamplerStateForTextureUnit(
19865     GLenum target, GLuint unit) {
19866   if (features().enable_samplers) {
19867     Sampler* sampler = state_.sampler_units[unit].get();
19868     if (sampler)
19869       return sampler->sampler_state();
19870   }
19871   TextureUnit& texture_unit = state_.texture_units[unit];
19872   TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(target);
19873   if (texture_ref)
19874     return texture_ref->texture()->sampler_state();
19875 
19876   return default_sampler_state_;
19877 }
19878 
NeedsCopyTextureImageWorkaround(GLenum internal_format,int32_t channels_exist,GLuint * source_texture_service_id,GLenum * source_texture_target)19879 bool GLES2DecoderImpl::NeedsCopyTextureImageWorkaround(
19880     GLenum internal_format,
19881     int32_t channels_exist,
19882     GLuint* source_texture_service_id,
19883     GLenum* source_texture_target) {
19884   // On some OSX devices, copyTexImage2D will fail if all of these conditions
19885   // are met:
19886   //   1. The internal format of the new texture is not GL_RGB or GL_RGBA.
19887   //   2. The image of the read FBO is backed by an IOSurface.
19888   // See https://crbug.com/581777#c4 for more details.
19889   if (!workarounds().use_intermediary_for_copy_texture_image)
19890     return false;
19891 
19892   if (internal_format == GL_RGB || internal_format == GL_RGBA)
19893     return false;
19894 
19895   Framebuffer* framebuffer = GetBoundReadFramebuffer();
19896   if (!framebuffer)
19897     return false;
19898 
19899   const Framebuffer::Attachment* attachment =
19900       framebuffer->GetReadBufferAttachment();
19901   if (!attachment)
19902     return false;
19903 
19904   if (!attachment->IsTextureAttachment())
19905     return false;
19906 
19907   TextureRef* texture =
19908       texture_manager()->GetTexture(attachment->object_name());
19909   if (!texture->texture()->HasImages())
19910     return false;
19911 
19912   // The workaround only works if the source texture consists of the channels
19913   // kRGB or kRGBA.
19914   if (channels_exist != GLES2Util::kRGBA && channels_exist != GLES2Util::kRGB)
19915     return false;
19916 
19917   *source_texture_target = texture->texture()->target();
19918   *source_texture_service_id = texture->service_id();
19919   return true;
19920 }
19921 
ChromiumImageNeedsRGBEmulation()19922 bool GLES2DecoderImpl::ChromiumImageNeedsRGBEmulation() {
19923   gpu::ImageFactory* factory = GetContextGroup()->image_factory();
19924   return factory ? !factory->SupportsFormatRGB() : false;
19925 }
19926 
ClearScheduleCALayerState()19927 void GLES2DecoderImpl::ClearScheduleCALayerState() {
19928   ca_layer_shared_state_.reset();
19929 }
19930 
ClearFramebufferForWorkaround(GLbitfield mask)19931 void GLES2DecoderImpl::ClearFramebufferForWorkaround(GLbitfield mask) {
19932   ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
19933                                      error_state_.get());
19934   clear_framebuffer_blit_->ClearFramebuffer(
19935       this, gfx::Size(viewport_max_width_, viewport_max_height_), mask,
19936       state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
19937       state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
19938 }
19939 
RestoreAllExternalTextureBindingsIfNeeded()19940 void GLES2DecoderImpl::RestoreAllExternalTextureBindingsIfNeeded() {
19941   if (texture_manager()->GetServiceIdGeneration() ==
19942       texture_manager_service_id_generation_)
19943     return;
19944 
19945   // Texture manager's version has changed, so rebind all external textures
19946   // in case their service ids have changed.
19947   for (unsigned texture_unit_index = 0;
19948        texture_unit_index < state_.texture_units.size(); texture_unit_index++) {
19949     TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
19950     if (texture_unit.bind_target != GL_TEXTURE_EXTERNAL_OES)
19951       continue;
19952 
19953     if (TextureRef* texture_ref =
19954             texture_unit.bound_texture_external_oes.get()) {
19955       api()->glActiveTextureFn(GL_TEXTURE0 + texture_unit_index);
19956       api()->glBindTextureFn(GL_TEXTURE_EXTERNAL_OES,
19957                              texture_ref->service_id());
19958     }
19959   }
19960 
19961   api()->glActiveTextureFn(GL_TEXTURE0 + state_.active_texture_unit);
19962 
19963   texture_manager_service_id_generation_ =
19964       texture_manager()->GetServiceIdGeneration();
19965 }
19966 
DoContextVisibilityHintCHROMIUM(GLboolean visibility)19967 void GLES2DecoderImpl::DoContextVisibilityHintCHROMIUM(GLboolean visibility) {
19968   if (feature_info_->IsWebGLContext())
19969     context_->SetVisibility(visibility == GL_TRUE);
19970 }
19971 
HandleInitializeDiscardableTextureCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)19972 error::Error GLES2DecoderImpl::HandleInitializeDiscardableTextureCHROMIUM(
19973     uint32_t immediate_data_size,
19974     const volatile void* cmd_data) {
19975   const volatile gles2::cmds::InitializeDiscardableTextureCHROMIUM& c =
19976       *static_cast<
19977           const volatile gles2::cmds::InitializeDiscardableTextureCHROMIUM*>(
19978           cmd_data);
19979   GLuint texture_id = c.texture_id;
19980   uint32_t shm_id = c.shm_id;
19981   uint32_t shm_offset = c.shm_offset;
19982 
19983   TextureRef* texture = texture_manager()->GetTexture(texture_id);
19984   if (!texture) {
19985     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
19986                        "glInitializeDiscardableTextureCHROMIUM",
19987                        "Invalid texture ID");
19988     return error::kNoError;
19989   }
19990   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(shm_id);
19991   if (!DiscardableHandleBase::ValidateParameters(buffer.get(), shm_offset))
19992     return error::kInvalidArguments;
19993 
19994   size_t size = texture->texture()->estimated_size();
19995   ServiceDiscardableHandle handle(std::move(buffer), shm_offset, shm_id);
19996   GetContextGroup()->discardable_manager()->InsertLockedTexture(
19997       texture_id, size, group_->texture_manager(), std::move(handle));
19998   return error::kNoError;
19999 }
20000 
HandleUnlockDiscardableTextureCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)20001 error::Error GLES2DecoderImpl::HandleUnlockDiscardableTextureCHROMIUM(
20002     uint32_t immediate_data_size,
20003     const volatile void* cmd_data) {
20004   const volatile gles2::cmds::UnlockDiscardableTextureCHROMIUM& c =
20005       *static_cast<
20006           const volatile gles2::cmds::UnlockDiscardableTextureCHROMIUM*>(
20007           cmd_data);
20008   GLuint texture_id = c.texture_id;
20009   ServiceDiscardableManager* discardable_manager =
20010       GetContextGroup()->discardable_manager();
20011   TextureRef* texture_to_unbind;
20012   if (!discardable_manager->UnlockTexture(texture_id, group_->texture_manager(),
20013                                           &texture_to_unbind)) {
20014     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glUnlockDiscardableTextureCHROMIUM",
20015                        "Texture ID not initialized");
20016   }
20017   if (texture_to_unbind)
20018     UnbindTexture(texture_to_unbind, SupportsSeparateFramebufferBinds());
20019 
20020   return error::kNoError;
20021 }
20022 
HandleLockDiscardableTextureCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)20023 error::Error GLES2DecoderImpl::HandleLockDiscardableTextureCHROMIUM(
20024     uint32_t immediate_data_size,
20025     const volatile void* cmd_data) {
20026   const volatile gles2::cmds::LockDiscardableTextureCHROMIUM& c =
20027       *static_cast<const volatile gles2::cmds::LockDiscardableTextureCHROMIUM*>(
20028           cmd_data);
20029   GLuint texture_id = c.texture_id;
20030   if (!GetContextGroup()->discardable_manager()->LockTexture(
20031           texture_id, group_->texture_manager())) {
20032     // Temporarily log a crash dump for debugging crbug.com/870317.
20033     base::debug::DumpWithoutCrashing();
20034     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glLockDiscardableTextureCHROMIUM",
20035                        "Texture ID not initialized");
20036   }
20037   return error::kNoError;
20038 }
20039 
20040 
GetShmBuffer(uint32_t shm_id)20041 scoped_refptr<gpu::Buffer> GLES2DecoderImpl::GetShmBuffer(uint32_t shm_id) {
20042   return GetSharedMemoryBuffer(shm_id);
20043 }
20044 
DoWindowRectanglesEXT(GLenum mode,GLsizei n,const volatile GLint * box)20045 void GLES2DecoderImpl::DoWindowRectanglesEXT(GLenum mode,
20046                                              GLsizei n,
20047                                              const volatile GLint* box) {
20048   std::vector<GLint> box_copy(box, box + (n * 4));
20049   if (static_cast<size_t>(n) > state_.GetMaxWindowRectangles()) {
20050     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glWindowRectanglesEXT",
20051                        "count > GL_MAX_WINDOW_RECTANGLES_EXT");
20052     return;
20053   }
20054   for (int i = 0; i < n; ++i) {
20055     int boxindex = i * 4;
20056     if (box_copy[boxindex + 2] < 0 || box_copy[boxindex + 3] < 0) {
20057       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glWindowRectanglesEXT",
20058                          "negative box width or height");
20059       return;
20060     }
20061   }
20062   state_.SetWindowRectangles(mode, n, box_copy.data());
20063   state_.UpdateWindowRectangles();
20064 }
20065 
DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,GLuint dest_id,GLint x,GLint y,GLsizei width,GLsizei height)20066 void GLES2DecoderImpl::DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
20067                                                             GLuint dest_id,
20068                                                             GLint x,
20069                                                             GLint y,
20070                                                             GLsizei width,
20071                                                             GLsizei height) {
20072   TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoUnpremultiplyAndDitherCopyCHROMIUM");
20073   static const char kFunctionName[] = "glUnpremultiplyAndDitherCopyCHROMIUM";
20074 
20075   // Do basic validation of our params. Because we don't rely on the caller to
20076   // provide the targets / formats of src / dst, we read them here before
20077   // forwarding to CopySubTextureHelper. This extension always deals with level
20078   // 0.
20079   const GLint kLevel = 0;
20080 
20081   TextureRef* source_texture_ref = GetTexture(source_id);
20082   TextureRef* dest_texture_ref = GetTexture(dest_id);
20083   if (!source_texture_ref || !dest_texture_ref) {
20084     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "unknown texture id");
20085     return;
20086   }
20087 
20088   Texture* source_texture = source_texture_ref->texture();
20089   GLenum source_target = source_texture->target();
20090   Texture* dest_texture = dest_texture_ref->texture();
20091   GLenum dest_target = dest_texture->target();
20092   if ((source_target != GL_TEXTURE_2D &&
20093        source_target != GL_TEXTURE_RECTANGLE_ARB &&
20094        source_target != GL_TEXTURE_EXTERNAL_OES) ||
20095       (dest_target != GL_TEXTURE_2D &&
20096        dest_target != GL_TEXTURE_RECTANGLE_ARB)) {
20097     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
20098                        "invalid texture target");
20099     return;
20100   }
20101 
20102   GLenum source_type = 0;
20103   GLenum source_internal_format = 0;
20104   source_texture->GetLevelType(source_target, kLevel, &source_type,
20105                                &source_internal_format);
20106 
20107   GLenum dest_type = 0;
20108   GLenum dest_internal_format = 0;
20109   dest_texture->GetLevelType(dest_target, kLevel, &dest_type,
20110                              &dest_internal_format);
20111   GLenum format =
20112       TextureManager::ExtractFormatFromStorageFormat(dest_internal_format);
20113 
20114   if (format != GL_BGRA && format != GL_RGBA) {
20115     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid format");
20116     return;
20117   }
20118 
20119   if (dest_type != GL_UNSIGNED_SHORT_4_4_4_4) {
20120     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
20121                        "invalid destination type");
20122     return;
20123   }
20124 
20125   CopySubTextureHelper(
20126       kFunctionName, source_id, kLevel, dest_target, dest_id, kLevel, x, y, x,
20127       y, width, height, GL_FALSE /* unpack_flip_y */,
20128       GL_FALSE /* unpack_premultiply_alpha */,
20129       GL_TRUE /* unpack_unmultiply_alpha */, GL_TRUE /* dither */);
20130 }
20131 
CreateAbstractTexture(GLenum target,GLenum internal_format,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type)20132 std::unique_ptr<AbstractTexture> GLES2DecoderImpl::CreateAbstractTexture(
20133     GLenum target,
20134     GLenum internal_format,
20135     GLsizei width,
20136     GLsizei height,
20137     GLsizei depth,
20138     GLint border,
20139     GLenum format,
20140     GLenum type) {
20141   GLuint service_id = 0;
20142   api()->glGenTexturesFn(1, &service_id);
20143   scoped_refptr<gpu::gles2::TextureRef> texture_ref =
20144       TextureRef::Create(texture_manager(), 0, service_id);
20145   texture_manager()->SetTarget(texture_ref.get(), target);
20146   const GLint level = 0;
20147   // Mark the texture as "not cleared".
20148   gfx::Rect cleared_rect = gfx::Rect();
20149   texture_manager()->SetLevelInfo(texture_ref.get(), target, level,
20150                                   internal_format, width, height, depth, border,
20151                                   format, type, cleared_rect);
20152 
20153   // Unretained is safe, because of the destruction cb.
20154   std::unique_ptr<ValidatingAbstractTextureImpl> abstract_texture =
20155       std::make_unique<ValidatingAbstractTextureImpl>(
20156           std::move(texture_ref), this,
20157           base::BindOnce(&GLES2DecoderImpl::OnAbstractTextureDestroyed,
20158                          base::Unretained(this)));
20159   abstract_textures_.insert(abstract_texture.get());
20160 
20161   return std::unique_ptr<AbstractTexture>(abstract_texture.release());
20162 }
20163 
OnAbstractTextureDestroyed(ValidatingAbstractTextureImpl * abstract_texture,scoped_refptr<TextureRef> texture_ref)20164 void GLES2DecoderImpl::OnAbstractTextureDestroyed(
20165     ValidatingAbstractTextureImpl* abstract_texture,
20166     scoped_refptr<TextureRef> texture_ref) {
20167   DCHECK(texture_ref);
20168   abstract_textures_.erase(abstract_texture);
20169   // Keep |texture_ref| until we have a current context to destroy it, unless
20170   // the context is current.  In that case, clear everything that's pending
20171   // destruction and let |texture_ref| go out of scope.
20172   // TODO(liberato): Consider moving this to the context group, so that any
20173   // context in our group can delete textures sooner.
20174   if (context_->IsCurrent(nullptr))
20175     texture_refs_pending_destruction_.clear();
20176   else
20177     texture_refs_pending_destruction_.insert(std::move(texture_ref));
20178 }
20179 
DoSetReadbackBufferShadowAllocationINTERNAL(GLuint buffer_id,GLuint shm_id,GLuint shm_offset,GLuint size)20180 void GLES2DecoderImpl::DoSetReadbackBufferShadowAllocationINTERNAL(
20181     GLuint buffer_id,
20182     GLuint shm_id,
20183     GLuint shm_offset,
20184     GLuint size) {
20185   static const char kFunctionName[] = "glSetBufferShadowAllocationINTERNAL";
20186   scoped_refptr<Buffer> buffer = buffer_manager()->GetBuffer(buffer_id);
20187   if (!buffer) {
20188     LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "unknown buffer");
20189     return;
20190   }
20191   if (static_cast<GLsizeiptr>(size) != buffer->size()) {
20192     MarkContextLost(error::kGuilty);
20193     group_->LoseContexts(error::kUnknown);
20194     return;
20195   }
20196 
20197   scoped_refptr<gpu::Buffer> shm = GetSharedMemoryBuffer(shm_id);
20198   buffer->SetReadbackShadowAllocation(shm, shm_offset);
20199   // All buffers in writes_submitted_but_not_completed_ should have shm
20200   // allocations.
20201   writes_submitted_but_not_completed_.insert(buffer);
20202 }
20203 
CompileShaderAndExitCommandProcessingEarly(Shader * shader)20204 void GLES2DecoderImpl::CompileShaderAndExitCommandProcessingEarly(
20205     Shader* shader) {
20206   // No need to call DoCompile or exit command processing early if the call
20207   // to DoCompile will be a no-op.
20208   if (!shader->CanCompile())
20209     return;
20210 
20211   shader->DoCompile();
20212 
20213   // Shader compilation can be very slow (see https://crbug.com/844780), Exit
20214   // command processing to allow for context preemption and GPU watchdog
20215   // checks.
20216   ExitCommandProcessingEarly();
20217 }
20218 
ReportProgress()20219 void GLES2DecoderImpl::ReportProgress() {
20220   if (group_)
20221     group_->ReportProgress();
20222 }
20223 
HandleSetActiveURLCHROMIUM(uint32_t immediate_data_size,const volatile void * cmd_data)20224 error::Error GLES2DecoderImpl::HandleSetActiveURLCHROMIUM(
20225     uint32_t immediate_data_size,
20226     const volatile void* cmd_data) {
20227   const volatile cmds::SetActiveURLCHROMIUM& c =
20228       *static_cast<const volatile cmds::SetActiveURLCHROMIUM*>(cmd_data);
20229   Bucket* url_bucket = GetBucket(c.url_bucket_id);
20230   static constexpr size_t kMaxStrLen = 1024;
20231   if (!url_bucket || url_bucket->size() == 0 ||
20232       url_bucket->size() > kMaxStrLen) {
20233     return error::kInvalidArguments;
20234   }
20235 
20236   size_t size = url_bucket->size();
20237   const char* url_str = url_bucket->GetDataAs<const char*>(0, size);
20238   if (!url_str)
20239     return error::kInvalidArguments;
20240 
20241   GURL url(base::StringPiece(url_str, size));
20242   client()->SetActiveURL(std::move(url));
20243   return error::kNoError;
20244 }
20245 
20246 // Include the auto-generated part of this file. We split this because it means
20247 // we can easily edit the non-auto generated parts right here in this file
20248 // instead of having to edit some template or the code generator.
20249 #include "base/macros.h"
20250 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
20251 
20252 }  // namespace gles2
20253 }  // namespace gpu
20254