1 // Copyright (c) 2016 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_passthrough.h"
6 
7 #include "base/callback_helpers.h"
8 #include "base/metrics/histogram_macros.h"
9 #include "base/numerics/ranges.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "build/build_config.h"
12 #include "gpu/command_buffer/common/discardable_handle.h"
13 #include "gpu/command_buffer/service/decoder_client.h"
14 #include "gpu/command_buffer/service/gpu_fence_manager.h"
15 #include "gpu/command_buffer/service/gpu_tracer.h"
16 #include "gpu/command_buffer/service/image_factory.h"
17 #include "gpu/command_buffer/service/multi_draw_manager.h"
18 #include "gpu/command_buffer/service/passthrough_discardable_manager.h"
19 #include "gpu/command_buffer/service/shared_image_factory.h"
20 #include "gpu/command_buffer/service/shared_image_representation.h"
21 #include "ui/gfx/geometry/rect_conversions.h"
22 #include "ui/gl/ca_renderer_layer_params.h"
23 #include "ui/gl/dc_renderer_layer_params.h"
24 #include "ui/gl/gl_version_info.h"
25 
26 namespace gpu {
27 namespace gles2 {
28 
29 // Temporarily allows compilation of shaders that use the
30 // ARB_texture_rectangle/ANGLE_texture_rectangle extension. We don't want to
31 // expose the extension to WebGL user shaders but we still need to use it for
32 // parts of the implementation on macOS. Note that the extension is always
33 // enabled on macOS and this only controls shader compilation.
34 class GLES2DecoderPassthroughImpl::
35     ScopedEnableTextureRectangleInShaderCompiler {
36  public:
37   ScopedEnableTextureRectangleInShaderCompiler(
38       const ScopedEnableTextureRectangleInShaderCompiler&) = delete;
39   ScopedEnableTextureRectangleInShaderCompiler& operator=(
40       const ScopedEnableTextureRectangleInShaderCompiler&) = delete;
41 
42   // This class is a no-op except on macOS.
43 #if !defined(OS_MAC)
ScopedEnableTextureRectangleInShaderCompiler(GLES2DecoderPassthroughImpl * decoder)44   explicit ScopedEnableTextureRectangleInShaderCompiler(
45       GLES2DecoderPassthroughImpl* decoder) {}
46 
47  private:
48 #else
49   explicit ScopedEnableTextureRectangleInShaderCompiler(
50       GLES2DecoderPassthroughImpl* decoder)
51       : decoder_(decoder) {
52     if (decoder_->feature_info_->IsWebGLContext())
53       decoder_->api_->glEnableFn(GL_TEXTURE_RECTANGLE_ANGLE);
54   }
55   ~ScopedEnableTextureRectangleInShaderCompiler() {
56     if (decoder_->feature_info_->IsWebGLContext())
57       decoder_->api_->glDisableFn(GL_TEXTURE_RECTANGLE_ANGLE);
58   }
59 
60  private:
61   GLES2DecoderPassthroughImpl* decoder_;
62 #endif
63 };
64 
65 namespace {
66 
67 template <typename ClientType, typename ServiceType, typename GenFunction>
GenHelper(GLsizei n,const volatile ClientType * client_ids,ClientServiceMap<ClientType,ServiceType> * id_map,GenFunction gen_function)68 error::Error GenHelper(GLsizei n,
69                        const volatile ClientType* client_ids,
70                        ClientServiceMap<ClientType, ServiceType>* id_map,
71                        GenFunction gen_function) {
72   DCHECK(n >= 0);
73   std::vector<ClientType> client_ids_copy(client_ids, client_ids + n);
74   for (GLsizei ii = 0; ii < n; ++ii) {
75     if (id_map->HasClientID(client_ids_copy[ii])) {
76       return error::kInvalidArguments;
77     }
78   }
79   if (!CheckUniqueAndNonNullIds(n, client_ids_copy.data())) {
80     return error::kInvalidArguments;
81   }
82 
83   std::vector<ServiceType> service_ids(n, 0);
84   gen_function(n, service_ids.data());
85   for (GLsizei ii = 0; ii < n; ++ii) {
86     id_map->SetIDMapping(client_ids_copy[ii], service_ids[ii]);
87   }
88 
89   return error::kNoError;
90 }
91 
92 template <typename ClientType, typename ServiceType, typename GenFunction>
CreateHelper(ClientType client_id,ClientServiceMap<ClientType,ServiceType> * id_map,GenFunction create_function)93 error::Error CreateHelper(ClientType client_id,
94                           ClientServiceMap<ClientType, ServiceType>* id_map,
95                           GenFunction create_function) {
96   if (id_map->HasClientID(client_id)) {
97     return error::kInvalidArguments;
98   }
99   ServiceType service_id = create_function();
100   id_map->SetIDMapping(client_id, service_id);
101   return error::kNoError;
102 }
103 
104 template <typename ClientType, typename ServiceType, typename DeleteFunction>
DeleteHelper(GLsizei n,const volatile ClientType * client_ids,ClientServiceMap<ClientType,ServiceType> * id_map,DeleteFunction delete_function)105 error::Error DeleteHelper(GLsizei n,
106                           const volatile ClientType* client_ids,
107                           ClientServiceMap<ClientType, ServiceType>* id_map,
108                           DeleteFunction delete_function) {
109   DCHECK(n >= 0);
110   std::vector<ServiceType> service_ids(n, 0);
111   for (GLsizei ii = 0; ii < n; ++ii) {
112     ClientType client_id = client_ids[ii];
113 
114     // Don't pass service IDs of objects with a client ID of 0.  They are
115     // emulated and should not be deleteable
116     if (client_id != 0) {
117       service_ids[ii] = id_map->GetServiceIDOrInvalid(client_id);
118       id_map->RemoveClientID(client_id);
119     }
120   }
121 
122   delete_function(n, service_ids.data());
123 
124   return error::kNoError;
125 }
126 
127 template <typename ClientType, typename ServiceType, typename DeleteFunction>
DeleteHelper(ClientType client_id,ClientServiceMap<ClientType,ServiceType> * id_map,DeleteFunction delete_function)128 error::Error DeleteHelper(ClientType client_id,
129                           ClientServiceMap<ClientType, ServiceType>* id_map,
130                           DeleteFunction delete_function) {
131   delete_function(id_map->GetServiceIDOrInvalid(client_id));
132   id_map->RemoveClientID(client_id);
133   return error::kNoError;
134 }
135 
136 template <typename ClientType, typename ServiceType, typename GenFunction>
137 ServiceType GetServiceID(ClientType client_id,
138                          ClientServiceMap<ClientType, ServiceType>* id_map,
139                          bool create_if_missing,
140                          GenFunction gen_function) {
141   ServiceType service_id = id_map->invalid_service_id();
142   if (id_map->GetServiceID(client_id, &service_id)) {
143     return service_id;
144   }
145 
146   if (create_if_missing) {
147     service_id = gen_function();
148     id_map->SetIDMapping(client_id, service_id);
149     return service_id;
150   }
151 
152   return id_map->invalid_service_id();
153 }
154 
GetTextureServiceID(gl::GLApi * api,GLuint client_id,PassthroughResources * resources,bool create_if_missing)155 GLuint GetTextureServiceID(gl::GLApi* api,
156                            GLuint client_id,
157                            PassthroughResources* resources,
158                            bool create_if_missing) {
159   GLuint service_id = resources->texture_id_map.invalid_service_id();
160   if (resources->texture_id_map.GetServiceID(client_id, &service_id)) {
161     return service_id;
162   }
163 
164   if (create_if_missing) {
165     service_id = 0;
166     api->glGenTexturesFn(1, &service_id);
167     resources->texture_id_map.SetIDMapping(client_id, service_id);
168     return service_id;
169   }
170 
171   return resources->texture_id_map.invalid_service_id();
172 }
173 
GetBufferServiceID(gl::GLApi * api,GLuint client_id,PassthroughResources * resources,bool create_if_missing)174 GLuint GetBufferServiceID(gl::GLApi* api,
175                           GLuint client_id,
176                           PassthroughResources* resources,
177                           bool create_if_missing) {
178   return GetServiceID(client_id, &resources->buffer_id_map, create_if_missing,
179                       [api]() {
180                         GLuint service_id = 0;
181                         api->glGenBuffersARBFn(1, &service_id);
182                         return service_id;
183                       });
184 }
185 
GetRenderbufferServiceID(gl::GLApi * api,GLuint client_id,PassthroughResources * resources,bool create_if_missing)186 GLuint GetRenderbufferServiceID(gl::GLApi* api,
187                                 GLuint client_id,
188                                 PassthroughResources* resources,
189                                 bool create_if_missing) {
190   return GetServiceID(client_id, &resources->renderbuffer_id_map,
191                       create_if_missing, [api]() {
192                         GLuint service_id = 0;
193                         api->glGenRenderbuffersEXTFn(1, &service_id);
194                         return service_id;
195                       });
196 }
197 
GetFramebufferServiceID(gl::GLApi * api,GLuint client_id,ClientServiceMap<GLuint,GLuint> * id_map,bool create_if_missing)198 GLuint GetFramebufferServiceID(gl::GLApi* api,
199                                GLuint client_id,
200                                ClientServiceMap<GLuint, GLuint>* id_map,
201                                bool create_if_missing) {
202   return GetServiceID(client_id, id_map, create_if_missing, [api]() {
203     GLuint service_id = 0;
204     api->glGenFramebuffersEXTFn(1, &service_id);
205     return service_id;
206   });
207 }
208 
GetTransformFeedbackServiceID(GLuint client_id,ClientServiceMap<GLuint,GLuint> * id_map)209 GLuint GetTransformFeedbackServiceID(GLuint client_id,
210                                      ClientServiceMap<GLuint, GLuint>* id_map) {
211   return id_map->GetServiceIDOrInvalid(client_id);
212 }
213 
GetVertexArrayServiceID(GLuint client_id,ClientServiceMap<GLuint,GLuint> * id_map)214 GLuint GetVertexArrayServiceID(GLuint client_id,
215                                ClientServiceMap<GLuint, GLuint>* id_map) {
216   return id_map->GetServiceIDOrInvalid(client_id);
217 }
218 
GetProgramServiceID(GLuint client_id,PassthroughResources * resources)219 GLuint GetProgramServiceID(GLuint client_id, PassthroughResources* resources) {
220   return resources->program_id_map.GetServiceIDOrInvalid(client_id);
221 }
222 
GetShaderServiceID(GLuint client_id,PassthroughResources * resources)223 GLuint GetShaderServiceID(GLuint client_id, PassthroughResources* resources) {
224   return resources->shader_id_map.GetServiceIDOrInvalid(client_id);
225 }
226 
GetQueryServiceID(GLuint client_id,ClientServiceMap<GLuint,GLuint> * id_map)227 GLuint GetQueryServiceID(GLuint client_id,
228                          ClientServiceMap<GLuint, GLuint>* id_map) {
229   return id_map->GetServiceIDOrInvalid(client_id);
230 }
231 
GetSamplerServiceID(GLuint client_id,PassthroughResources * resources)232 GLuint GetSamplerServiceID(GLuint client_id, PassthroughResources* resources) {
233   return resources->sampler_id_map.GetServiceIDOrInvalid(client_id);
234 }
235 
GetSyncServiceID(GLuint client_id,PassthroughResources * resources)236 GLsync GetSyncServiceID(GLuint client_id, PassthroughResources* resources) {
237   return reinterpret_cast<GLsync>(
238       resources->sync_id_map.GetServiceIDOrInvalid(client_id));
239 }
240 
241 template <typename T>
InsertValueIntoBuffer(std::vector<uint8_t> * data,const T & value,size_t offset)242 void InsertValueIntoBuffer(std::vector<uint8_t>* data,
243                            const T& value,
244                            size_t offset) {
245   DCHECK_LE(offset + sizeof(T), data->size());
246   memcpy(data->data() + offset, &value, sizeof(T));
247 }
248 
249 template <typename T>
AppendValueToBuffer(std::vector<uint8_t> * data,const T & value)250 void AppendValueToBuffer(std::vector<uint8_t>* data, const T& value) {
251   const base::CheckedNumeric<size_t> old_size = data->size();
252   data->resize((old_size + sizeof(T)).ValueOrDie());
253   memcpy(data->data() + old_size.ValueOrDie(), &value, sizeof(T));
254 }
255 
AppendStringToBuffer(std::vector<uint8_t> * data,const char * str,size_t len)256 void AppendStringToBuffer(std::vector<uint8_t>* data,
257                           const char* str,
258                           size_t len) {
259   const base::CheckedNumeric<size_t> old_size = data->size();
260   data->resize((old_size + len).ValueOrDie());
261   memcpy(data->data() + old_size.ValueOrDie(), str, len);
262 }
263 
AssignGLRectangle(GLint rectangle[4],GLint x,GLint y,GLint width,GLint height)264 void AssignGLRectangle(GLint rectangle[4],
265                        GLint x,
266                        GLint y,
267                        GLint width,
268                        GLint height) {
269   rectangle[0] = x;
270   rectangle[1] = y;
271   rectangle[2] = width;
272   rectangle[3] = height;
273 }
274 
275 // In order to minimize the amount of data copied, the command buffer client
276 // unpack pixels before sending the glTex[Sub]Image[2|3]D calls. The only
277 // parameter it doesn't handle is the alignment. Resetting the unpack state is
278 // not needed when uploading from a PBO and for compressed formats which the
279 // client sends untouched. This class handles resetting and restoring the unpack
280 // state.
281 // TODO(cwallez@chromium.org) it would be nicer to handle the resetting /
282 // restoring on the client side.
283 class ScopedUnpackStateButAlignmentReset {
284  public:
ScopedUnpackStateButAlignmentReset(gl::GLApi * api,bool enable,bool is_3d)285   ScopedUnpackStateButAlignmentReset(gl::GLApi* api, bool enable, bool is_3d)
286       : api_(api) {
287     if (!enable) {
288       return;
289     }
290 
291     api_->glGetIntegervFn(GL_UNPACK_SKIP_PIXELS, &skip_pixels_);
292     api_->glPixelStoreiFn(GL_UNPACK_SKIP_PIXELS, 0);
293     api_->glGetIntegervFn(GL_UNPACK_SKIP_ROWS, &skip_rows_);
294     api_->glPixelStoreiFn(GL_UNPACK_SKIP_ROWS, 0);
295     api_->glGetIntegervFn(GL_UNPACK_ROW_LENGTH, &row_length_);
296     api_->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, 0);
297 
298     if (is_3d) {
299       api_->glGetIntegervFn(GL_UNPACK_SKIP_IMAGES, &skip_images_);
300       api_->glPixelStoreiFn(GL_UNPACK_SKIP_IMAGES, 0);
301       api_->glGetIntegervFn(GL_UNPACK_IMAGE_HEIGHT, &image_height_);
302       api_->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, 0);
303     }
304   }
305 
~ScopedUnpackStateButAlignmentReset()306   ~ScopedUnpackStateButAlignmentReset() {
307     if (skip_pixels_ != 0) {
308       api_->glPixelStoreiFn(GL_UNPACK_SKIP_PIXELS, skip_pixels_);
309     }
310     if (skip_rows_ != 0) {
311       api_->glPixelStoreiFn(GL_UNPACK_SKIP_ROWS, skip_rows_);
312     }
313     if (skip_images_ != 0) {
314       api_->glPixelStoreiFn(GL_UNPACK_SKIP_IMAGES, skip_images_);
315     }
316     if (row_length_ != 0) {
317       api_->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, row_length_);
318     }
319     if (image_height_ != 0) {
320       api_->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, image_height_);
321     }
322   }
323 
324  private:
325   gl::GLApi* api_;
326   GLint skip_pixels_ = 0;
327   GLint skip_rows_ = 0;
328   GLint skip_images_ = 0;
329   GLint row_length_ = 0;
330   GLint image_height_ = 0;
331 };
332 
333 class ScopedPackStateRowLengthReset {
334  public:
ScopedPackStateRowLengthReset(gl::GLApi * api,bool enable)335   ScopedPackStateRowLengthReset(gl::GLApi* api, bool enable) : api_(api) {
336     if (!enable) {
337       return;
338     }
339 
340     api_->glGetIntegervFn(GL_PACK_ROW_LENGTH, &row_length_);
341     api_->glPixelStoreiFn(GL_PACK_ROW_LENGTH, 0);
342   }
343 
~ScopedPackStateRowLengthReset()344   ~ScopedPackStateRowLengthReset() {
345     if (row_length_ != 0) {
346       api_->glPixelStoreiFn(GL_PACK_ROW_LENGTH, row_length_);
347     }
348   }
349 
350  private:
351   gl::GLApi* api_;
352   GLint row_length_ = 0;
353 };
354 
ModifyAttachmentForEmulatedFramebuffer(GLenum * attachment)355 bool ModifyAttachmentForEmulatedFramebuffer(GLenum* attachment) {
356   switch (*attachment) {
357     case GL_BACK:
358       *attachment = GL_COLOR_ATTACHMENT0;
359       return true;
360 
361     case GL_DEPTH:
362       *attachment = GL_DEPTH_ATTACHMENT;
363       return true;
364 
365     case GL_STENCIL:
366       *attachment = GL_STENCIL_ATTACHMENT;
367       return true;
368 
369     default:
370       return false;
371   }
372 }
373 
ModifyAttachmentsForEmulatedFramebuffer(std::vector<GLenum> * attachments)374 bool ModifyAttachmentsForEmulatedFramebuffer(std::vector<GLenum>* attachments) {
375   for (GLenum& attachment : *attachments) {
376     if (!ModifyAttachmentForEmulatedFramebuffer(&attachment)) {
377       return false;
378     }
379   }
380 
381   return true;
382 }
383 
384 }  // anonymous namespace
385 
386 // Implementations of commands
DoActiveTexture(GLenum texture)387 error::Error GLES2DecoderPassthroughImpl::DoActiveTexture(GLenum texture) {
388   CheckErrorCallbackState();
389   api()->glActiveTextureFn(texture);
390   if (CheckErrorCallbackState()) {
391     return error::kNoError;
392   }
393 
394   active_texture_unit_ = static_cast<size_t>(texture) - GL_TEXTURE0;
395   DCHECK(active_texture_unit_ < kMaxTextureUnits);
396 
397   return error::kNoError;
398 }
399 
DoAttachShader(GLuint program,GLuint shader)400 error::Error GLES2DecoderPassthroughImpl::DoAttachShader(GLuint program,
401                                                          GLuint shader) {
402   api()->glAttachShaderFn(GetProgramServiceID(program, resources_),
403                           GetShaderServiceID(shader, resources_));
404   return error::kNoError;
405 }
406 
DoBindAttribLocation(GLuint program,GLuint index,const char * name)407 error::Error GLES2DecoderPassthroughImpl::DoBindAttribLocation(
408     GLuint program,
409     GLuint index,
410     const char* name) {
411   api()->glBindAttribLocationFn(GetProgramServiceID(program, resources_), index,
412                                 name);
413   return error::kNoError;
414 }
415 
DoBindBuffer(GLenum target,GLuint buffer)416 error::Error GLES2DecoderPassthroughImpl::DoBindBuffer(GLenum target,
417                                                        GLuint buffer) {
418   CheckErrorCallbackState();
419   api()->glBindBufferFn(target, GetBufferServiceID(api(), buffer, resources_,
420                                                    bind_generates_resource_));
421   if (CheckErrorCallbackState()) {
422     return error::kNoError;
423   }
424 
425   DCHECK(bound_buffers_.find(target) != bound_buffers_.end());
426   bound_buffers_[target] = buffer;
427 
428   return error::kNoError;
429 }
430 
DoBindBufferBase(GLenum target,GLuint index,GLuint buffer)431 error::Error GLES2DecoderPassthroughImpl::DoBindBufferBase(GLenum target,
432                                                            GLuint index,
433                                                            GLuint buffer) {
434   CheckErrorCallbackState();
435   api()->glBindBufferBaseFn(
436       target, index,
437       GetBufferServiceID(api(), buffer, resources_, bind_generates_resource_));
438   if (CheckErrorCallbackState()) {
439     return error::kNoError;
440   }
441 
442   DCHECK(bound_buffers_.find(target) != bound_buffers_.end());
443   bound_buffers_[target] = buffer;
444 
445   return error::kNoError;
446 }
447 
DoBindBufferRange(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)448 error::Error GLES2DecoderPassthroughImpl::DoBindBufferRange(GLenum target,
449                                                             GLuint index,
450                                                             GLuint buffer,
451                                                             GLintptr offset,
452                                                             GLsizeiptr size) {
453   CheckErrorCallbackState();
454   api()->glBindBufferRangeFn(
455       target, index,
456       GetBufferServiceID(api(), buffer, resources_, bind_generates_resource_),
457       offset, size);
458   if (CheckErrorCallbackState()) {
459     return error::kNoError;
460   }
461 
462   DCHECK(bound_buffers_.find(target) != bound_buffers_.end());
463   bound_buffers_[target] = buffer;
464 
465   return error::kNoError;
466 }
467 
DoBindFramebuffer(GLenum target,GLuint framebuffer)468 error::Error GLES2DecoderPassthroughImpl::DoBindFramebuffer(
469     GLenum target,
470     GLuint framebuffer) {
471   CheckErrorCallbackState();
472   api()->glBindFramebufferEXTFn(
473       target, GetFramebufferServiceID(api(), framebuffer, &framebuffer_id_map_,
474                                       bind_generates_resource_));
475   if (CheckErrorCallbackState()) {
476     return error::kNoError;
477   }
478 
479   // Update tracking of the bound framebuffer
480   bool draw_framebuffer_changed = false;
481   switch (target) {
482     case GL_FRAMEBUFFER_EXT:
483       draw_framebuffer_changed = true;
484       bound_draw_framebuffer_ = framebuffer;
485       bound_read_framebuffer_ = framebuffer;
486       break;
487 
488     case GL_DRAW_FRAMEBUFFER:
489       draw_framebuffer_changed = true;
490       bound_draw_framebuffer_ = framebuffer;
491       break;
492 
493     case GL_READ_FRAMEBUFFER:
494       bound_read_framebuffer_ = framebuffer;
495       break;
496 
497     default:
498       NOTREACHED();
499       break;
500   }
501 
502   // Resync the surface offset if the draw framebuffer has changed to or from
503   // the default framebuffer
504   if (draw_framebuffer_changed && bound_draw_framebuffer_ != framebuffer &&
505       (bound_draw_framebuffer_ == 0 || framebuffer == 0)) {
506     ApplySurfaceDrawOffset();
507   }
508 
509   return error::kNoError;
510 }
511 
DoBindImageTexture(GLuint unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)512 error::Error GLES2DecoderPassthroughImpl::DoBindImageTexture(GLuint unit,
513                                                              GLuint texture,
514                                                              GLint level,
515                                                              GLboolean layered,
516                                                              GLint layer,
517                                                              GLenum access,
518                                                              GLenum format) {
519   api()->glBindImageTextureEXTFn(
520       unit,
521       GetTextureServiceID(api(), texture, resources_, bind_generates_resource_),
522       level, layered, layer, access, format);
523   return error::kNoError;
524 }
525 
DoBindRenderbuffer(GLenum target,GLuint renderbuffer)526 error::Error GLES2DecoderPassthroughImpl::DoBindRenderbuffer(
527     GLenum target,
528     GLuint renderbuffer) {
529   api()->glBindRenderbufferEXTFn(
530       target, GetRenderbufferServiceID(api(), renderbuffer, resources_,
531                                        bind_generates_resource_));
532   return error::kNoError;
533 }
534 
DoBindSampler(GLuint unit,GLuint sampler)535 error::Error GLES2DecoderPassthroughImpl::DoBindSampler(GLuint unit,
536                                                         GLuint sampler) {
537   api()->glBindSamplerFn(unit, GetSamplerServiceID(sampler, resources_));
538   return error::kNoError;
539 }
540 
DoBindTexture(GLenum target,GLuint texture)541 error::Error GLES2DecoderPassthroughImpl::DoBindTexture(GLenum target,
542                                                         GLuint texture) {
543   GLuint service_id =
544       GetTextureServiceID(api(), texture, resources_, bind_generates_resource_);
545 
546   CheckErrorCallbackState();
547 
548   api()->glBindTextureFn(target, service_id);
549 
550   // Only update tracking if no error was generated in the bind call
551   if (CheckErrorCallbackState()) {
552     return error::kNoError;
553   }
554 
555   // Track the currently bound textures
556   DCHECK(GLenumToTextureTarget(target) != TextureTarget::kUnkown);
557   scoped_refptr<TexturePassthrough> texture_passthrough = nullptr;
558 
559   // If there was anything bound that required an image bind / copy,
560   // forget it since it's no longer bound to a sampler.
561   RemovePendingBindingTexture(target, active_texture_unit_);
562 
563   if (service_id != 0) {
564     // Create a new texture object to track this texture
565     if (!resources_->texture_object_map.GetServiceID(texture,
566                                                      &texture_passthrough) ||
567         texture_passthrough == nullptr) {
568       texture_passthrough = new TexturePassthrough(service_id, target);
569       resources_->texture_object_map.SetIDMapping(texture, texture_passthrough);
570     } else {
571       // Shouldn't be possible to get here if this texture has a different
572       // target than the one it was just bound to
573       DCHECK(texture_passthrough->target() == target);
574     }
575 
576     DCHECK(texture_passthrough);
577 
578     // If |texture_passthrough| has a bound image that requires processing
579     // before a draw, then keep track of it.
580     if (texture_passthrough->is_bind_pending()) {
581       textures_pending_binding_.emplace_back(target, active_texture_unit_,
582                                              texture_passthrough->AsWeakPtr());
583     }
584   }
585 
586   BoundTexture* bound_texture =
587       &bound_textures_[static_cast<size_t>(GLenumToTextureTarget(target))]
588                       [active_texture_unit_];
589   bound_texture->client_id = texture;
590   bound_texture->texture = std::move(texture_passthrough);
591 
592   return error::kNoError;
593 }
594 
DoBindTransformFeedback(GLenum target,GLuint transformfeedback)595 error::Error GLES2DecoderPassthroughImpl::DoBindTransformFeedback(
596     GLenum target,
597     GLuint transformfeedback) {
598   api()->glBindTransformFeedbackFn(
599       target, GetTransformFeedbackServiceID(transformfeedback,
600                                             &transform_feedback_id_map_));
601   return error::kNoError;
602 }
603 
DoBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)604 error::Error GLES2DecoderPassthroughImpl::DoBlendColor(GLclampf red,
605                                                        GLclampf green,
606                                                        GLclampf blue,
607                                                        GLclampf alpha) {
608   api()->glBlendColorFn(red, green, blue, alpha);
609   return error::kNoError;
610 }
611 
DoBlendEquation(GLenum mode)612 error::Error GLES2DecoderPassthroughImpl::DoBlendEquation(GLenum mode) {
613   api()->glBlendEquationFn(mode);
614   return error::kNoError;
615 }
616 
DoBlendEquationiOES(GLuint buf,GLenum mode)617 error::Error GLES2DecoderPassthroughImpl::DoBlendEquationiOES(GLuint buf,
618                                                               GLenum mode) {
619   api()->glBlendEquationiOESFn(buf, mode);
620   return error::kNoError;
621 }
622 
DoBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)623 error::Error GLES2DecoderPassthroughImpl::DoBlendEquationSeparate(
624     GLenum modeRGB,
625     GLenum modeAlpha) {
626   api()->glBlendEquationSeparateFn(modeRGB, modeAlpha);
627   return error::kNoError;
628 }
629 
DoBlendEquationSeparateiOES(GLuint buf,GLenum modeRGB,GLenum modeAlpha)630 error::Error GLES2DecoderPassthroughImpl::DoBlendEquationSeparateiOES(
631     GLuint buf,
632     GLenum modeRGB,
633     GLenum modeAlpha) {
634   api()->glBlendEquationSeparateiOESFn(buf, modeRGB, modeAlpha);
635   return error::kNoError;
636 }
637 
DoBlendFunc(GLenum sfactor,GLenum dfactor)638 error::Error GLES2DecoderPassthroughImpl::DoBlendFunc(GLenum sfactor,
639                                                       GLenum dfactor) {
640   api()->glBlendFuncFn(sfactor, dfactor);
641   return error::kNoError;
642 }
643 
DoBlendFunciOES(GLuint buf,GLenum sfactor,GLenum dfactor)644 error::Error GLES2DecoderPassthroughImpl::DoBlendFunciOES(GLuint buf,
645                                                           GLenum sfactor,
646                                                           GLenum dfactor) {
647   api()->glBlendFunciOESFn(buf, sfactor, dfactor);
648   return error::kNoError;
649 }
650 
DoBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)651 error::Error GLES2DecoderPassthroughImpl::DoBlendFuncSeparate(GLenum srcRGB,
652                                                               GLenum dstRGB,
653                                                               GLenum srcAlpha,
654                                                               GLenum dstAlpha) {
655   api()->glBlendFuncSeparateFn(srcRGB, dstRGB, srcAlpha, dstAlpha);
656   return error::kNoError;
657 }
658 
DoBlendFuncSeparateiOES(GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)659 error::Error GLES2DecoderPassthroughImpl::DoBlendFuncSeparateiOES(
660     GLuint buf,
661     GLenum srcRGB,
662     GLenum dstRGB,
663     GLenum srcAlpha,
664     GLenum dstAlpha) {
665   api()->glBlendFuncSeparateiOESFn(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
666   return error::kNoError;
667 }
668 
DoBufferData(GLenum target,GLsizeiptr size,const void * data,GLenum usage)669 error::Error GLES2DecoderPassthroughImpl::DoBufferData(GLenum target,
670                                                        GLsizeiptr size,
671                                                        const void* data,
672                                                        GLenum usage) {
673   CheckErrorCallbackState();
674   api()->glBufferDataFn(target, size, data, usage);
675   if (CheckErrorCallbackState()) {
676     return error::kNoError;
677   }
678 
679   // Calling buffer data on a mapped buffer will implicitly unmap it
680   resources_->mapped_buffer_map.erase(bound_buffers_[target]);
681 
682   return error::kNoError;
683 }
684 
DoBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data)685 error::Error GLES2DecoderPassthroughImpl::DoBufferSubData(GLenum target,
686                                                           GLintptr offset,
687                                                           GLsizeiptr size,
688                                                           const void* data) {
689   api()->glBufferSubDataFn(target, offset, size, data);
690   return error::kNoError;
691 }
692 
DoCheckFramebufferStatus(GLenum target,uint32_t * result)693 error::Error GLES2DecoderPassthroughImpl::DoCheckFramebufferStatus(
694     GLenum target,
695     uint32_t* result) {
696   *result = api()->glCheckFramebufferStatusEXTFn(target);
697   return error::kNoError;
698 }
699 
DoClear(GLbitfield mask)700 error::Error GLES2DecoderPassthroughImpl::DoClear(GLbitfield mask) {
701   api()->glClearFn(mask);
702   return error::kNoError;
703 }
704 
DoClearBufferfi(GLenum buffer,GLint drawbuffers,GLfloat depth,GLint stencil)705 error::Error GLES2DecoderPassthroughImpl::DoClearBufferfi(GLenum buffer,
706                                                           GLint drawbuffers,
707                                                           GLfloat depth,
708                                                           GLint stencil) {
709   api()->glClearBufferfiFn(buffer, drawbuffers, depth, stencil);
710   return error::kNoError;
711 }
712 
DoClearBufferfv(GLenum buffer,GLint drawbuffers,const volatile GLfloat * value)713 error::Error GLES2DecoderPassthroughImpl::DoClearBufferfv(
714     GLenum buffer,
715     GLint drawbuffers,
716     const volatile GLfloat* value) {
717   api()->glClearBufferfvFn(buffer, drawbuffers,
718                            const_cast<const GLfloat*>(value));
719   return error::kNoError;
720 }
721 
DoClearBufferiv(GLenum buffer,GLint drawbuffers,const volatile GLint * value)722 error::Error GLES2DecoderPassthroughImpl::DoClearBufferiv(
723     GLenum buffer,
724     GLint drawbuffers,
725     const volatile GLint* value) {
726   api()->glClearBufferivFn(buffer, drawbuffers,
727                            const_cast<const GLint*>(value));
728   return error::kNoError;
729 }
730 
DoClearBufferuiv(GLenum buffer,GLint drawbuffers,const volatile GLuint * value)731 error::Error GLES2DecoderPassthroughImpl::DoClearBufferuiv(
732     GLenum buffer,
733     GLint drawbuffers,
734     const volatile GLuint* value) {
735   api()->glClearBufferuivFn(buffer, drawbuffers,
736                             const_cast<const GLuint*>(value));
737   return error::kNoError;
738 }
739 
DoClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)740 error::Error GLES2DecoderPassthroughImpl::DoClearColor(GLclampf red,
741                                                        GLclampf green,
742                                                        GLclampf blue,
743                                                        GLclampf alpha) {
744   api()->glClearColorFn(red, green, blue, alpha);
745   return error::kNoError;
746 }
747 
DoClearDepthf(GLclampf depth)748 error::Error GLES2DecoderPassthroughImpl::DoClearDepthf(GLclampf depth) {
749   api()->glClearDepthfFn(depth);
750   return error::kNoError;
751 }
752 
DoClearStencil(GLint s)753 error::Error GLES2DecoderPassthroughImpl::DoClearStencil(GLint s) {
754   api()->glClearStencilFn(s);
755   return error::kNoError;
756 }
757 
DoClientWaitSync(GLuint sync,GLbitfield flags,GLuint64 timeout,GLenum * result)758 error::Error GLES2DecoderPassthroughImpl::DoClientWaitSync(GLuint sync,
759                                                            GLbitfield flags,
760                                                            GLuint64 timeout,
761                                                            GLenum* result) {
762   // Force GL_SYNC_FLUSH_COMMANDS_BIT to avoid infinite wait.
763   GLbitfield modified_flags = flags | GL_SYNC_FLUSH_COMMANDS_BIT;
764   *result = api()->glClientWaitSyncFn(GetSyncServiceID(sync, resources_),
765                                       modified_flags, timeout);
766   return error::kNoError;
767 }
768 
DoColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)769 error::Error GLES2DecoderPassthroughImpl::DoColorMask(GLboolean red,
770                                                       GLboolean green,
771                                                       GLboolean blue,
772                                                       GLboolean alpha) {
773   api()->glColorMaskFn(red, green, blue, alpha);
774   return error::kNoError;
775 }
776 
DoColorMaskiOES(GLuint buf,GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)777 error::Error GLES2DecoderPassthroughImpl::DoColorMaskiOES(GLuint buf,
778                                                           GLboolean red,
779                                                           GLboolean green,
780                                                           GLboolean blue,
781                                                           GLboolean alpha) {
782   api()->glColorMaskiOESFn(buf, red, green, blue, alpha);
783   return error::kNoError;
784 }
785 
DoCompileShader(GLuint shader)786 error::Error GLES2DecoderPassthroughImpl::DoCompileShader(GLuint shader) {
787   api()->glCompileShaderFn(GetShaderServiceID(shader, resources_));
788   return error::kNoError;
789 }
790 
DoCompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei image_size,GLsizei data_size,const void * data)791 error::Error GLES2DecoderPassthroughImpl::DoCompressedTexImage2D(
792     GLenum target,
793     GLint level,
794     GLenum internalformat,
795     GLsizei width,
796     GLsizei height,
797     GLint border,
798     GLsizei image_size,
799     GLsizei data_size,
800     const void* data) {
801   CheckErrorCallbackState();
802   api()->glCompressedTexImage2DRobustANGLEFn(target, level, internalformat,
803                                              width, height, border, image_size,
804                                              data_size, data);
805   if (CheckErrorCallbackState()) {
806     return error::kNoError;
807   }
808 
809   UpdateTextureSizeFromTarget(target);
810 
811   // Texture data upload can be slow.  Exit command processing to allow for
812   // context preemption and GPU watchdog checks.
813   ExitCommandProcessingEarly();
814 
815   return error::kNoError;
816 }
817 
DoCompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei image_size,GLsizei data_size,const void * data)818 error::Error GLES2DecoderPassthroughImpl::DoCompressedTexSubImage2D(
819     GLenum target,
820     GLint level,
821     GLint xoffset,
822     GLint yoffset,
823     GLsizei width,
824     GLsizei height,
825     GLenum format,
826     GLsizei image_size,
827     GLsizei data_size,
828     const void* data) {
829   api()->glCompressedTexSubImage2DRobustANGLEFn(target, level, xoffset, yoffset,
830                                                 width, height, format,
831                                                 image_size, data_size, data);
832 
833   // Texture data upload can be slow.  Exit command processing to allow for
834   // context preemption and GPU watchdog checks.
835   ExitCommandProcessingEarly();
836 
837   return error::kNoError;
838 }
839 
DoCompressedTexImage3D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei image_size,GLsizei data_size,const void * data)840 error::Error GLES2DecoderPassthroughImpl::DoCompressedTexImage3D(
841     GLenum target,
842     GLint level,
843     GLenum internalformat,
844     GLsizei width,
845     GLsizei height,
846     GLsizei depth,
847     GLint border,
848     GLsizei image_size,
849     GLsizei data_size,
850     const void* data) {
851   CheckErrorCallbackState();
852   api()->glCompressedTexImage3DRobustANGLEFn(target, level, internalformat,
853                                              width, height, depth, border,
854                                              image_size, data_size, data);
855   if (CheckErrorCallbackState()) {
856     return error::kNoError;
857   }
858 
859   UpdateTextureSizeFromTarget(target);
860 
861   // Texture data upload can be slow.  Exit command processing to allow for
862   // context preemption and GPU watchdog checks.
863   ExitCommandProcessingEarly();
864 
865   return error::kNoError;
866 }
867 
DoCompressedTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei image_size,GLsizei data_size,const void * data)868 error::Error GLES2DecoderPassthroughImpl::DoCompressedTexSubImage3D(
869     GLenum target,
870     GLint level,
871     GLint xoffset,
872     GLint yoffset,
873     GLint zoffset,
874     GLsizei width,
875     GLsizei height,
876     GLsizei depth,
877     GLenum format,
878     GLsizei image_size,
879     GLsizei data_size,
880     const void* data) {
881   api()->glCompressedTexSubImage3DRobustANGLEFn(
882       target, level, xoffset, yoffset, zoffset, width, height, depth, format,
883       image_size, data_size, data);
884 
885   // Texture data upload can be slow.  Exit command processing to allow for
886   // context preemption and GPU watchdog checks.
887   ExitCommandProcessingEarly();
888 
889   return error::kNoError;
890 }
891 
DoContextVisibilityHintCHROMIUM(GLboolean visibility)892 error::Error GLES2DecoderPassthroughImpl::DoContextVisibilityHintCHROMIUM(
893     GLboolean visibility) {
894   if (feature_info_->IsWebGLContext())
895     context_->SetVisibility(visibility == GL_TRUE);
896   return error::kNoError;
897 }
898 
DoCopyBufferSubData(GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)899 error::Error GLES2DecoderPassthroughImpl::DoCopyBufferSubData(
900     GLenum readtarget,
901     GLenum writetarget,
902     GLintptr readoffset,
903     GLintptr writeoffset,
904     GLsizeiptr size) {
905   api()->glCopyBufferSubDataFn(readtarget, writetarget, readoffset, writeoffset,
906                                size);
907   return error::kNoError;
908 }
909 
DoCopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)910 error::Error GLES2DecoderPassthroughImpl::DoCopyTexImage2D(
911     GLenum target,
912     GLint level,
913     GLenum internalformat,
914     GLint x,
915     GLint y,
916     GLsizei width,
917     GLsizei height,
918     GLint border) {
919   CheckErrorCallbackState();
920   api()->glCopyTexImage2DFn(target, level, internalformat, x, y, width, height,
921                             border);
922   if (CheckErrorCallbackState()) {
923     return error::kNoError;
924   }
925 
926   UpdateTextureSizeFromTarget(target);
927 
928   // Texture data copying can be slow.  Exit command processing to allow for
929   // context preemption and GPU watchdog checks.
930   ExitCommandProcessingEarly();
931 
932   return error::kNoError;
933 }
934 
DoCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)935 error::Error GLES2DecoderPassthroughImpl::DoCopyTexSubImage2D(GLenum target,
936                                                               GLint level,
937                                                               GLint xoffset,
938                                                               GLint yoffset,
939                                                               GLint x,
940                                                               GLint y,
941                                                               GLsizei width,
942                                                               GLsizei height) {
943   api()->glCopyTexSubImage2DFn(target, level, xoffset, yoffset, x, y, width,
944                                height);
945 
946   // Texture data copying can be slow.  Exit command processing to allow for
947   // context preemption and GPU watchdog checks.
948   ExitCommandProcessingEarly();
949 
950   return error::kNoError;
951 }
952 
DoCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)953 error::Error GLES2DecoderPassthroughImpl::DoCopyTexSubImage3D(GLenum target,
954                                                               GLint level,
955                                                               GLint xoffset,
956                                                               GLint yoffset,
957                                                               GLint zoffset,
958                                                               GLint x,
959                                                               GLint y,
960                                                               GLsizei width,
961                                                               GLsizei height) {
962   api()->glCopyTexSubImage3DFn(target, level, xoffset, yoffset, zoffset, x, y,
963                                width, height);
964 
965   // Texture data copying can be slow.  Exit command processing to allow for
966   // context preemption and GPU watchdog checks.
967   ExitCommandProcessingEarly();
968 
969   return error::kNoError;
970 }
971 
DoCreateProgram(GLuint client_id)972 error::Error GLES2DecoderPassthroughImpl::DoCreateProgram(GLuint client_id) {
973   return CreateHelper(client_id, &resources_->program_id_map,
974                       [this]() { return api()->glCreateProgramFn(); });
975 }
976 
DoCreateShader(GLenum type,GLuint client_id)977 error::Error GLES2DecoderPassthroughImpl::DoCreateShader(GLenum type,
978                                                          GLuint client_id) {
979   return CreateHelper(client_id, &resources_->shader_id_map,
980                       [this, type]() { return api()->glCreateShaderFn(type); });
981 }
982 
DoCullFace(GLenum mode)983 error::Error GLES2DecoderPassthroughImpl::DoCullFace(GLenum mode) {
984   api()->glCullFaceFn(mode);
985   return error::kNoError;
986 }
987 
DoDeleteBuffers(GLsizei n,const volatile GLuint * buffers)988 error::Error GLES2DecoderPassthroughImpl::DoDeleteBuffers(
989     GLsizei n,
990     const volatile GLuint* buffers) {
991   // DeleteHelper requires that n is non-negative because it allocates a copy of
992   // the IDs
993   if (n < 0) {
994     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
995     return error::kNoError;
996   }
997 
998   std::vector<GLuint> service_ids(n, 0);
999   for (GLsizei ii = 0; ii < n; ++ii) {
1000     GLuint client_id = buffers[ii];
1001 
1002     // Update the bound and mapped buffer state tracking
1003     for (auto& buffer_binding : bound_buffers_) {
1004       if (buffer_binding.second == client_id) {
1005         buffer_binding.second = 0;
1006       }
1007       resources_->mapped_buffer_map.erase(client_id);
1008     }
1009 
1010     service_ids[ii] =
1011         resources_->buffer_id_map.GetServiceIDOrInvalid(client_id);
1012     resources_->buffer_id_map.RemoveClientID(client_id);
1013 
1014     auto is_the_deleted_buffer = [client_id](const auto& update) {
1015       return update.first == client_id;
1016     };
1017     base::EraseIf(buffer_shadow_updates_, is_the_deleted_buffer);
1018     for (PendingQuery& pending_query : pending_queries_) {
1019       base::EraseIf(pending_query.buffer_shadow_updates, is_the_deleted_buffer);
1020     }
1021   }
1022   api()->glDeleteBuffersARBFn(n, service_ids.data());
1023 
1024   return error::kNoError;
1025 }
1026 
DoDeleteFramebuffers(GLsizei n,const volatile GLuint * framebuffers)1027 error::Error GLES2DecoderPassthroughImpl::DoDeleteFramebuffers(
1028     GLsizei n,
1029     const volatile GLuint* framebuffers) {
1030   // DeleteHelper requires that n is non-negative because it allocates a copy of
1031   // the IDs
1032   if (n < 0) {
1033     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
1034     return error::kNoError;
1035   }
1036 
1037   std::vector<GLuint> framebuffers_copy(framebuffers, framebuffers + n);
1038 
1039   // If a bound framebuffer is deleted, it's binding is reset to 0.  In the case
1040   // of an emulated default framebuffer, bind the emulated one.
1041   for (GLuint framebuffer : framebuffers_copy) {
1042     if (framebuffer == bound_draw_framebuffer_) {
1043       bound_draw_framebuffer_ = 0;
1044       if (emulated_back_buffer_) {
1045         api()->glBindFramebufferEXTFn(
1046             GL_DRAW_FRAMEBUFFER, emulated_back_buffer_->framebuffer_service_id);
1047       }
1048 
1049       // Update the surface offset if the bound draw framebuffer is deleted
1050       ApplySurfaceDrawOffset();
1051     }
1052     if (framebuffer == bound_read_framebuffer_) {
1053       bound_read_framebuffer_ = 0;
1054       if (emulated_back_buffer_) {
1055         api()->glBindFramebufferEXTFn(
1056             GL_READ_FRAMEBUFFER, emulated_back_buffer_->framebuffer_service_id);
1057       }
1058     }
1059   }
1060 
1061   return DeleteHelper(n, framebuffers_copy.data(), &framebuffer_id_map_,
1062                       [this](GLsizei n, GLuint* framebuffers) {
1063                         api()->glDeleteFramebuffersEXTFn(n, framebuffers);
1064                       });
1065 }
1066 
DoDeleteProgram(GLuint program)1067 error::Error GLES2DecoderPassthroughImpl::DoDeleteProgram(GLuint program) {
1068   return DeleteHelper(
1069       program, &resources_->program_id_map,
1070       [this](GLuint program) { api()->glDeleteProgramFn(program); });
1071 }
1072 
DoDeleteRenderbuffers(GLsizei n,const volatile GLuint * renderbuffers)1073 error::Error GLES2DecoderPassthroughImpl::DoDeleteRenderbuffers(
1074     GLsizei n,
1075     const volatile GLuint* renderbuffers) {
1076   // DeleteHelper requires that n is non-negative because it allocates a copy of
1077   // the IDs
1078   if (n < 0) {
1079     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
1080     return error::kNoError;
1081   }
1082   return DeleteHelper(n, renderbuffers, &resources_->renderbuffer_id_map,
1083                       [this](GLsizei n, GLuint* renderbuffers) {
1084                         api()->glDeleteRenderbuffersEXTFn(n, renderbuffers);
1085                       });
1086 }
1087 
DoDeleteSamplers(GLsizei n,const volatile GLuint * samplers)1088 error::Error GLES2DecoderPassthroughImpl::DoDeleteSamplers(
1089     GLsizei n,
1090     const volatile GLuint* samplers) {
1091   // DeleteHelper requires that n is non-negative because it allocates a copy of
1092   // the IDs
1093   if (n < 0) {
1094     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
1095     return error::kNoError;
1096   }
1097   return DeleteHelper(n, samplers, &resources_->sampler_id_map,
1098                       [this](GLsizei n, GLuint* samplers) {
1099                         api()->glDeleteSamplersFn(n, samplers);
1100                       });
1101 }
1102 
DoDeleteSync(GLuint sync)1103 error::Error GLES2DecoderPassthroughImpl::DoDeleteSync(GLuint sync) {
1104   return DeleteHelper(sync, &resources_->sync_id_map, [this](uintptr_t sync) {
1105     api()->glDeleteSyncFn(reinterpret_cast<GLsync>(sync));
1106   });
1107 }
1108 
DoDeleteShader(GLuint shader)1109 error::Error GLES2DecoderPassthroughImpl::DoDeleteShader(GLuint shader) {
1110   return DeleteHelper(
1111       shader, &resources_->shader_id_map,
1112       [this](GLuint shader) { api()->glDeleteShaderFn(shader); });
1113 }
1114 
DoDeleteTextures(GLsizei n,const volatile GLuint * textures)1115 error::Error GLES2DecoderPassthroughImpl::DoDeleteTextures(
1116     GLsizei n,
1117     const volatile GLuint* textures) {
1118   // DeleteHelper requires that n is non-negative because it allocates a copy of
1119   // the IDs
1120   if (n < 0) {
1121     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
1122     return error::kNoError;
1123   }
1124 
1125   // Textures that are currently associated with a mailbox are stored in the
1126   // texture_object_map_ and are deleted automatically when they are
1127   // unreferenced.  Only delete textures that are not in this map.
1128   std::vector<GLuint> non_mailbox_client_ids;
1129   for (GLsizei ii = 0; ii < n; ++ii) {
1130     GLuint client_id = textures[ii];
1131     scoped_refptr<TexturePassthrough> texture = nullptr;
1132     if (!resources_->texture_object_map.GetServiceID(client_id, &texture) ||
1133         texture == nullptr) {
1134       // Delete with DeleteHelper
1135       non_mailbox_client_ids.push_back(client_id);
1136     } else {
1137       // Deleted when unreferenced
1138       resources_->texture_id_map.RemoveClientID(client_id);
1139       resources_->texture_object_map.RemoveClientID(client_id);
1140       resources_->texture_shared_image_map.erase(client_id);
1141       UpdateTextureBinding(texture->target(), client_id, nullptr);
1142     }
1143 
1144     // Notify the discardable manager that the texture is deleted
1145     group_->passthrough_discardable_manager()->DeleteTexture(client_id,
1146                                                              group_.get());
1147   }
1148   return DeleteHelper(
1149       non_mailbox_client_ids.size(), non_mailbox_client_ids.data(),
1150       &resources_->texture_id_map, [this](GLsizei n, GLuint* textures) {
1151         api()->glDeleteTexturesFn(n, textures);
1152       });
1153 }
1154 
DoDeleteTransformFeedbacks(GLsizei n,const volatile GLuint * ids)1155 error::Error GLES2DecoderPassthroughImpl::DoDeleteTransformFeedbacks(
1156     GLsizei n,
1157     const volatile GLuint* ids) {
1158   // DeleteHelper requires that n is non-negative because it allocates a copy of
1159   // the IDs
1160   if (n < 0) {
1161     InsertError(GL_INVALID_VALUE, "n cannot be negative.");
1162     return error::kNoError;
1163   }
1164   return DeleteHelper(n, ids, &transform_feedback_id_map_,
1165                       [this](GLsizei n, GLuint* transform_feedbacks) {
1166                         api()->glDeleteTransformFeedbacksFn(
1167                             n, transform_feedbacks);
1168                       });
1169 }
1170 
DoDepthFunc(GLenum func)1171 error::Error GLES2DecoderPassthroughImpl::DoDepthFunc(GLenum func) {
1172   api()->glDepthFuncFn(func);
1173   return error::kNoError;
1174 }
1175 
DoDepthMask(GLboolean flag)1176 error::Error GLES2DecoderPassthroughImpl::DoDepthMask(GLboolean flag) {
1177   api()->glDepthMaskFn(flag);
1178   return error::kNoError;
1179 }
1180 
DoDepthRangef(GLclampf zNear,GLclampf zFar)1181 error::Error GLES2DecoderPassthroughImpl::DoDepthRangef(GLclampf zNear,
1182                                                         GLclampf zFar) {
1183   api()->glDepthRangefFn(zNear, zFar);
1184   return error::kNoError;
1185 }
1186 
DoDetachShader(GLuint program,GLuint shader)1187 error::Error GLES2DecoderPassthroughImpl::DoDetachShader(GLuint program,
1188                                                          GLuint shader) {
1189   api()->glDetachShaderFn(GetProgramServiceID(program, resources_),
1190                           GetShaderServiceID(shader, resources_));
1191   return error::kNoError;
1192 }
1193 
DoDisable(GLenum cap)1194 error::Error GLES2DecoderPassthroughImpl::DoDisable(GLenum cap) {
1195   api()->glDisableFn(cap);
1196   return error::kNoError;
1197 }
1198 
DoDisableVertexAttribArray(GLuint index)1199 error::Error GLES2DecoderPassthroughImpl::DoDisableVertexAttribArray(
1200     GLuint index) {
1201   api()->glDisableVertexAttribArrayFn(index);
1202   return error::kNoError;
1203 }
1204 
DoDispatchCompute(GLuint num_groups_x,GLuint num_groups_y,GLuint num_groups_z)1205 error::Error GLES2DecoderPassthroughImpl::DoDispatchCompute(
1206     GLuint num_groups_x,
1207     GLuint num_groups_y,
1208     GLuint num_groups_z) {
1209   BindPendingImagesForSamplersIfNeeded();
1210   api()->glDispatchComputeFn(num_groups_x, num_groups_y, num_groups_z);
1211   return error::kNoError;
1212 }
1213 
DoDispatchComputeIndirect(GLintptr offset)1214 error::Error GLES2DecoderPassthroughImpl::DoDispatchComputeIndirect(
1215     GLintptr offset) {
1216   BindPendingImagesForSamplersIfNeeded();
1217   // TODO(jiajie.hu@intel.com): Use glDispatchComputeIndirectRobustANGLEFn()
1218   // when it's ready in ANGLE.
1219   api()->glDispatchComputeIndirectFn(offset);
1220   return error::kNoError;
1221 }
1222 
DoDrawArrays(GLenum mode,GLint first,GLsizei count)1223 error::Error GLES2DecoderPassthroughImpl::DoDrawArrays(GLenum mode,
1224                                                        GLint first,
1225                                                        GLsizei count) {
1226   BindPendingImagesForSamplersIfNeeded();
1227   api()->glDrawArraysFn(mode, first, count);
1228   return error::kNoError;
1229 }
1230 
DoDrawArraysIndirect(GLenum mode,const void * offset)1231 error::Error GLES2DecoderPassthroughImpl::DoDrawArraysIndirect(
1232     GLenum mode,
1233     const void* offset) {
1234   BindPendingImagesForSamplersIfNeeded();
1235   // TODO(jiajie.hu@intel.com): Use glDrawArraysIndirectRobustANGLEFn() when
1236   // it's ready in ANGLE.
1237   api()->glDrawArraysIndirectFn(mode, offset);
1238   return error::kNoError;
1239 }
1240 
DoDrawElements(GLenum mode,GLsizei count,GLenum type,const void * indices)1241 error::Error GLES2DecoderPassthroughImpl::DoDrawElements(GLenum mode,
1242                                                          GLsizei count,
1243                                                          GLenum type,
1244                                                          const void* indices) {
1245   BindPendingImagesForSamplersIfNeeded();
1246   api()->glDrawElementsFn(mode, count, type, indices);
1247   return error::kNoError;
1248 }
1249 
DoDrawElementsIndirect(GLenum mode,GLenum type,const void * offset)1250 error::Error GLES2DecoderPassthroughImpl::DoDrawElementsIndirect(
1251     GLenum mode,
1252     GLenum type,
1253     const void* offset) {
1254   BindPendingImagesForSamplersIfNeeded();
1255   // TODO(jiajie.hu@intel.com): Use glDrawElementsIndirectRobustANGLEFn() when
1256   // it's ready in ANGLE.
1257   api()->glDrawElementsIndirectFn(mode, type, offset);
1258   return error::kNoError;
1259 }
1260 
DoEnable(GLenum cap)1261 error::Error GLES2DecoderPassthroughImpl::DoEnable(GLenum cap) {
1262   api()->glEnableFn(cap);
1263   return error::kNoError;
1264 }
1265 
DoEnableVertexAttribArray(GLuint index)1266 error::Error GLES2DecoderPassthroughImpl::DoEnableVertexAttribArray(
1267     GLuint index) {
1268   api()->glEnableVertexAttribArrayFn(index);
1269   return error::kNoError;
1270 }
1271 
DoFenceSync(GLenum condition,GLbitfield flags,GLuint client_id)1272 error::Error GLES2DecoderPassthroughImpl::DoFenceSync(GLenum condition,
1273                                                       GLbitfield flags,
1274                                                       GLuint client_id) {
1275   if (resources_->sync_id_map.HasClientID(client_id)) {
1276     return error::kInvalidArguments;
1277   }
1278 
1279   CheckErrorCallbackState();
1280   GLsync service_id = api()->glFenceSyncFn(condition, flags);
1281   if (CheckErrorCallbackState()) {
1282     return error::kNoError;
1283   }
1284 
1285   resources_->sync_id_map.SetIDMapping(client_id,
1286                                        reinterpret_cast<uintptr_t>(service_id));
1287 
1288   return error::kNoError;
1289 }
1290 
DoFinish()1291 error::Error GLES2DecoderPassthroughImpl::DoFinish() {
1292   // Finish can take a long time, make sure the watchdog gives it the most
1293   // amount of time to complete.
1294   group_->ReportProgress();
1295 
1296   api()->glFinishFn();
1297 
1298   group_->ReportProgress();
1299 
1300   error::Error error = ProcessReadPixels(true);
1301   if (error != error::kNoError) {
1302     return error;
1303   }
1304   return ProcessQueries(true);
1305 }
1306 
DoFlush()1307 error::Error GLES2DecoderPassthroughImpl::DoFlush() {
1308   api()->glFlushFn();
1309 
1310   error::Error error = ProcessReadPixels(false);
1311   if (error != error::kNoError) {
1312     return error;
1313   }
1314   return ProcessQueries(false);
1315 }
1316 
DoFlushMappedBufferRange(GLenum target,GLintptr offset,GLsizeiptr size)1317 error::Error GLES2DecoderPassthroughImpl::DoFlushMappedBufferRange(
1318     GLenum target,
1319     GLintptr offset,
1320     GLsizeiptr size) {
1321   auto bound_buffers_iter = bound_buffers_.find(target);
1322   if (bound_buffers_iter == bound_buffers_.end() ||
1323       bound_buffers_iter->second == 0) {
1324     InsertError(GL_INVALID_OPERATION, "No buffer bound to this target.");
1325     return error::kNoError;
1326   }
1327 
1328   GLuint client_buffer = bound_buffers_iter->second;
1329   auto mapped_buffer_info_iter =
1330       resources_->mapped_buffer_map.find(client_buffer);
1331   if (mapped_buffer_info_iter == resources_->mapped_buffer_map.end()) {
1332     InsertError(GL_INVALID_OPERATION, "Buffer is not mapped.");
1333     return error::kNoError;
1334   }
1335 
1336   const MappedBuffer& map_info = mapped_buffer_info_iter->second;
1337 
1338   if (offset < 0) {
1339     InsertError(GL_INVALID_VALUE, "Offset cannot be negative.");
1340     return error::kNoError;
1341   }
1342 
1343   if (size < 0) {
1344     InsertError(GL_INVALID_VALUE, "Size cannot be negative.");
1345     return error::kNoError;
1346   }
1347 
1348   base::CheckedNumeric<size_t> range_start(offset);
1349   base::CheckedNumeric<size_t> range_end = offset + size;
1350   if (!range_end.IsValid() || range_end.ValueOrDefault(0) > map_info.size) {
1351     InsertError(GL_INVALID_OPERATION,
1352                 "Flush range is not within the original mapping size.");
1353     return error::kNoError;
1354   }
1355 
1356   uint8_t* mem = GetSharedMemoryAs<uint8_t*>(
1357       map_info.data_shm_id, map_info.data_shm_offset, map_info.size);
1358   if (!mem) {
1359     return error::kOutOfBounds;
1360   }
1361 
1362   memcpy(map_info.map_ptr + offset, mem + offset, size);
1363   api()->glFlushMappedBufferRangeFn(target, offset, size);
1364 
1365   return error::kNoError;
1366 }
1367 
DoFramebufferParameteri(GLenum target,GLenum pname,GLint param)1368 error::Error GLES2DecoderPassthroughImpl::DoFramebufferParameteri(GLenum target,
1369                                                                   GLenum pname,
1370                                                                   GLint param) {
1371   api()->glFramebufferParameteriFn(target, pname, param);
1372   return error::kNoError;
1373 }
1374 
DoFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)1375 error::Error GLES2DecoderPassthroughImpl::DoFramebufferRenderbuffer(
1376     GLenum target,
1377     GLenum attachment,
1378     GLenum renderbuffertarget,
1379     GLuint renderbuffer) {
1380   if (IsEmulatedFramebufferBound(target)) {
1381     InsertError(GL_INVALID_OPERATION,
1382                 "Cannot change the attachments of the default framebuffer.");
1383     return error::kNoError;
1384   }
1385   api()->glFramebufferRenderbufferEXTFn(
1386       target, attachment, renderbuffertarget,
1387       GetRenderbufferServiceID(api(), renderbuffer, resources_, false));
1388   return error::kNoError;
1389 }
1390 
DoFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)1391 error::Error GLES2DecoderPassthroughImpl::DoFramebufferTexture2D(
1392     GLenum target,
1393     GLenum attachment,
1394     GLenum textarget,
1395     GLuint texture,
1396     GLint level) {
1397   if (IsEmulatedFramebufferBound(target)) {
1398     InsertError(GL_INVALID_OPERATION,
1399                 "Cannot change the attachments of the default framebuffer.");
1400     return error::kNoError;
1401   }
1402   BindPendingImageForClientIDIfNeeded(texture);
1403   api()->glFramebufferTexture2DEXTFn(
1404       target, attachment, textarget,
1405       GetTextureServiceID(api(), texture, resources_, false), level);
1406   return error::kNoError;
1407 }
1408 
DoFramebufferTextureLayer(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)1409 error::Error GLES2DecoderPassthroughImpl::DoFramebufferTextureLayer(
1410     GLenum target,
1411     GLenum attachment,
1412     GLuint texture,
1413     GLint level,
1414     GLint layer) {
1415   if (IsEmulatedFramebufferBound(target)) {
1416     InsertError(GL_INVALID_OPERATION,
1417                 "Cannot change the attachments of the default framebuffer.");
1418     return error::kNoError;
1419   }
1420   api()->glFramebufferTextureLayerFn(
1421       target, attachment,
1422       GetTextureServiceID(api(), texture, resources_, false), level, layer);
1423   return error::kNoError;
1424 }
1425 
DoFramebufferTextureMultiviewOVR(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint base_view_index,GLsizei num_views)1426 error::Error GLES2DecoderPassthroughImpl::DoFramebufferTextureMultiviewOVR(
1427     GLenum target,
1428     GLenum attachment,
1429     GLuint texture,
1430     GLint level,
1431     GLint base_view_index,
1432     GLsizei num_views) {
1433   if (IsEmulatedFramebufferBound(target)) {
1434     InsertError(GL_INVALID_OPERATION,
1435                 "Cannot change the attachments of the default framebuffer.");
1436     return error::kNoError;
1437   }
1438   api()->glFramebufferTextureMultiviewOVRFn(
1439       target, attachment,
1440       GetTextureServiceID(api(), texture, resources_, false), level,
1441       base_view_index, num_views);
1442   return error::kNoError;
1443 }
1444 
DoFrontFace(GLenum mode)1445 error::Error GLES2DecoderPassthroughImpl::DoFrontFace(GLenum mode) {
1446   api()->glFrontFaceFn(mode);
1447   return error::kNoError;
1448 }
1449 
DoGenBuffers(GLsizei n,volatile GLuint * buffers)1450 error::Error GLES2DecoderPassthroughImpl::DoGenBuffers(
1451     GLsizei n,
1452     volatile GLuint* buffers) {
1453   return GenHelper(n, buffers, &resources_->buffer_id_map,
1454                    [this](GLsizei n, GLuint* buffers) {
1455                      api()->glGenBuffersARBFn(n, buffers);
1456                    });
1457 }
1458 
DoGenerateMipmap(GLenum target)1459 error::Error GLES2DecoderPassthroughImpl::DoGenerateMipmap(GLenum target) {
1460   api()->glGenerateMipmapEXTFn(target);
1461   return error::kNoError;
1462 }
1463 
DoGenFramebuffers(GLsizei n,volatile GLuint * framebuffers)1464 error::Error GLES2DecoderPassthroughImpl::DoGenFramebuffers(
1465     GLsizei n,
1466     volatile GLuint* framebuffers) {
1467   return GenHelper(n, framebuffers, &framebuffer_id_map_,
1468                    [this](GLsizei n, GLuint* framebuffers) {
1469                      api()->glGenFramebuffersEXTFn(n, framebuffers);
1470                    });
1471 }
1472 
DoGenRenderbuffers(GLsizei n,volatile GLuint * renderbuffers)1473 error::Error GLES2DecoderPassthroughImpl::DoGenRenderbuffers(
1474     GLsizei n,
1475     volatile GLuint* renderbuffers) {
1476   return GenHelper(n, renderbuffers, &resources_->renderbuffer_id_map,
1477                    [this](GLsizei n, GLuint* renderbuffers) {
1478                      api()->glGenRenderbuffersEXTFn(n, renderbuffers);
1479                    });
1480 }
1481 
DoGenSamplers(GLsizei n,volatile GLuint * samplers)1482 error::Error GLES2DecoderPassthroughImpl::DoGenSamplers(
1483     GLsizei n,
1484     volatile GLuint* samplers) {
1485   return GenHelper(n, samplers, &resources_->sampler_id_map,
1486                    [this](GLsizei n, GLuint* samplers) {
1487                      api()->glGenSamplersFn(n, samplers);
1488                    });
1489 }
1490 
DoGenTextures(GLsizei n,volatile GLuint * textures)1491 error::Error GLES2DecoderPassthroughImpl::DoGenTextures(
1492     GLsizei n,
1493     volatile GLuint* textures) {
1494   return GenHelper(n, textures, &resources_->texture_id_map,
1495                    [this](GLsizei n, GLuint* textures) {
1496                      api()->glGenTexturesFn(n, textures);
1497                    });
1498 }
1499 
DoGenTransformFeedbacks(GLsizei n,volatile GLuint * ids)1500 error::Error GLES2DecoderPassthroughImpl::DoGenTransformFeedbacks(
1501     GLsizei n,
1502     volatile GLuint* ids) {
1503   return GenHelper(n, ids, &transform_feedback_id_map_,
1504                    [this](GLsizei n, GLuint* transform_feedbacks) {
1505                      api()->glGenTransformFeedbacksFn(n, transform_feedbacks);
1506                    });
1507 }
1508 
DoGetActiveAttrib(GLuint program,GLuint index,GLint * size,GLenum * type,std::string * name,int32_t * success)1509 error::Error GLES2DecoderPassthroughImpl::DoGetActiveAttrib(GLuint program,
1510                                                             GLuint index,
1511                                                             GLint* size,
1512                                                             GLenum* type,
1513                                                             std::string* name,
1514                                                             int32_t* success) {
1515   CheckErrorCallbackState();
1516 
1517   GLuint service_id = GetProgramServiceID(program, resources_);
1518   GLint active_attribute_max_length = 0;
1519   api()->glGetProgramivFn(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
1520                           &active_attribute_max_length);
1521   if (CheckErrorCallbackState()) {
1522     *success = 0;
1523     return error::kNoError;
1524   }
1525 
1526   std::vector<char> name_buffer(active_attribute_max_length, 0);
1527   GLsizei length = 0;
1528   api()->glGetActiveAttribFn(service_id, index, name_buffer.size(), &length,
1529                              size, type, name_buffer.data());
1530   DCHECK(length <= active_attribute_max_length);
1531   *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
1532   *success = CheckErrorCallbackState() ? 0 : 1;
1533   return error::kNoError;
1534 }
1535 
DoGetActiveUniform(GLuint program,GLuint index,GLint * size,GLenum * type,std::string * name,int32_t * success)1536 error::Error GLES2DecoderPassthroughImpl::DoGetActiveUniform(GLuint program,
1537                                                              GLuint index,
1538                                                              GLint* size,
1539                                                              GLenum* type,
1540                                                              std::string* name,
1541                                                              int32_t* success) {
1542   CheckErrorCallbackState();
1543 
1544   GLuint service_id = GetProgramServiceID(program, resources_);
1545   GLint active_uniform_max_length = 0;
1546   api()->glGetProgramivFn(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH,
1547                           &active_uniform_max_length);
1548   if (CheckErrorCallbackState()) {
1549     *success = 0;
1550     return error::kNoError;
1551   }
1552 
1553   std::vector<char> name_buffer(active_uniform_max_length, 0);
1554   GLsizei length = 0;
1555   api()->glGetActiveUniformFn(service_id, index, name_buffer.size(), &length,
1556                               size, type, name_buffer.data());
1557   DCHECK(length <= active_uniform_max_length);
1558   *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
1559   *success = CheckErrorCallbackState() ? 0 : 1;
1560   return error::kNoError;
1561 }
1562 
DoGetActiveUniformBlockiv(GLuint program,GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1563 error::Error GLES2DecoderPassthroughImpl::DoGetActiveUniformBlockiv(
1564     GLuint program,
1565     GLuint index,
1566     GLenum pname,
1567     GLsizei bufSize,
1568     GLsizei* length,
1569     GLint* params) {
1570   api()->glGetActiveUniformBlockivRobustANGLEFn(
1571       GetProgramServiceID(program, resources_), index, pname, bufSize, length,
1572       params);
1573   return error::kNoError;
1574 }
1575 
DoGetActiveUniformBlockName(GLuint program,GLuint index,std::string * name)1576 error::Error GLES2DecoderPassthroughImpl::DoGetActiveUniformBlockName(
1577     GLuint program,
1578     GLuint index,
1579     std::string* name) {
1580   CheckErrorCallbackState();
1581 
1582   GLuint program_service_id = GetProgramServiceID(program, resources_);
1583   GLint max_name_length = 0;
1584   api()->glGetProgramivFn(program_service_id,
1585                           GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH,
1586                           &max_name_length);
1587 
1588   if (CheckErrorCallbackState()) {
1589     return error::kNoError;
1590   }
1591 
1592   std::vector<GLchar> buffer(max_name_length, 0);
1593   GLsizei length = 0;
1594   api()->glGetActiveUniformBlockNameFn(program_service_id, index,
1595                                        max_name_length, &length, buffer.data());
1596   DCHECK(length <= max_name_length);
1597   *name = length > 0 ? std::string(buffer.data(), length) : std::string();
1598 
1599   return error::kNoError;
1600 }
1601 
DoGetActiveUniformsiv(GLuint program,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)1602 error::Error GLES2DecoderPassthroughImpl::DoGetActiveUniformsiv(
1603     GLuint program,
1604     GLsizei count,
1605     const GLuint* indices,
1606     GLenum pname,
1607     GLint* params) {
1608   api()->glGetActiveUniformsivFn(GetProgramServiceID(program, resources_),
1609                                  count, indices, pname, params);
1610   return error::kNoError;
1611 }
1612 
DoGetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)1613 error::Error GLES2DecoderPassthroughImpl::DoGetAttachedShaders(
1614     GLuint program,
1615     GLsizei maxcount,
1616     GLsizei* count,
1617     GLuint* shaders) {
1618   api()->glGetAttachedShadersFn(GetProgramServiceID(program, resources_),
1619                                 maxcount, count, shaders);
1620   return error::kNoError;
1621 }
1622 
DoGetAttribLocation(GLuint program,const char * name,GLint * result)1623 error::Error GLES2DecoderPassthroughImpl::DoGetAttribLocation(GLuint program,
1624                                                               const char* name,
1625                                                               GLint* result) {
1626   *result = api()->glGetAttribLocationFn(
1627       GetProgramServiceID(program, resources_), name);
1628   return error::kNoError;
1629 }
1630 
DoGetBooleanv(GLenum pname,GLsizei bufsize,GLsizei * length,GLboolean * params)1631 error::Error GLES2DecoderPassthroughImpl::DoGetBooleanv(GLenum pname,
1632                                                         GLsizei bufsize,
1633                                                         GLsizei* length,
1634                                                         GLboolean* params) {
1635   return GetNumericHelper(pname, bufsize, length, params,
1636                           [this](GLenum pname, GLsizei bufsize, GLsizei* length,
1637                                  GLboolean* params) {
1638                             api()->glGetBooleanvRobustANGLEFn(pname, bufsize,
1639                                                               length, params);
1640                           });
1641 }
1642 
DoGetBooleani_v(GLenum pname,GLuint index,GLsizei bufsize,GLsizei * length,GLboolean * data)1643 error::Error GLES2DecoderPassthroughImpl::DoGetBooleani_v(GLenum pname,
1644                                                           GLuint index,
1645                                                           GLsizei bufsize,
1646                                                           GLsizei* length,
1647                                                           GLboolean* data) {
1648   glGetBooleani_vRobustANGLE(pname, index, bufsize, length, data);
1649   return error::kNoError;
1650 }
1651 
DoGetBufferParameteri64v(GLenum target,GLenum pname,GLsizei bufsize,GLsizei * length,GLint64 * params)1652 error::Error GLES2DecoderPassthroughImpl::DoGetBufferParameteri64v(
1653     GLenum target,
1654     GLenum pname,
1655     GLsizei bufsize,
1656     GLsizei* length,
1657     GLint64* params) {
1658   CheckErrorCallbackState();
1659   api()->glGetBufferParameteri64vRobustANGLEFn(target, pname, bufsize, length,
1660                                                params);
1661   if (CheckErrorCallbackState()) {
1662     return error::kNoError;
1663   }
1664   PatchGetBufferResults(target, pname, bufsize, length, params);
1665   return error::kNoError;
1666 }
1667 
DoGetBufferParameteriv(GLenum target,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1668 error::Error GLES2DecoderPassthroughImpl::DoGetBufferParameteriv(
1669     GLenum target,
1670     GLenum pname,
1671     GLsizei bufsize,
1672     GLsizei* length,
1673     GLint* params) {
1674   CheckErrorCallbackState();
1675   api()->glGetBufferParameterivRobustANGLEFn(target, pname, bufsize, length,
1676                                              params);
1677   if (CheckErrorCallbackState()) {
1678     return error::kNoError;
1679   }
1680   PatchGetBufferResults(target, pname, bufsize, length, params);
1681   return error::kNoError;
1682 }
1683 
DoGetError(uint32_t * result)1684 error::Error GLES2DecoderPassthroughImpl::DoGetError(uint32_t* result) {
1685   FlushErrors();
1686   *result = PopError();
1687   return error::kNoError;
1688 }
1689 
DoGetFloatv(GLenum pname,GLsizei bufsize,GLsizei * length,GLfloat * params)1690 error::Error GLES2DecoderPassthroughImpl::DoGetFloatv(GLenum pname,
1691                                                       GLsizei bufsize,
1692                                                       GLsizei* length,
1693                                                       GLfloat* params) {
1694   return GetNumericHelper(
1695       pname, bufsize, length, params,
1696       [this](GLenum pname, GLsizei bufsize, GLsizei* length, GLfloat* params) {
1697         api()->glGetFloatvRobustANGLEFn(pname, bufsize, length, params);
1698       });
1699 }
1700 
DoGetFragDataLocation(GLuint program,const char * name,GLint * result)1701 error::Error GLES2DecoderPassthroughImpl::DoGetFragDataLocation(
1702     GLuint program,
1703     const char* name,
1704     GLint* result) {
1705   *result = api()->glGetFragDataLocationFn(
1706       GetProgramServiceID(program, resources_), name);
1707   return error::kNoError;
1708 }
1709 
DoGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1710 error::Error GLES2DecoderPassthroughImpl::DoGetFramebufferAttachmentParameteriv(
1711     GLenum target,
1712     GLenum attachment,
1713     GLenum pname,
1714     GLsizei bufsize,
1715     GLsizei* length,
1716     GLint* params) {
1717   GLenum updated_attachment = attachment;
1718   if (IsEmulatedFramebufferBound(target)) {
1719     // Update the attachment do the equivalent one in the emulated framebuffer
1720     if (!ModifyAttachmentForEmulatedFramebuffer(&updated_attachment)) {
1721       InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
1722       *length = 0;
1723       return error::kNoError;
1724     }
1725 
1726     // Generate errors for parameter names that are only valid for non-default
1727     // framebuffers
1728     switch (pname) {
1729       case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1730       case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1731       case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1732       case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
1733         InsertError(GL_INVALID_ENUM, "Invalid parameter name.");
1734         *length = 0;
1735         return error::kNoError;
1736     }
1737   }
1738 
1739   CheckErrorCallbackState();
1740 
1741   api()->glGetFramebufferAttachmentParameterivRobustANGLEFn(
1742       target, updated_attachment, pname, bufsize, length, params);
1743 
1744   if (CheckErrorCallbackState()) {
1745     DCHECK(*length == 0);
1746     return error::kNoError;
1747   }
1748 
1749   // Update the results of the query, if needed
1750   const error::Error error = PatchGetFramebufferAttachmentParameter(
1751       target, updated_attachment, pname, *length, params);
1752   if (error != error::kNoError) {
1753     *length = 0;
1754     return error;
1755   }
1756 
1757   return error::kNoError;
1758 }
1759 
DoGetInteger64v(GLenum pname,GLsizei bufsize,GLsizei * length,GLint64 * params)1760 error::Error GLES2DecoderPassthroughImpl::DoGetInteger64v(GLenum pname,
1761                                                           GLsizei bufsize,
1762                                                           GLsizei* length,
1763                                                           GLint64* params) {
1764   return GetNumericHelper(
1765       pname, bufsize, length, params,
1766       [this](GLenum pname, GLsizei bufsize, GLsizei* length, GLint64* params) {
1767         api()->glGetInteger64vRobustANGLEFn(pname, bufsize, length, params);
1768       });
1769 }
1770 
DoGetIntegeri_v(GLenum pname,GLuint index,GLsizei bufsize,GLsizei * length,GLint * data)1771 error::Error GLES2DecoderPassthroughImpl::DoGetIntegeri_v(GLenum pname,
1772                                                           GLuint index,
1773                                                           GLsizei bufsize,
1774                                                           GLsizei* length,
1775                                                           GLint* data) {
1776   glGetIntegeri_vRobustANGLE(pname, index, bufsize, length, data);
1777   return error::kNoError;
1778 }
1779 
DoGetInteger64i_v(GLenum pname,GLuint index,GLsizei bufsize,GLsizei * length,GLint64 * data)1780 error::Error GLES2DecoderPassthroughImpl::DoGetInteger64i_v(GLenum pname,
1781                                                             GLuint index,
1782                                                             GLsizei bufsize,
1783                                                             GLsizei* length,
1784                                                             GLint64* data) {
1785   glGetInteger64i_vRobustANGLE(pname, index, bufsize, length, data);
1786   return error::kNoError;
1787 }
1788 
DoGetIntegerv(GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1789 error::Error GLES2DecoderPassthroughImpl::DoGetIntegerv(GLenum pname,
1790                                                         GLsizei bufsize,
1791                                                         GLsizei* length,
1792                                                         GLint* params) {
1793   return GetNumericHelper(
1794       pname, bufsize, length, params,
1795       [this](GLenum pname, GLsizei bufsize, GLsizei* length, GLint* params) {
1796         api()->glGetIntegervRobustANGLEFn(pname, bufsize, length, params);
1797       });
1798 }
1799 
DoGetInternalformativ(GLenum target,GLenum format,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1800 error::Error GLES2DecoderPassthroughImpl::DoGetInternalformativ(GLenum target,
1801                                                                 GLenum format,
1802                                                                 GLenum pname,
1803                                                                 GLsizei bufSize,
1804                                                                 GLsizei* length,
1805                                                                 GLint* params) {
1806   api()->glGetInternalformativRobustANGLEFn(target, format, pname, bufSize,
1807                                             length, params);
1808   return error::kNoError;
1809 }
1810 
DoGetProgramiv(GLuint program,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1811 error::Error GLES2DecoderPassthroughImpl::DoGetProgramiv(GLuint program,
1812                                                          GLenum pname,
1813                                                          GLsizei bufsize,
1814                                                          GLsizei* length,
1815                                                          GLint* params) {
1816   api()->glGetProgramivRobustANGLEFn(GetProgramServiceID(program, resources_),
1817                                      pname, bufsize, length, params);
1818   return error::kNoError;
1819 }
1820 
DoGetProgramInfoLog(GLuint program,std::string * infolog)1821 error::Error GLES2DecoderPassthroughImpl::DoGetProgramInfoLog(
1822     GLuint program,
1823     std::string* infolog) {
1824   CheckErrorCallbackState();
1825   GLint info_log_len = 0;
1826   api()->glGetProgramivFn(GetProgramServiceID(program, resources_),
1827                           GL_INFO_LOG_LENGTH, &info_log_len);
1828 
1829   if (CheckErrorCallbackState()) {
1830     return error::kNoError;
1831   }
1832 
1833   std::vector<char> buffer(info_log_len, 0);
1834   GLsizei length = 0;
1835   api()->glGetProgramInfoLogFn(GetProgramServiceID(program, resources_),
1836                                info_log_len, &length, buffer.data());
1837   DCHECK(length <= info_log_len);
1838   *infolog = length > 0 ? std::string(buffer.data(), length) : std::string();
1839   return error::kNoError;
1840 }
1841 
DoGetProgramInterfaceiv(GLuint program,GLenum program_interface,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1842 error::Error GLES2DecoderPassthroughImpl::DoGetProgramInterfaceiv(
1843     GLuint program,
1844     GLenum program_interface,
1845     GLenum pname,
1846     GLsizei bufsize,
1847     GLsizei* length,
1848     GLint* params) {
1849   // glGetProgramInterfaceivRobustANGLE remains to be implemented in ANGLE.
1850   if (bufsize < 1) {
1851     return error::kOutOfBounds;
1852   }
1853   *length = 1;
1854   api()->glGetProgramInterfaceivFn(GetProgramServiceID(program, resources_),
1855                                    program_interface, pname, params);
1856   return error::kNoError;
1857 }
1858 
DoGetProgramResourceiv(GLuint program,GLenum program_interface,GLuint index,GLsizei prop_count,const GLenum * props,GLsizei bufsize,GLsizei * length,GLint * params)1859 error::Error GLES2DecoderPassthroughImpl::DoGetProgramResourceiv(
1860     GLuint program,
1861     GLenum program_interface,
1862     GLuint index,
1863     GLsizei prop_count,
1864     const GLenum* props,
1865     GLsizei bufsize,
1866     GLsizei* length,
1867     GLint* params) {
1868   api()->glGetProgramResourceivFn(GetProgramServiceID(program, resources_),
1869                                   program_interface, index, prop_count, props,
1870                                   bufsize, length, params);
1871   return error::kNoError;
1872 }
1873 
DoGetProgramResourceIndex(GLuint program,GLenum program_interface,const char * name,GLuint * index)1874 error::Error GLES2DecoderPassthroughImpl::DoGetProgramResourceIndex(
1875     GLuint program,
1876     GLenum program_interface,
1877     const char* name,
1878     GLuint* index) {
1879   *index = api()->glGetProgramResourceIndexFn(
1880       GetProgramServiceID(program, resources_), program_interface, name);
1881   return error::kNoError;
1882 }
1883 
DoGetProgramResourceLocation(GLuint program,GLenum program_interface,const char * name,GLint * location)1884 error::Error GLES2DecoderPassthroughImpl::DoGetProgramResourceLocation(
1885     GLuint program,
1886     GLenum program_interface,
1887     const char* name,
1888     GLint* location) {
1889   *location = api()->glGetProgramResourceLocationFn(
1890       GetProgramServiceID(program, resources_), program_interface, name);
1891   return error::kNoError;
1892 }
1893 
DoGetProgramResourceName(GLuint program,GLenum program_interface,GLuint index,std::string * name)1894 error::Error GLES2DecoderPassthroughImpl::DoGetProgramResourceName(
1895     GLuint program,
1896     GLenum program_interface,
1897     GLuint index,
1898     std::string* name) {
1899   CheckErrorCallbackState();
1900 
1901   GLuint service_id = GetProgramServiceID(program, resources_);
1902   GLint max_name_length = 0;
1903   api()->glGetProgramInterfaceivFn(service_id, program_interface,
1904                                    GL_MAX_NAME_LENGTH, &max_name_length);
1905   if (CheckErrorCallbackState()) {
1906     return error::kNoError;
1907   }
1908 
1909   std::vector<GLchar> buffer(max_name_length, 0);
1910   GLsizei length = 0;
1911   api()->glGetProgramResourceNameFn(service_id, program_interface, index,
1912                                     max_name_length, &length, buffer.data());
1913   DCHECK_LE(length, max_name_length);
1914   *name = length > 0 ? std::string(buffer.data(), length) : std::string();
1915   return error::kNoError;
1916 }
1917 
DoGetRenderbufferParameteriv(GLenum target,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1918 error::Error GLES2DecoderPassthroughImpl::DoGetRenderbufferParameteriv(
1919     GLenum target,
1920     GLenum pname,
1921     GLsizei bufsize,
1922     GLsizei* length,
1923     GLint* params) {
1924   api()->glGetRenderbufferParameterivRobustANGLEFn(target, pname, bufsize,
1925                                                    length, params);
1926   return error::kNoError;
1927 }
1928 
DoGetSamplerParameterfv(GLuint sampler,GLenum pname,GLsizei bufsize,GLsizei * length,GLfloat * params)1929 error::Error GLES2DecoderPassthroughImpl::DoGetSamplerParameterfv(
1930     GLuint sampler,
1931     GLenum pname,
1932     GLsizei bufsize,
1933     GLsizei* length,
1934     GLfloat* params) {
1935   api()->glGetSamplerParameterfvRobustANGLEFn(
1936       GetSamplerServiceID(sampler, resources_), pname, bufsize, length, params);
1937   return error::kNoError;
1938 }
1939 
DoGetSamplerParameteriv(GLuint sampler,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1940 error::Error GLES2DecoderPassthroughImpl::DoGetSamplerParameteriv(
1941     GLuint sampler,
1942     GLenum pname,
1943     GLsizei bufsize,
1944     GLsizei* length,
1945     GLint* params) {
1946   api()->glGetSamplerParameterivRobustANGLEFn(
1947       GetSamplerServiceID(sampler, resources_), pname, bufsize, length, params);
1948   return error::kNoError;
1949 }
1950 
DoGetShaderiv(GLuint shader,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)1951 error::Error GLES2DecoderPassthroughImpl::DoGetShaderiv(GLuint shader,
1952                                                         GLenum pname,
1953                                                         GLsizei bufsize,
1954                                                         GLsizei* length,
1955                                                         GLint* params) {
1956   api()->glGetShaderivRobustANGLEFn(GetShaderServiceID(shader, resources_),
1957                                     pname, bufsize, length, params);
1958   return error::kNoError;
1959 }
1960 
DoGetShaderInfoLog(GLuint shader,std::string * infolog)1961 error::Error GLES2DecoderPassthroughImpl::DoGetShaderInfoLog(
1962     GLuint shader,
1963     std::string* infolog) {
1964   CheckErrorCallbackState();
1965 
1966   GLuint service_id = GetShaderServiceID(shader, resources_);
1967   GLint info_log_len = 0;
1968   api()->glGetShaderivFn(service_id, GL_INFO_LOG_LENGTH, &info_log_len);
1969   if (CheckErrorCallbackState()) {
1970     return error::kNoError;
1971   }
1972 
1973   std::vector<char> buffer(info_log_len, 0);
1974   GLsizei length = 0;
1975   api()->glGetShaderInfoLogFn(service_id, info_log_len, &length, buffer.data());
1976   DCHECK(length <= info_log_len);
1977   *infolog = length > 0 ? std::string(buffer.data(), length) : std::string();
1978   return error::kNoError;
1979 }
1980 
DoGetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision,int32_t * success)1981 error::Error GLES2DecoderPassthroughImpl::DoGetShaderPrecisionFormat(
1982     GLenum shadertype,
1983     GLenum precisiontype,
1984     GLint* range,
1985     GLint* precision,
1986     int32_t* success) {
1987   CheckErrorCallbackState();
1988   api()->glGetShaderPrecisionFormatFn(shadertype, precisiontype, range,
1989                                       precision);
1990   *success = CheckErrorCallbackState() ? 0 : 1;
1991   return error::kNoError;
1992 }
1993 
DoGetShaderSource(GLuint shader,std::string * source)1994 error::Error GLES2DecoderPassthroughImpl::DoGetShaderSource(
1995     GLuint shader,
1996     std::string* source) {
1997   CheckErrorCallbackState();
1998 
1999   GLuint shader_service_id = GetShaderServiceID(shader, resources_);
2000   GLint shader_source_length = 0;
2001   api()->glGetShaderivFn(shader_service_id, GL_SHADER_SOURCE_LENGTH,
2002                          &shader_source_length);
2003   if (CheckErrorCallbackState()) {
2004     return error::kNoError;
2005   }
2006 
2007   std::vector<char> buffer(shader_source_length, 0);
2008   GLsizei length = 0;
2009   api()->glGetShaderSourceFn(shader_service_id, shader_source_length, &length,
2010                              buffer.data());
2011   DCHECK(length <= shader_source_length);
2012   *source = shader_source_length > 0 ? std::string(buffer.data(), length)
2013                                      : std::string();
2014   return error::kNoError;
2015 }
2016 
DoGetString(GLenum name,uint32_t bucket_id)2017 error::Error GLES2DecoderPassthroughImpl::DoGetString(GLenum name,
2018                                                       uint32_t bucket_id) {
2019   std::string extensions;
2020   const char* str = nullptr;
2021 
2022   switch (name) {
2023     case GL_VERSION:
2024       str = GetServiceVersionString(feature_info_.get());
2025       break;
2026     case GL_SHADING_LANGUAGE_VERSION:
2027       str = GetServiceShadingLanguageVersionString(feature_info_.get());
2028       break;
2029     case GL_EXTENSIONS: {
2030       extensions = gfx::MakeExtensionString(feature_info_->extensions());
2031       str = extensions.c_str();
2032       break;
2033     }
2034     default:
2035       str = reinterpret_cast<const char*>(api()->glGetStringFn(name));
2036       break;
2037   }
2038 
2039   Bucket* bucket = CreateBucket(bucket_id);
2040   bucket->SetFromString(str);
2041   return error::kNoError;
2042 }
2043 
DoGetSynciv(GLuint sync,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * values)2044 error::Error GLES2DecoderPassthroughImpl::DoGetSynciv(GLuint sync,
2045                                                       GLenum pname,
2046                                                       GLsizei bufsize,
2047                                                       GLsizei* length,
2048                                                       GLint* values) {
2049   api()->glGetSyncivFn(GetSyncServiceID(sync, resources_), pname, bufsize,
2050                        length, values);
2051   return error::kNoError;
2052 }
2053 
DoGetTexParameterfv(GLenum target,GLenum pname,GLsizei bufsize,GLsizei * length,GLfloat * params)2054 error::Error GLES2DecoderPassthroughImpl::DoGetTexParameterfv(GLenum target,
2055                                                               GLenum pname,
2056                                                               GLsizei bufsize,
2057                                                               GLsizei* length,
2058                                                               GLfloat* params) {
2059   api()->glGetTexParameterfvRobustANGLEFn(target, pname, bufsize, length,
2060                                           params);
2061   return error::kNoError;
2062 }
2063 
DoGetTexParameteriv(GLenum target,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)2064 error::Error GLES2DecoderPassthroughImpl::DoGetTexParameteriv(GLenum target,
2065                                                               GLenum pname,
2066                                                               GLsizei bufsize,
2067                                                               GLsizei* length,
2068                                                               GLint* params) {
2069   api()->glGetTexParameterivRobustANGLEFn(target, pname, bufsize, length,
2070                                           params);
2071   return error::kNoError;
2072 }
2073 
DoGetTransformFeedbackVarying(GLuint program,GLuint index,GLsizei * size,GLenum * type,std::string * name,int32_t * success)2074 error::Error GLES2DecoderPassthroughImpl::DoGetTransformFeedbackVarying(
2075     GLuint program,
2076     GLuint index,
2077     GLsizei* size,
2078     GLenum* type,
2079     std::string* name,
2080     int32_t* success) {
2081   CheckErrorCallbackState();
2082 
2083   GLuint service_id = GetProgramServiceID(program, resources_);
2084   GLint transform_feedback_varying_max_length = 0;
2085   api()->glGetProgramivFn(service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH,
2086                           &transform_feedback_varying_max_length);
2087   if (CheckErrorCallbackState()) {
2088     *success = 0;
2089     return error::kNoError;
2090   }
2091 
2092   std::vector<char> name_buffer(transform_feedback_varying_max_length, 0);
2093   GLsizei length = 0;
2094   api()->glGetTransformFeedbackVaryingFn(service_id, index, name_buffer.size(),
2095                                          &length, size, type,
2096                                          name_buffer.data());
2097   DCHECK(length <= transform_feedback_varying_max_length);
2098   *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
2099   *success = CheckErrorCallbackState() ? 0 : 1;
2100   return error::kNoError;
2101 }
2102 
DoGetUniformBlockIndex(GLuint program,const char * name,GLint * index)2103 error::Error GLES2DecoderPassthroughImpl::DoGetUniformBlockIndex(
2104     GLuint program,
2105     const char* name,
2106     GLint* index) {
2107   *index = api()->glGetUniformBlockIndexFn(
2108       GetProgramServiceID(program, resources_), name);
2109   return error::kNoError;
2110 }
2111 
DoGetUniformfv(GLuint program,GLint location,GLsizei bufsize,GLsizei * length,GLfloat * params)2112 error::Error GLES2DecoderPassthroughImpl::DoGetUniformfv(GLuint program,
2113                                                          GLint location,
2114                                                          GLsizei bufsize,
2115                                                          GLsizei* length,
2116                                                          GLfloat* params) {
2117   // GetUniform*RobustANGLE entry points expect bufsize in bytes like the entry
2118   // points in GL_EXT_robustness
2119   api()->glGetUniformfvRobustANGLEFn(GetProgramServiceID(program, resources_),
2120                                      location, bufsize * sizeof(*params),
2121                                      length, params);
2122   return error::kNoError;
2123 }
2124 
DoGetUniformiv(GLuint program,GLint location,GLsizei bufsize,GLsizei * length,GLint * params)2125 error::Error GLES2DecoderPassthroughImpl::DoGetUniformiv(GLuint program,
2126                                                          GLint location,
2127                                                          GLsizei bufsize,
2128                                                          GLsizei* length,
2129                                                          GLint* params) {
2130   // GetUniform*RobustANGLE entry points expect bufsize in bytes like the entry
2131   // points in GL_EXT_robustness
2132   api()->glGetUniformivRobustANGLEFn(GetProgramServiceID(program, resources_),
2133                                      location, bufsize * sizeof(*params),
2134                                      length, params);
2135   return error::kNoError;
2136 }
2137 
DoGetUniformuiv(GLuint program,GLint location,GLsizei bufsize,GLsizei * length,GLuint * params)2138 error::Error GLES2DecoderPassthroughImpl::DoGetUniformuiv(GLuint program,
2139                                                           GLint location,
2140                                                           GLsizei bufsize,
2141                                                           GLsizei* length,
2142                                                           GLuint* params) {
2143   // GetUniform*RobustANGLE entry points expect bufsize in bytes like the entry
2144   // points in GL_EXT_robustness
2145   api()->glGetUniformuivRobustANGLEFn(GetProgramServiceID(program, resources_),
2146                                       location, bufsize * sizeof(*params),
2147                                       length, params);
2148   return error::kNoError;
2149 }
2150 
DoGetUniformIndices(GLuint program,GLsizei count,const char * const * names,GLsizei bufSize,GLuint * indices)2151 error::Error GLES2DecoderPassthroughImpl::DoGetUniformIndices(
2152     GLuint program,
2153     GLsizei count,
2154     const char* const* names,
2155     GLsizei bufSize,
2156     GLuint* indices) {
2157   api()->glGetUniformIndicesFn(GetProgramServiceID(program, resources_), count,
2158                                names, indices);
2159   return error::kNoError;
2160 }
2161 
DoGetUniformLocation(GLuint program,const char * name,GLint * location)2162 error::Error GLES2DecoderPassthroughImpl::DoGetUniformLocation(
2163     GLuint program,
2164     const char* name,
2165     GLint* location) {
2166   *location = api()->glGetUniformLocationFn(
2167       GetProgramServiceID(program, resources_), name);
2168   return error::kNoError;
2169 }
2170 
DoGetVertexAttribfv(GLuint index,GLenum pname,GLsizei bufsize,GLsizei * length,GLfloat * params)2171 error::Error GLES2DecoderPassthroughImpl::DoGetVertexAttribfv(GLuint index,
2172                                                               GLenum pname,
2173                                                               GLsizei bufsize,
2174                                                               GLsizei* length,
2175                                                               GLfloat* params) {
2176   api()->glGetVertexAttribfvRobustANGLEFn(index, pname, bufsize, length,
2177                                           params);
2178   return error::kNoError;
2179 }
2180 
DoGetVertexAttribiv(GLuint index,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)2181 error::Error GLES2DecoderPassthroughImpl::DoGetVertexAttribiv(GLuint index,
2182                                                               GLenum pname,
2183                                                               GLsizei bufsize,
2184                                                               GLsizei* length,
2185                                                               GLint* params) {
2186   api()->glGetVertexAttribivRobustANGLEFn(index, pname, bufsize, length,
2187                                           params);
2188   return error::kNoError;
2189 }
2190 
DoGetVertexAttribIiv(GLuint index,GLenum pname,GLsizei bufsize,GLsizei * length,GLint * params)2191 error::Error GLES2DecoderPassthroughImpl::DoGetVertexAttribIiv(GLuint index,
2192                                                                GLenum pname,
2193                                                                GLsizei bufsize,
2194                                                                GLsizei* length,
2195                                                                GLint* params) {
2196   api()->glGetVertexAttribIivRobustANGLEFn(index, pname, bufsize, length,
2197                                            params);
2198   return error::kNoError;
2199 }
2200 
DoGetVertexAttribIuiv(GLuint index,GLenum pname,GLsizei bufsize,GLsizei * length,GLuint * params)2201 error::Error GLES2DecoderPassthroughImpl::DoGetVertexAttribIuiv(
2202     GLuint index,
2203     GLenum pname,
2204     GLsizei bufsize,
2205     GLsizei* length,
2206     GLuint* params) {
2207   api()->glGetVertexAttribIuivRobustANGLEFn(index, pname, bufsize, length,
2208                                             params);
2209   return error::kNoError;
2210 }
2211 
DoGetVertexAttribPointerv(GLuint index,GLenum pname,GLsizei bufsize,GLsizei * length,GLuint * pointer)2212 error::Error GLES2DecoderPassthroughImpl::DoGetVertexAttribPointerv(
2213     GLuint index,
2214     GLenum pname,
2215     GLsizei bufsize,
2216     GLsizei* length,
2217     GLuint* pointer) {
2218   std::array<void*, 1> temp_pointers{{nullptr}};
2219   GLsizei temp_length = 0;
2220   api()->glGetVertexAttribPointervRobustANGLEFn(
2221       index, pname, static_cast<GLsizei>(temp_pointers.size()), &temp_length,
2222       temp_pointers.data());
2223   DCHECK(temp_length >= 0 &&
2224          temp_length <= static_cast<GLsizei>(temp_pointers.size()) &&
2225          temp_length <= bufsize);
2226   for (GLsizei ii = 0; ii < temp_length; ii++) {
2227     pointer[ii] =
2228         static_cast<GLuint>(reinterpret_cast<uintptr_t>(temp_pointers[ii]));
2229   }
2230   *length = temp_length;
2231   return error::kNoError;
2232 }
2233 
DoHint(GLenum target,GLenum mode)2234 error::Error GLES2DecoderPassthroughImpl::DoHint(GLenum target, GLenum mode) {
2235   api()->glHintFn(target, mode);
2236   return error::kNoError;
2237 }
2238 
DoInvalidateFramebuffer(GLenum target,GLsizei count,const volatile GLenum * attachments)2239 error::Error GLES2DecoderPassthroughImpl::DoInvalidateFramebuffer(
2240     GLenum target,
2241     GLsizei count,
2242     const volatile GLenum* attachments) {
2243   // Validate that count is non-negative before allocating a vector
2244   if (count < 0) {
2245     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
2246     return error::kNoError;
2247   }
2248 
2249   std::vector<GLenum> attachments_copy(attachments, attachments + count);
2250   if (IsEmulatedFramebufferBound(target)) {
2251     // Update the attachment do the equivalent one in the emulated framebuffer
2252     if (!ModifyAttachmentsForEmulatedFramebuffer(&attachments_copy)) {
2253       InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
2254       return error::kNoError;
2255     }
2256   }
2257   api()->glInvalidateFramebufferFn(target, count, attachments_copy.data());
2258   return error::kNoError;
2259 }
2260 
DoInvalidateSubFramebuffer(GLenum target,GLsizei count,const volatile GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)2261 error::Error GLES2DecoderPassthroughImpl::DoInvalidateSubFramebuffer(
2262     GLenum target,
2263     GLsizei count,
2264     const volatile GLenum* attachments,
2265     GLint x,
2266     GLint y,
2267     GLsizei width,
2268     GLsizei height) {
2269   // Validate that count is non-negative before allocating a vector
2270   if (count < 0) {
2271     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
2272     return error::kNoError;
2273   }
2274 
2275   std::vector<GLenum> attachments_copy(attachments, attachments + count);
2276   if (IsEmulatedFramebufferBound(target)) {
2277     // Update the attachment do the equivalent one in the emulated framebuffer
2278     if (!ModifyAttachmentsForEmulatedFramebuffer(&attachments_copy)) {
2279       InsertError(GL_INVALID_OPERATION, "Invalid attachment.");
2280       return error::kNoError;
2281     }
2282   }
2283   api()->glInvalidateSubFramebufferFn(target, count, attachments_copy.data(), x,
2284                                       y, width, height);
2285   return error::kNoError;
2286 }
2287 
DoIsBuffer(GLuint buffer,uint32_t * result)2288 error::Error GLES2DecoderPassthroughImpl::DoIsBuffer(GLuint buffer,
2289                                                      uint32_t* result) {
2290   *result =
2291       api()->glIsBufferFn(GetBufferServiceID(api(), buffer, resources_, false));
2292   return error::kNoError;
2293 }
2294 
DoIsEnabled(GLenum cap,uint32_t * result)2295 error::Error GLES2DecoderPassthroughImpl::DoIsEnabled(GLenum cap,
2296                                                       uint32_t* result) {
2297   *result = api()->glIsEnabledFn(cap);
2298   return error::kNoError;
2299 }
2300 
DoIsEnablediOES(GLenum target,GLuint index,uint32_t * result)2301 error::Error GLES2DecoderPassthroughImpl::DoIsEnablediOES(GLenum target,
2302                                                           GLuint index,
2303                                                           uint32_t* result) {
2304   *result = api()->glIsEnablediOESFn(target, index);
2305   return error::kNoError;
2306 }
2307 
DoIsFramebuffer(GLuint framebuffer,uint32_t * result)2308 error::Error GLES2DecoderPassthroughImpl::DoIsFramebuffer(GLuint framebuffer,
2309                                                           uint32_t* result) {
2310   *result = api()->glIsFramebufferEXTFn(
2311       GetFramebufferServiceID(api(), framebuffer, &framebuffer_id_map_, false));
2312   return error::kNoError;
2313 }
2314 
DoIsProgram(GLuint program,uint32_t * result)2315 error::Error GLES2DecoderPassthroughImpl::DoIsProgram(GLuint program,
2316                                                       uint32_t* result) {
2317   *result = api()->glIsProgramFn(GetProgramServiceID(program, resources_));
2318   return error::kNoError;
2319 }
2320 
DoIsRenderbuffer(GLuint renderbuffer,uint32_t * result)2321 error::Error GLES2DecoderPassthroughImpl::DoIsRenderbuffer(GLuint renderbuffer,
2322                                                            uint32_t* result) {
2323   *result = api()->glIsRenderbufferEXTFn(
2324       GetRenderbufferServiceID(api(), renderbuffer, resources_, false));
2325   return error::kNoError;
2326 }
2327 
DoIsSampler(GLuint sampler,uint32_t * result)2328 error::Error GLES2DecoderPassthroughImpl::DoIsSampler(GLuint sampler,
2329                                                       uint32_t* result) {
2330   *result = api()->glIsSamplerFn(GetSamplerServiceID(sampler, resources_));
2331   return error::kNoError;
2332 }
2333 
DoIsShader(GLuint shader,uint32_t * result)2334 error::Error GLES2DecoderPassthroughImpl::DoIsShader(GLuint shader,
2335                                                      uint32_t* result) {
2336   *result = api()->glIsShaderFn(GetShaderServiceID(shader, resources_));
2337   return error::kNoError;
2338 }
2339 
DoIsSync(GLuint sync,uint32_t * result)2340 error::Error GLES2DecoderPassthroughImpl::DoIsSync(GLuint sync,
2341                                                    uint32_t* result) {
2342   *result = api()->glIsSyncFn(GetSyncServiceID(sync, resources_));
2343   return error::kNoError;
2344 }
2345 
DoIsTexture(GLuint texture,uint32_t * result)2346 error::Error GLES2DecoderPassthroughImpl::DoIsTexture(GLuint texture,
2347                                                       uint32_t* result) {
2348   *result = api()->glIsTextureFn(
2349       GetTextureServiceID(api(), texture, resources_, false));
2350   return error::kNoError;
2351 }
2352 
DoIsTransformFeedback(GLuint transformfeedback,uint32_t * result)2353 error::Error GLES2DecoderPassthroughImpl::DoIsTransformFeedback(
2354     GLuint transformfeedback,
2355     uint32_t* result) {
2356   *result = api()->glIsTransformFeedbackFn(GetTransformFeedbackServiceID(
2357       transformfeedback, &transform_feedback_id_map_));
2358   return error::kNoError;
2359 }
2360 
DoLineWidth(GLfloat width)2361 error::Error GLES2DecoderPassthroughImpl::DoLineWidth(GLfloat width) {
2362   api()->glLineWidthFn(width);
2363   return error::kNoError;
2364 }
2365 
DoLinkProgram(GLuint program)2366 error::Error GLES2DecoderPassthroughImpl::DoLinkProgram(GLuint program) {
2367   TRACE_EVENT0("gpu", "GLES2DecoderPassthroughImpl::DoLinkProgram");
2368   SCOPED_UMA_HISTOGRAM_TIMER("GPU.PassthroughDoLinkProgramTime");
2369   GLuint program_service_id = GetProgramServiceID(program, resources_);
2370   api()->glLinkProgramFn(program_service_id);
2371 
2372   // Program linking can be very slow.  Exit command processing to allow for
2373   // context preemption and GPU watchdog checks.
2374   ExitCommandProcessingEarly();
2375 
2376   linking_program_service_id_ = program_service_id;
2377 
2378   return error::kNoError;
2379 }
2380 
DoMemoryBarrierEXT(GLbitfield barriers)2381 error::Error GLES2DecoderPassthroughImpl::DoMemoryBarrierEXT(
2382     GLbitfield barriers) {
2383   api()->glMemoryBarrierEXTFn(barriers);
2384   return error::kNoError;
2385 }
2386 
DoMemoryBarrierByRegion(GLbitfield barriers)2387 error::Error GLES2DecoderPassthroughImpl::DoMemoryBarrierByRegion(
2388     GLbitfield barriers) {
2389   api()->glMemoryBarrierByRegionFn(barriers);
2390   return error::kNoError;
2391 }
2392 
DoMultiDrawBeginCHROMIUM(GLsizei drawcount)2393 error::Error GLES2DecoderPassthroughImpl::DoMultiDrawBeginCHROMIUM(
2394     GLsizei drawcount) {
2395   if (drawcount < 0) {
2396     InsertError(GL_INVALID_VALUE, "drawcount cannot be negative.");
2397     return error::kNoError;
2398   }
2399 
2400   if (!multi_draw_manager_->Begin(drawcount)) {
2401     return error::kInvalidArguments;
2402   }
2403   return error::kNoError;
2404 }
2405 
DoMultiDrawEndCHROMIUM()2406 error::Error GLES2DecoderPassthroughImpl::DoMultiDrawEndCHROMIUM() {
2407   MultiDrawManager::ResultData result;
2408   if (!multi_draw_manager_->End(&result)) {
2409     return error::kInvalidArguments;
2410   }
2411   switch (result.draw_function) {
2412     case MultiDrawManager::DrawFunction::DrawArrays:
2413       api()->glMultiDrawArraysANGLEFn(result.mode, result.firsts.data(),
2414                                       result.counts.data(), result.drawcount);
2415       return error::kNoError;
2416     case MultiDrawManager::DrawFunction::DrawArraysInstanced:
2417       api()->glMultiDrawArraysInstancedANGLEFn(
2418           result.mode, result.firsts.data(), result.counts.data(),
2419           result.instance_counts.data(), result.drawcount);
2420       return error::kNoError;
2421     case MultiDrawManager::DrawFunction::DrawArraysInstancedBaseInstance:
2422       api()->glMultiDrawArraysInstancedBaseInstanceANGLEFn(
2423           result.mode, result.firsts.data(), result.counts.data(),
2424           result.instance_counts.data(), result.baseinstances.data(),
2425           result.drawcount);
2426       return error::kNoError;
2427     case MultiDrawManager::DrawFunction::DrawElements:
2428       api()->glMultiDrawElementsANGLEFn(result.mode, result.counts.data(),
2429                                         result.type, result.indices.data(),
2430                                         result.drawcount);
2431       return error::kNoError;
2432     case MultiDrawManager::DrawFunction::DrawElementsInstanced:
2433       api()->glMultiDrawElementsInstancedANGLEFn(
2434           result.mode, result.counts.data(), result.type, result.indices.data(),
2435           result.instance_counts.data(), result.drawcount);
2436       return error::kNoError;
2437     case MultiDrawManager::DrawFunction::
2438         DrawElementsInstancedBaseVertexBaseInstance:
2439       api()->glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLEFn(
2440           result.mode, result.counts.data(), result.type, result.indices.data(),
2441           result.instance_counts.data(), result.basevertices.data(),
2442           result.baseinstances.data(), result.drawcount);
2443       return error::kNoError;
2444     default:
2445       NOTREACHED();
2446       return error::kLostContext;
2447   }
2448 }
2449 
DoPauseTransformFeedback()2450 error::Error GLES2DecoderPassthroughImpl::DoPauseTransformFeedback() {
2451   api()->glPauseTransformFeedbackFn();
2452   return error::kNoError;
2453 }
2454 
DoPixelStorei(GLenum pname,GLint param)2455 error::Error GLES2DecoderPassthroughImpl::DoPixelStorei(GLenum pname,
2456                                                         GLint param) {
2457   api()->glPixelStoreiFn(pname, param);
2458   return error::kNoError;
2459 }
2460 
DoPolygonOffset(GLfloat factor,GLfloat units)2461 error::Error GLES2DecoderPassthroughImpl::DoPolygonOffset(GLfloat factor,
2462                                                           GLfloat units) {
2463   api()->glPolygonOffsetFn(factor, units);
2464   return error::kNoError;
2465 }
2466 
DoReadBuffer(GLenum src)2467 error::Error GLES2DecoderPassthroughImpl::DoReadBuffer(GLenum src) {
2468   api()->glReadBufferFn(src);
2469   return error::kNoError;
2470 }
2471 
DoReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufsize,GLsizei * length,GLsizei * columns,GLsizei * rows,void * pixels,int32_t * success)2472 error::Error GLES2DecoderPassthroughImpl::DoReadPixels(GLint x,
2473                                                        GLint y,
2474                                                        GLsizei width,
2475                                                        GLsizei height,
2476                                                        GLenum format,
2477                                                        GLenum type,
2478                                                        GLsizei bufsize,
2479                                                        GLsizei* length,
2480                                                        GLsizei* columns,
2481                                                        GLsizei* rows,
2482                                                        void* pixels,
2483                                                        int32_t* success) {
2484   CheckErrorCallbackState();
2485   ScopedPackStateRowLengthReset reset_row_length(
2486       api(), bufsize != 0 && feature_info_->gl_version_info().is_es3);
2487   api()->glReadPixelsRobustANGLEFn(x, y, width, height, format, type, bufsize,
2488                                    length, columns, rows, pixels);
2489   *success = CheckErrorCallbackState() ? 0 : 1;
2490   return error::kNoError;
2491 }
2492 
DoReadPixelsAsync(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufsize,GLsizei * length,GLsizei * columns,GLsizei * rows,uint32_t pixels_shm_id,uint32_t pixels_shm_offset,uint32_t result_shm_id,uint32_t result_shm_offset)2493 error::Error GLES2DecoderPassthroughImpl::DoReadPixelsAsync(
2494     GLint x,
2495     GLint y,
2496     GLsizei width,
2497     GLsizei height,
2498     GLenum format,
2499     GLenum type,
2500     GLsizei bufsize,
2501     GLsizei* length,
2502     GLsizei* columns,
2503     GLsizei* rows,
2504     uint32_t pixels_shm_id,
2505     uint32_t pixels_shm_offset,
2506     uint32_t result_shm_id,
2507     uint32_t result_shm_offset) {
2508   DCHECK(feature_info_->feature_flags().use_async_readpixels &&
2509          bound_buffers_[GL_PIXEL_PACK_BUFFER] == 0);
2510 
2511   CheckErrorCallbackState();
2512   ScopedPackStateRowLengthReset reset_row_length(
2513       api(), bufsize != 0 && feature_info_->gl_version_info().is_es3);
2514 
2515   PendingReadPixels pending_read_pixels;
2516   pending_read_pixels.pixels_shm_id = pixels_shm_id;
2517   pending_read_pixels.pixels_shm_offset = pixels_shm_offset;
2518   pending_read_pixels.result_shm_id = result_shm_id;
2519   pending_read_pixels.result_shm_offset = result_shm_offset;
2520 
2521   api()->glGenBuffersARBFn(1, &pending_read_pixels.buffer_service_id);
2522   api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB,
2523                         pending_read_pixels.buffer_service_id);
2524 
2525   // GL_STREAM_READ is not available until ES3.
2526   const GLenum usage_hint = feature_info_->gl_version_info().IsAtLeastGLES(3, 0)
2527                                 ? GL_STREAM_READ
2528                                 : GL_STATIC_DRAW;
2529 
2530   const uint32_t bytes_per_pixel =
2531       GLES2Util::ComputeImageGroupSize(format, type);
2532   if (bytes_per_pixel == 0) {
2533     InsertError(GL_INVALID_ENUM, "Invalid ReadPixels format or type.");
2534     return error::kNoError;
2535   }
2536 
2537   if (width < 0 || height < 0) {
2538     InsertError(GL_INVALID_VALUE, "Width and height cannot be negative.");
2539     return error::kNoError;
2540   }
2541 
2542   if (!base::CheckMul(bytes_per_pixel, width, height)
2543            .AssignIfValid(&pending_read_pixels.pixels_size)) {
2544     return error::kOutOfBounds;
2545   }
2546 
2547   api()->glBufferDataFn(GL_PIXEL_PACK_BUFFER_ARB,
2548                         pending_read_pixels.pixels_size, nullptr, usage_hint);
2549 
2550   // No need to worry about ES3 pixel pack parameters, because no
2551   // PIXEL_PACK_BUFFER is bound, and all these settings haven't been
2552   // sent to GL.
2553   api()->glReadPixelsFn(x, y, width, height, format, type, nullptr);
2554 
2555   api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER_ARB, 0);
2556 
2557   // Test for errors now before creating a fence
2558   if (CheckErrorCallbackState()) {
2559     return error::kNoError;
2560   }
2561 
2562   pending_read_pixels.fence = gl::GLFence::Create();
2563 
2564   if (CheckErrorCallbackState()) {
2565     return error::kNoError;
2566   }
2567 
2568   pending_read_pixels_.push_back(std::move(pending_read_pixels));
2569   return error::kNoError;
2570 }
2571 
DoReleaseShaderCompiler()2572 error::Error GLES2DecoderPassthroughImpl::DoReleaseShaderCompiler() {
2573   api()->glReleaseShaderCompilerFn();
2574   return error::kNoError;
2575 }
2576 
DoRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)2577 error::Error GLES2DecoderPassthroughImpl::DoRenderbufferStorage(
2578     GLenum target,
2579     GLenum internalformat,
2580     GLsizei width,
2581     GLsizei height) {
2582   api()->glRenderbufferStorageEXTFn(target, internalformat, width, height);
2583   return error::kNoError;
2584 }
2585 
DoResumeTransformFeedback()2586 error::Error GLES2DecoderPassthroughImpl::DoResumeTransformFeedback() {
2587   api()->glResumeTransformFeedbackFn();
2588   return error::kNoError;
2589 }
2590 
DoSampleCoverage(GLclampf value,GLboolean invert)2591 error::Error GLES2DecoderPassthroughImpl::DoSampleCoverage(GLclampf value,
2592                                                            GLboolean invert) {
2593   api()->glSampleCoverageFn(value, invert);
2594   return error::kNoError;
2595 }
2596 
DoSamplerParameterf(GLuint sampler,GLenum pname,GLfloat param)2597 error::Error GLES2DecoderPassthroughImpl::DoSamplerParameterf(GLuint sampler,
2598                                                               GLenum pname,
2599                                                               GLfloat param) {
2600   api()->glSamplerParameterfFn(GetSamplerServiceID(sampler, resources_), pname,
2601                                param);
2602   return error::kNoError;
2603 }
2604 
DoSamplerParameterfv(GLuint sampler,GLenum pname,const volatile GLfloat * params)2605 error::Error GLES2DecoderPassthroughImpl::DoSamplerParameterfv(
2606     GLuint sampler,
2607     GLenum pname,
2608     const volatile GLfloat* params) {
2609   std::array<GLfloat, 1> params_copy{{params[0]}};
2610   api()->glSamplerParameterfvRobustANGLEFn(
2611       GetSamplerServiceID(sampler, resources_), pname,
2612       static_cast<GLsizei>(params_copy.size()), params_copy.data());
2613   return error::kNoError;
2614 }
2615 
DoSamplerParameteri(GLuint sampler,GLenum pname,GLint param)2616 error::Error GLES2DecoderPassthroughImpl::DoSamplerParameteri(GLuint sampler,
2617                                                               GLenum pname,
2618                                                               GLint param) {
2619   api()->glSamplerParameteriFn(GetSamplerServiceID(sampler, resources_), pname,
2620                                param);
2621   return error::kNoError;
2622 }
2623 
DoSamplerParameteriv(GLuint sampler,GLenum pname,const volatile GLint * params)2624 error::Error GLES2DecoderPassthroughImpl::DoSamplerParameteriv(
2625     GLuint sampler,
2626     GLenum pname,
2627     const volatile GLint* params) {
2628   std::array<GLint, 1> params_copy{{params[0]}};
2629   api()->glSamplerParameterivRobustANGLEFn(
2630       GetSamplerServiceID(sampler, resources_), pname,
2631       static_cast<GLsizei>(params_copy.size()), params_copy.data());
2632   return error::kNoError;
2633 }
2634 
DoScissor(GLint x,GLint y,GLsizei width,GLsizei height)2635 error::Error GLES2DecoderPassthroughImpl::DoScissor(GLint x,
2636                                                     GLint y,
2637                                                     GLsizei width,
2638                                                     GLsizei height) {
2639   CheckErrorCallbackState();
2640 
2641   gfx::Vector2d scissor_offset = GetSurfaceDrawOffset();
2642   api()->glScissorFn(x + scissor_offset.x(), y + scissor_offset.y(), width,
2643                      height);
2644 
2645   if (CheckErrorCallbackState()) {
2646     // Skip any state tracking updates if an error was generated
2647     return error::kNoError;
2648   }
2649 
2650   AssignGLRectangle(scissor_, x, y, width, height);
2651 
2652   return error::kNoError;
2653 }
2654 
DoShaderBinary(GLsizei n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLsizei length)2655 error::Error GLES2DecoderPassthroughImpl::DoShaderBinary(GLsizei n,
2656                                                          const GLuint* shaders,
2657                                                          GLenum binaryformat,
2658                                                          const void* binary,
2659                                                          GLsizei length) {
2660   std::vector<GLuint> service_shaders(n, 0);
2661   for (GLsizei i = 0; i < n; i++) {
2662     service_shaders[i] = GetShaderServiceID(shaders[i], resources_);
2663   }
2664   api()->glShaderBinaryFn(n, service_shaders.data(), binaryformat, binary,
2665                           length);
2666   return error::kNoError;
2667 }
2668 
DoShaderSource(GLuint shader,GLsizei count,const char ** string,const GLint * length)2669 error::Error GLES2DecoderPassthroughImpl::DoShaderSource(GLuint shader,
2670                                                          GLsizei count,
2671                                                          const char** string,
2672                                                          const GLint* length) {
2673   api()->glShaderSourceFn(GetShaderServiceID(shader, resources_), count, string,
2674                           length);
2675   return error::kNoError;
2676 }
2677 
DoStencilFunc(GLenum func,GLint ref,GLuint mask)2678 error::Error GLES2DecoderPassthroughImpl::DoStencilFunc(GLenum func,
2679                                                         GLint ref,
2680                                                         GLuint mask) {
2681   api()->glStencilFuncFn(func, ref, mask);
2682   return error::kNoError;
2683 }
2684 
DoStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)2685 error::Error GLES2DecoderPassthroughImpl::DoStencilFuncSeparate(GLenum face,
2686                                                                 GLenum func,
2687                                                                 GLint ref,
2688                                                                 GLuint mask) {
2689   api()->glStencilFuncSeparateFn(face, func, ref, mask);
2690   return error::kNoError;
2691 }
2692 
DoStencilMask(GLuint mask)2693 error::Error GLES2DecoderPassthroughImpl::DoStencilMask(GLuint mask) {
2694   api()->glStencilMaskFn(mask);
2695   return error::kNoError;
2696 }
2697 
DoStencilMaskSeparate(GLenum face,GLuint mask)2698 error::Error GLES2DecoderPassthroughImpl::DoStencilMaskSeparate(GLenum face,
2699                                                                 GLuint mask) {
2700   api()->glStencilMaskSeparateFn(face, mask);
2701   return error::kNoError;
2702 }
2703 
DoStencilOp(GLenum fail,GLenum zfail,GLenum zpass)2704 error::Error GLES2DecoderPassthroughImpl::DoStencilOp(GLenum fail,
2705                                                       GLenum zfail,
2706                                                       GLenum zpass) {
2707   api()->glStencilOpFn(fail, zfail, zpass);
2708   return error::kNoError;
2709 }
2710 
DoStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)2711 error::Error GLES2DecoderPassthroughImpl::DoStencilOpSeparate(GLenum face,
2712                                                               GLenum fail,
2713                                                               GLenum zfail,
2714                                                               GLenum zpass) {
2715   api()->glStencilOpSeparateFn(face, fail, zfail, zpass);
2716   return error::kNoError;
2717 }
2718 
DoTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei image_size,const void * pixels)2719 error::Error GLES2DecoderPassthroughImpl::DoTexImage2D(GLenum target,
2720                                                        GLint level,
2721                                                        GLint internalformat,
2722                                                        GLsizei width,
2723                                                        GLsizei height,
2724                                                        GLint border,
2725                                                        GLenum format,
2726                                                        GLenum type,
2727                                                        GLsizei image_size,
2728                                                        const void* pixels) {
2729   ScopedUnpackStateButAlignmentReset reset_unpack(
2730       api(), image_size != 0 && feature_info_->gl_version_info().is_es3, false);
2731 
2732   CheckErrorCallbackState();
2733   api()->glTexImage2DRobustANGLEFn(target, level, internalformat, width, height,
2734                                    border, format, type, image_size, pixels);
2735   if (CheckErrorCallbackState()) {
2736     return error::kNoError;
2737   }
2738 
2739   UpdateTextureSizeFromTarget(target);
2740 
2741   // Texture data upload can be slow.  Exit command processing to allow for
2742   // context preemption and GPU watchdog checks.
2743   ExitCommandProcessingEarly();
2744 
2745   return error::kNoError;
2746 }
2747 
DoTexImage3D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei image_size,const void * pixels)2748 error::Error GLES2DecoderPassthroughImpl::DoTexImage3D(GLenum target,
2749                                                        GLint level,
2750                                                        GLint internalformat,
2751                                                        GLsizei width,
2752                                                        GLsizei height,
2753                                                        GLsizei depth,
2754                                                        GLint border,
2755                                                        GLenum format,
2756                                                        GLenum type,
2757                                                        GLsizei image_size,
2758                                                        const void* pixels) {
2759   ScopedUnpackStateButAlignmentReset reset_unpack(
2760       api(), image_size != 0 && feature_info_->gl_version_info().is_es3, true);
2761 
2762   CheckErrorCallbackState();
2763   api()->glTexImage3DRobustANGLEFn(target, level, internalformat, width, height,
2764                                    depth, border, format, type, image_size,
2765                                    pixels);
2766   if (CheckErrorCallbackState()) {
2767     return error::kNoError;
2768   }
2769 
2770   UpdateTextureSizeFromTarget(target);
2771 
2772   // Texture data upload can be slow.  Exit command processing to allow for
2773   // context preemption and GPU watchdog checks.
2774   ExitCommandProcessingEarly();
2775 
2776   return error::kNoError;
2777 }
2778 
DoTexParameterf(GLenum target,GLenum pname,GLfloat param)2779 error::Error GLES2DecoderPassthroughImpl::DoTexParameterf(GLenum target,
2780                                                           GLenum pname,
2781                                                           GLfloat param) {
2782   // Don't allow clients to modify the resource initialization state.
2783   if (pname == GL_RESOURCE_INITIALIZED_ANGLE) {
2784     InsertError(GL_INVALID_ENUM, "Invalid enum.");
2785     return error::kNoError;
2786   }
2787 
2788   api()->glTexParameterfFn(target, pname, param);
2789   return error::kNoError;
2790 }
2791 
DoTexParameterfv(GLenum target,GLenum pname,const volatile GLfloat * params)2792 error::Error GLES2DecoderPassthroughImpl::DoTexParameterfv(
2793     GLenum target,
2794     GLenum pname,
2795     const volatile GLfloat* params) {
2796   // Don't allow clients to modify the resource initialization state.
2797   if (pname == GL_RESOURCE_INITIALIZED_ANGLE) {
2798     InsertError(GL_INVALID_ENUM, "Invalid enum.");
2799     return error::kNoError;
2800   }
2801 
2802   std::array<GLfloat, 1> params_copy{{params[0]}};
2803   api()->glTexParameterfvRobustANGLEFn(target, pname,
2804                                        static_cast<GLsizei>(params_copy.size()),
2805                                        params_copy.data());
2806   return error::kNoError;
2807 }
2808 
DoTexParameteri(GLenum target,GLenum pname,GLint param)2809 error::Error GLES2DecoderPassthroughImpl::DoTexParameteri(GLenum target,
2810                                                           GLenum pname,
2811                                                           GLint param) {
2812   // Don't allow clients to modify the resource initialization state.
2813   if (pname == GL_RESOURCE_INITIALIZED_ANGLE) {
2814     InsertError(GL_INVALID_ENUM, "Invalid enum.");
2815     return error::kNoError;
2816   }
2817 
2818   api()->glTexParameteriFn(target, pname, param);
2819   return error::kNoError;
2820 }
2821 
DoTexParameteriv(GLenum target,GLenum pname,const volatile GLint * params)2822 error::Error GLES2DecoderPassthroughImpl::DoTexParameteriv(
2823     GLenum target,
2824     GLenum pname,
2825     const volatile GLint* params) {
2826   // Don't allow clients to modify the resource initialization state.
2827   if (pname == GL_RESOURCE_INITIALIZED_ANGLE) {
2828     InsertError(GL_INVALID_ENUM, "Invalid enum.");
2829     return error::kNoError;
2830   }
2831 
2832   std::array<GLint, 1> params_copy{{params[0]}};
2833   api()->glTexParameterivRobustANGLEFn(target, pname,
2834                                        static_cast<GLsizei>(params_copy.size()),
2835                                        params_copy.data());
2836   return error::kNoError;
2837 }
2838 
DoTexStorage3D(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth)2839 error::Error GLES2DecoderPassthroughImpl::DoTexStorage3D(GLenum target,
2840                                                          GLsizei levels,
2841                                                          GLenum internalFormat,
2842                                                          GLsizei width,
2843                                                          GLsizei height,
2844                                                          GLsizei depth) {
2845   CheckErrorCallbackState();
2846   api()->glTexStorage3DFn(target, levels, internalFormat, width, height, depth);
2847   if (CheckErrorCallbackState()) {
2848     return error::kNoError;
2849   }
2850 
2851   UpdateTextureSizeFromTarget(target);
2852   return error::kNoError;
2853 }
2854 
DoTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei image_size,const void * pixels)2855 error::Error GLES2DecoderPassthroughImpl::DoTexSubImage2D(GLenum target,
2856                                                           GLint level,
2857                                                           GLint xoffset,
2858                                                           GLint yoffset,
2859                                                           GLsizei width,
2860                                                           GLsizei height,
2861                                                           GLenum format,
2862                                                           GLenum type,
2863                                                           GLsizei image_size,
2864                                                           const void* pixels) {
2865   ScopedUnpackStateButAlignmentReset reset_unpack(
2866       api(), image_size != 0 && feature_info_->gl_version_info().is_es3, false);
2867   api()->glTexSubImage2DRobustANGLEFn(target, level, xoffset, yoffset, width,
2868                                       height, format, type, image_size, pixels);
2869 
2870   // Texture data upload can be slow.  Exit command processing to allow for
2871   // context preemption and GPU watchdog checks.
2872   ExitCommandProcessingEarly();
2873 
2874   return error::kNoError;
2875 }
2876 
DoTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLsizei image_size,const void * pixels)2877 error::Error GLES2DecoderPassthroughImpl::DoTexSubImage3D(GLenum target,
2878                                                           GLint level,
2879                                                           GLint xoffset,
2880                                                           GLint yoffset,
2881                                                           GLint zoffset,
2882                                                           GLsizei width,
2883                                                           GLsizei height,
2884                                                           GLsizei depth,
2885                                                           GLenum format,
2886                                                           GLenum type,
2887                                                           GLsizei image_size,
2888                                                           const void* pixels) {
2889   ScopedUnpackStateButAlignmentReset reset_unpack(
2890       api(), image_size != 0 && feature_info_->gl_version_info().is_es3, true);
2891   api()->glTexSubImage3DRobustANGLEFn(target, level, xoffset, yoffset, zoffset,
2892                                       width, height, depth, format, type,
2893                                       image_size, pixels);
2894 
2895   // Texture data upload can be slow.  Exit command processing to allow for
2896   // context preemption and GPU watchdog checks.
2897   ExitCommandProcessingEarly();
2898 
2899   return error::kNoError;
2900 }
2901 
DoTransformFeedbackVaryings(GLuint program,GLsizei count,const char ** varyings,GLenum buffermode)2902 error::Error GLES2DecoderPassthroughImpl::DoTransformFeedbackVaryings(
2903     GLuint program,
2904     GLsizei count,
2905     const char** varyings,
2906     GLenum buffermode) {
2907   api()->glTransformFeedbackVaryingsFn(GetProgramServiceID(program, resources_),
2908                                        count, varyings, buffermode);
2909   return error::kNoError;
2910 }
2911 
DoUniform1f(GLint location,GLfloat x)2912 error::Error GLES2DecoderPassthroughImpl::DoUniform1f(GLint location,
2913                                                       GLfloat x) {
2914   api()->glUniform1fFn(location, x);
2915   return error::kNoError;
2916 }
2917 
DoUniform1fv(GLint location,GLsizei count,const volatile GLfloat * v)2918 error::Error GLES2DecoderPassthroughImpl::DoUniform1fv(
2919     GLint location,
2920     GLsizei count,
2921     const volatile GLfloat* v) {
2922   api()->glUniform1fvFn(location, count, const_cast<const GLfloat*>(v));
2923   return error::kNoError;
2924 }
2925 
DoUniform1i(GLint location,GLint x)2926 error::Error GLES2DecoderPassthroughImpl::DoUniform1i(GLint location, GLint x) {
2927   api()->glUniform1iFn(location, x);
2928   return error::kNoError;
2929 }
2930 
DoUniform1iv(GLint location,GLsizei count,const volatile GLint * v)2931 error::Error GLES2DecoderPassthroughImpl::DoUniform1iv(
2932     GLint location,
2933     GLsizei count,
2934     const volatile GLint* v) {
2935   api()->glUniform1ivFn(location, count, const_cast<const GLint*>(v));
2936   return error::kNoError;
2937 }
2938 
DoUniform1ui(GLint location,GLuint x)2939 error::Error GLES2DecoderPassthroughImpl::DoUniform1ui(GLint location,
2940                                                        GLuint x) {
2941   api()->glUniform1uiFn(location, x);
2942   return error::kNoError;
2943 }
2944 
DoUniform1uiv(GLint location,GLsizei count,const volatile GLuint * v)2945 error::Error GLES2DecoderPassthroughImpl::DoUniform1uiv(
2946     GLint location,
2947     GLsizei count,
2948     const volatile GLuint* v) {
2949   api()->glUniform1uivFn(location, count, const_cast<const GLuint*>(v));
2950   return error::kNoError;
2951 }
2952 
DoUniform2f(GLint location,GLfloat x,GLfloat y)2953 error::Error GLES2DecoderPassthroughImpl::DoUniform2f(GLint location,
2954                                                       GLfloat x,
2955                                                       GLfloat y) {
2956   api()->glUniform2fFn(location, x, y);
2957   return error::kNoError;
2958 }
2959 
DoUniform2fv(GLint location,GLsizei count,const volatile GLfloat * v)2960 error::Error GLES2DecoderPassthroughImpl::DoUniform2fv(
2961     GLint location,
2962     GLsizei count,
2963     const volatile GLfloat* v) {
2964   api()->glUniform2fvFn(location, count, const_cast<const GLfloat*>(v));
2965   return error::kNoError;
2966 }
2967 
DoUniform2i(GLint location,GLint x,GLint y)2968 error::Error GLES2DecoderPassthroughImpl::DoUniform2i(GLint location,
2969                                                       GLint x,
2970                                                       GLint y) {
2971   api()->glUniform2iFn(location, x, y);
2972   return error::kNoError;
2973 }
2974 
DoUniform2iv(GLint location,GLsizei count,const volatile GLint * v)2975 error::Error GLES2DecoderPassthroughImpl::DoUniform2iv(
2976     GLint location,
2977     GLsizei count,
2978     const volatile GLint* v) {
2979   api()->glUniform2ivFn(location, count, const_cast<const GLint*>(v));
2980   return error::kNoError;
2981 }
2982 
DoUniform2ui(GLint location,GLuint x,GLuint y)2983 error::Error GLES2DecoderPassthroughImpl::DoUniform2ui(GLint location,
2984                                                        GLuint x,
2985                                                        GLuint y) {
2986   api()->glUniform2uiFn(location, x, y);
2987   return error::kNoError;
2988 }
2989 
DoUniform2uiv(GLint location,GLsizei count,const volatile GLuint * v)2990 error::Error GLES2DecoderPassthroughImpl::DoUniform2uiv(
2991     GLint location,
2992     GLsizei count,
2993     const volatile GLuint* v) {
2994   api()->glUniform2uivFn(location, count, const_cast<const GLuint*>(v));
2995   return error::kNoError;
2996 }
2997 
DoUniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)2998 error::Error GLES2DecoderPassthroughImpl::DoUniform3f(GLint location,
2999                                                       GLfloat x,
3000                                                       GLfloat y,
3001                                                       GLfloat z) {
3002   api()->glUniform3fFn(location, x, y, z);
3003   return error::kNoError;
3004 }
3005 
DoUniform3fv(GLint location,GLsizei count,const volatile GLfloat * v)3006 error::Error GLES2DecoderPassthroughImpl::DoUniform3fv(
3007     GLint location,
3008     GLsizei count,
3009     const volatile GLfloat* v) {
3010   api()->glUniform3fvFn(location, count, const_cast<const GLfloat*>(v));
3011   return error::kNoError;
3012 }
3013 
DoUniform3i(GLint location,GLint x,GLint y,GLint z)3014 error::Error GLES2DecoderPassthroughImpl::DoUniform3i(GLint location,
3015                                                       GLint x,
3016                                                       GLint y,
3017                                                       GLint z) {
3018   api()->glUniform3iFn(location, x, y, z);
3019   return error::kNoError;
3020 }
3021 
DoUniform3iv(GLint location,GLsizei count,const volatile GLint * v)3022 error::Error GLES2DecoderPassthroughImpl::DoUniform3iv(
3023     GLint location,
3024     GLsizei count,
3025     const volatile GLint* v) {
3026   api()->glUniform3ivFn(location, count, const_cast<const GLint*>(v));
3027   return error::kNoError;
3028 }
3029 
DoUniform3ui(GLint location,GLuint x,GLuint y,GLuint z)3030 error::Error GLES2DecoderPassthroughImpl::DoUniform3ui(GLint location,
3031                                                        GLuint x,
3032                                                        GLuint y,
3033                                                        GLuint z) {
3034   api()->glUniform3uiFn(location, x, y, z);
3035   return error::kNoError;
3036 }
3037 
DoUniform3uiv(GLint location,GLsizei count,const volatile GLuint * v)3038 error::Error GLES2DecoderPassthroughImpl::DoUniform3uiv(
3039     GLint location,
3040     GLsizei count,
3041     const volatile GLuint* v) {
3042   api()->glUniform3uivFn(location, count, const_cast<const GLuint*>(v));
3043   return error::kNoError;
3044 }
3045 
DoUniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)3046 error::Error GLES2DecoderPassthroughImpl::DoUniform4f(GLint location,
3047                                                       GLfloat x,
3048                                                       GLfloat y,
3049                                                       GLfloat z,
3050                                                       GLfloat w) {
3051   api()->glUniform4fFn(location, x, y, z, w);
3052   return error::kNoError;
3053 }
3054 
DoUniform4fv(GLint location,GLsizei count,const volatile GLfloat * v)3055 error::Error GLES2DecoderPassthroughImpl::DoUniform4fv(
3056     GLint location,
3057     GLsizei count,
3058     const volatile GLfloat* v) {
3059   api()->glUniform4fvFn(location, count, const_cast<const GLfloat*>(v));
3060   return error::kNoError;
3061 }
3062 
DoUniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)3063 error::Error GLES2DecoderPassthroughImpl::DoUniform4i(GLint location,
3064                                                       GLint x,
3065                                                       GLint y,
3066                                                       GLint z,
3067                                                       GLint w) {
3068   api()->glUniform4iFn(location, x, y, z, w);
3069   return error::kNoError;
3070 }
3071 
DoUniform4iv(GLint location,GLsizei count,const volatile GLint * v)3072 error::Error GLES2DecoderPassthroughImpl::DoUniform4iv(
3073     GLint location,
3074     GLsizei count,
3075     const volatile GLint* v) {
3076   api()->glUniform4ivFn(location, count, const_cast<const GLint*>(v));
3077   return error::kNoError;
3078 }
3079 
DoUniform4ui(GLint location,GLuint x,GLuint y,GLuint z,GLuint w)3080 error::Error GLES2DecoderPassthroughImpl::DoUniform4ui(GLint location,
3081                                                        GLuint x,
3082                                                        GLuint y,
3083                                                        GLuint z,
3084                                                        GLuint w) {
3085   api()->glUniform4uiFn(location, x, y, z, w);
3086   return error::kNoError;
3087 }
3088 
DoUniform4uiv(GLint location,GLsizei count,const volatile GLuint * v)3089 error::Error GLES2DecoderPassthroughImpl::DoUniform4uiv(
3090     GLint location,
3091     GLsizei count,
3092     const volatile GLuint* v) {
3093   api()->glUniform4uivFn(location, count, const_cast<const GLuint*>(v));
3094   return error::kNoError;
3095 }
3096 
DoUniformBlockBinding(GLuint program,GLuint index,GLuint binding)3097 error::Error GLES2DecoderPassthroughImpl::DoUniformBlockBinding(
3098     GLuint program,
3099     GLuint index,
3100     GLuint binding) {
3101   api()->glUniformBlockBindingFn(GetProgramServiceID(program, resources_),
3102                                  index, binding);
3103   return error::kNoError;
3104 }
3105 
DoUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3106 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix2fv(
3107     GLint location,
3108     GLsizei count,
3109     GLboolean transpose,
3110     const volatile GLfloat* value) {
3111   api()->glUniformMatrix2fvFn(location, count, transpose,
3112                               const_cast<const GLfloat*>(value));
3113   return error::kNoError;
3114 }
3115 
DoUniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3116 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix2x3fv(
3117     GLint location,
3118     GLsizei count,
3119     GLboolean transpose,
3120     const volatile GLfloat* value) {
3121   api()->glUniformMatrix2x3fvFn(location, count, transpose,
3122                                 const_cast<const GLfloat*>(value));
3123   return error::kNoError;
3124 }
3125 
DoUniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3126 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix2x4fv(
3127     GLint location,
3128     GLsizei count,
3129     GLboolean transpose,
3130     const volatile GLfloat* value) {
3131   api()->glUniformMatrix2x4fvFn(location, count, transpose,
3132                                 const_cast<const GLfloat*>(value));
3133   return error::kNoError;
3134 }
3135 
DoUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3136 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix3fv(
3137     GLint location,
3138     GLsizei count,
3139     GLboolean transpose,
3140     const volatile GLfloat* value) {
3141   api()->glUniformMatrix3fvFn(location, count, transpose,
3142                               const_cast<const GLfloat*>(value));
3143   return error::kNoError;
3144 }
3145 
DoUniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3146 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix3x2fv(
3147     GLint location,
3148     GLsizei count,
3149     GLboolean transpose,
3150     const volatile GLfloat* value) {
3151   api()->glUniformMatrix3x2fvFn(location, count, transpose,
3152                                 const_cast<const GLfloat*>(value));
3153   return error::kNoError;
3154 }
3155 
DoUniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3156 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix3x4fv(
3157     GLint location,
3158     GLsizei count,
3159     GLboolean transpose,
3160     const volatile GLfloat* value) {
3161   api()->glUniformMatrix3x4fvFn(location, count, transpose,
3162                                 const_cast<const GLfloat*>(value));
3163   return error::kNoError;
3164 }
3165 
DoUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3166 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix4fv(
3167     GLint location,
3168     GLsizei count,
3169     GLboolean transpose,
3170     const volatile GLfloat* value) {
3171   api()->glUniformMatrix4fvFn(location, count, transpose,
3172                               const_cast<const GLfloat*>(value));
3173   return error::kNoError;
3174 }
3175 
DoUniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3176 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix4x2fv(
3177     GLint location,
3178     GLsizei count,
3179     GLboolean transpose,
3180     const volatile GLfloat* value) {
3181   api()->glUniformMatrix4x2fvFn(location, count, transpose,
3182                                 const_cast<const GLfloat*>(value));
3183   return error::kNoError;
3184 }
3185 
DoUniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const volatile GLfloat * value)3186 error::Error GLES2DecoderPassthroughImpl::DoUniformMatrix4x3fv(
3187     GLint location,
3188     GLsizei count,
3189     GLboolean transpose,
3190     const volatile GLfloat* value) {
3191   api()->glUniformMatrix4x3fvFn(location, count, transpose,
3192                                 const_cast<const GLfloat*>(value));
3193   return error::kNoError;
3194 }
3195 
DoUseProgram(GLuint program)3196 error::Error GLES2DecoderPassthroughImpl::DoUseProgram(GLuint program) {
3197   api()->glUseProgramFn(GetProgramServiceID(program, resources_));
3198   return error::kNoError;
3199 }
3200 
DoValidateProgram(GLuint program)3201 error::Error GLES2DecoderPassthroughImpl::DoValidateProgram(GLuint program) {
3202   api()->glValidateProgramFn(GetProgramServiceID(program, resources_));
3203   return error::kNoError;
3204 }
3205 
DoVertexAttrib1f(GLuint indx,GLfloat x)3206 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib1f(GLuint indx,
3207                                                            GLfloat x) {
3208   api()->glVertexAttrib1fFn(indx, x);
3209   return error::kNoError;
3210 }
3211 
DoVertexAttrib1fv(GLuint indx,const volatile GLfloat * values)3212 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib1fv(
3213     GLuint indx,
3214     const volatile GLfloat* values) {
3215   api()->glVertexAttrib1fvFn(indx, const_cast<const GLfloat*>(values));
3216   return error::kNoError;
3217 }
3218 
DoVertexAttrib2f(GLuint indx,GLfloat x,GLfloat y)3219 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib2f(GLuint indx,
3220                                                            GLfloat x,
3221                                                            GLfloat y) {
3222   api()->glVertexAttrib2fFn(indx, x, y);
3223   return error::kNoError;
3224 }
3225 
DoVertexAttrib2fv(GLuint indx,const volatile GLfloat * values)3226 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib2fv(
3227     GLuint indx,
3228     const volatile GLfloat* values) {
3229   api()->glVertexAttrib2fvFn(indx, const_cast<const GLfloat*>(values));
3230   return error::kNoError;
3231 }
3232 
DoVertexAttrib3f(GLuint indx,GLfloat x,GLfloat y,GLfloat z)3233 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib3f(GLuint indx,
3234                                                            GLfloat x,
3235                                                            GLfloat y,
3236                                                            GLfloat z) {
3237   api()->glVertexAttrib3fFn(indx, x, y, z);
3238   return error::kNoError;
3239 }
3240 
DoVertexAttrib3fv(GLuint indx,const volatile GLfloat * values)3241 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib3fv(
3242     GLuint indx,
3243     const volatile GLfloat* values) {
3244   api()->glVertexAttrib3fvFn(indx, const_cast<const GLfloat*>(values));
3245   return error::kNoError;
3246 }
3247 
DoVertexAttrib4f(GLuint indx,GLfloat x,GLfloat y,GLfloat z,GLfloat w)3248 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib4f(GLuint indx,
3249                                                            GLfloat x,
3250                                                            GLfloat y,
3251                                                            GLfloat z,
3252                                                            GLfloat w) {
3253   api()->glVertexAttrib4fFn(indx, x, y, z, w);
3254   return error::kNoError;
3255 }
3256 
DoVertexAttrib4fv(GLuint indx,const volatile GLfloat * values)3257 error::Error GLES2DecoderPassthroughImpl::DoVertexAttrib4fv(
3258     GLuint indx,
3259     const volatile GLfloat* values) {
3260   api()->glVertexAttrib4fvFn(indx, const_cast<const GLfloat*>(values));
3261   return error::kNoError;
3262 }
3263 
DoVertexAttribI4i(GLuint indx,GLint x,GLint y,GLint z,GLint w)3264 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribI4i(GLuint indx,
3265                                                             GLint x,
3266                                                             GLint y,
3267                                                             GLint z,
3268                                                             GLint w) {
3269   api()->glVertexAttribI4iFn(indx, x, y, z, w);
3270   return error::kNoError;
3271 }
3272 
DoVertexAttribI4iv(GLuint indx,const volatile GLint * values)3273 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribI4iv(
3274     GLuint indx,
3275     const volatile GLint* values) {
3276   api()->glVertexAttribI4ivFn(indx, const_cast<const GLint*>(values));
3277   return error::kNoError;
3278 }
3279 
DoVertexAttribI4ui(GLuint indx,GLuint x,GLuint y,GLuint z,GLuint w)3280 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribI4ui(GLuint indx,
3281                                                              GLuint x,
3282                                                              GLuint y,
3283                                                              GLuint z,
3284                                                              GLuint w) {
3285   api()->glVertexAttribI4uiFn(indx, x, y, z, w);
3286   return error::kNoError;
3287 }
3288 
DoVertexAttribI4uiv(GLuint indx,const volatile GLuint * values)3289 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribI4uiv(
3290     GLuint indx,
3291     const volatile GLuint* values) {
3292   api()->glVertexAttribI4uivFn(indx, const_cast<const GLuint*>(values));
3293   return error::kNoError;
3294 }
3295 
DoVertexAttribIPointer(GLuint indx,GLint size,GLenum type,GLsizei stride,const void * ptr)3296 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribIPointer(
3297     GLuint indx,
3298     GLint size,
3299     GLenum type,
3300     GLsizei stride,
3301     const void* ptr) {
3302   api()->glVertexAttribIPointerFn(indx, size, type, stride, ptr);
3303   return error::kNoError;
3304 }
3305 
DoVertexAttribPointer(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const void * ptr)3306 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribPointer(
3307     GLuint indx,
3308     GLint size,
3309     GLenum type,
3310     GLboolean normalized,
3311     GLsizei stride,
3312     const void* ptr) {
3313   api()->glVertexAttribPointerFn(indx, size, type, normalized, stride, ptr);
3314   return error::kNoError;
3315 }
3316 
DoViewport(GLint x,GLint y,GLsizei width,GLsizei height)3317 error::Error GLES2DecoderPassthroughImpl::DoViewport(GLint x,
3318                                                      GLint y,
3319                                                      GLsizei width,
3320                                                      GLsizei height) {
3321   CheckErrorCallbackState();
3322 
3323   gfx::Vector2d viewport_offset = GetSurfaceDrawOffset();
3324   api()->glViewportFn(x + viewport_offset.x(), y + viewport_offset.y(), width,
3325                       height);
3326 
3327   if (CheckErrorCallbackState()) {
3328     // Skip any state tracking updates if an error was generated. Viewport may
3329     // have been out of bounds.
3330     return error::kNoError;
3331   }
3332 
3333   AssignGLRectangle(viewport_, x, y, width, height);
3334 
3335   return error::kNoError;
3336 }
3337 
DoWaitSync(GLuint sync,GLbitfield flags,GLuint64 timeout)3338 error::Error GLES2DecoderPassthroughImpl::DoWaitSync(GLuint sync,
3339                                                      GLbitfield flags,
3340                                                      GLuint64 timeout) {
3341   api()->glWaitSyncFn(GetSyncServiceID(sync, resources_), flags, timeout);
3342   return error::kNoError;
3343 }
3344 
DoBlitFramebufferCHROMIUM(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)3345 error::Error GLES2DecoderPassthroughImpl::DoBlitFramebufferCHROMIUM(
3346     GLint srcX0,
3347     GLint srcY0,
3348     GLint srcX1,
3349     GLint srcY1,
3350     GLint dstX0,
3351     GLint dstY0,
3352     GLint dstX1,
3353     GLint dstY1,
3354     GLbitfield mask,
3355     GLenum filter) {
3356   DCHECK(feature_info_->feature_flags().chromium_framebuffer_multisample);
3357   api()->glBlitFramebufferFn(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
3358                              dstY1, mask, filter);
3359   return error::kNoError;
3360 }
3361 
3362 error::Error
DoRenderbufferStorageMultisampleCHROMIUM(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3363 GLES2DecoderPassthroughImpl::DoRenderbufferStorageMultisampleCHROMIUM(
3364     GLenum target,
3365     GLsizei samples,
3366     GLenum internalformat,
3367     GLsizei width,
3368     GLsizei height) {
3369   DCHECK(feature_info_->feature_flags().chromium_framebuffer_multisample);
3370   api()->glRenderbufferStorageMultisampleFn(target, samples, internalformat,
3371                                             width, height);
3372   return error::kNoError;
3373 }
3374 
3375 error::Error
DoRenderbufferStorageMultisampleAdvancedAMD(GLenum target,GLsizei samples,GLsizei storageSamples,GLenum internalformat,GLsizei width,GLsizei height)3376 GLES2DecoderPassthroughImpl::DoRenderbufferStorageMultisampleAdvancedAMD(
3377     GLenum target,
3378     GLsizei samples,
3379     GLsizei storageSamples,
3380     GLenum internalformat,
3381     GLsizei width,
3382     GLsizei height) {
3383   DCHECK(feature_info_->feature_flags().amd_framebuffer_multisample_advanced);
3384   api()->glRenderbufferStorageMultisampleAdvancedAMDFn(
3385       target, samples, storageSamples, internalformat, width, height);
3386   return error::kNoError;
3387 }
3388 
DoRenderbufferStorageMultisampleEXT(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3389 error::Error GLES2DecoderPassthroughImpl::DoRenderbufferStorageMultisampleEXT(
3390     GLenum target,
3391     GLsizei samples,
3392     GLenum internalformat,
3393     GLsizei width,
3394     GLsizei height) {
3395   DCHECK(feature_info_->feature_flags().multisampled_render_to_texture);
3396   api()->glRenderbufferStorageMultisampleEXTFn(target, samples, internalformat,
3397                                                width, height);
3398   return error::kNoError;
3399 }
3400 
DoFramebufferTexture2DMultisampleEXT(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples)3401 error::Error GLES2DecoderPassthroughImpl::DoFramebufferTexture2DMultisampleEXT(
3402     GLenum target,
3403     GLenum attachment,
3404     GLenum textarget,
3405     GLuint texture,
3406     GLint level,
3407     GLsizei samples) {
3408   DCHECK(feature_info_->feature_flags().multisampled_render_to_texture);
3409   if (IsEmulatedFramebufferBound(target)) {
3410     InsertError(GL_INVALID_OPERATION,
3411                 "Cannot change the attachments of the default framebuffer.");
3412     return error::kNoError;
3413   }
3414   BindPendingImageForClientIDIfNeeded(texture);
3415   api()->glFramebufferTexture2DMultisampleEXTFn(
3416       target, attachment, textarget,
3417       GetTextureServiceID(api(), texture, resources_, false), level, samples);
3418   return error::kNoError;
3419 }
3420 
DoTexStorage2DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height)3421 error::Error GLES2DecoderPassthroughImpl::DoTexStorage2DEXT(
3422     GLenum target,
3423     GLsizei levels,
3424     GLenum internalFormat,
3425     GLsizei width,
3426     GLsizei height) {
3427   CheckErrorCallbackState();
3428   api()->glTexStorage2DEXTFn(target, levels, internalFormat, width, height);
3429   if (CheckErrorCallbackState()) {
3430     return error::kNoError;
3431   }
3432   UpdateTextureSizeFromTarget(target);
3433   return error::kNoError;
3434 }
3435 
DoTexStorage2DImageCHROMIUM(GLenum target,GLenum internalFormat,GLenum bufferUsage,GLsizei width,GLsizei height)3436 error::Error GLES2DecoderPassthroughImpl::DoTexStorage2DImageCHROMIUM(
3437     GLenum target,
3438     GLenum internalFormat,
3439     GLenum bufferUsage,
3440     GLsizei width,
3441     GLsizei height) {
3442   TextureTarget target_enum = GLenumToTextureTarget(target);
3443   if (target_enum == TextureTarget::kCubeMap ||
3444       target_enum == TextureTarget::kUnkown) {
3445     InsertError(GL_INVALID_ENUM, "Invalid target");
3446     return error::kNoError;
3447   }
3448 
3449   const BoundTexture& bound_texture =
3450       bound_textures_[static_cast<size_t>(target_enum)][active_texture_unit_];
3451   if (bound_texture.texture == nullptr) {
3452     InsertError(GL_INVALID_OPERATION, "No texture bound");
3453     return error::kNoError;
3454   }
3455 
3456   gfx::BufferFormat buffer_format;
3457   if (!GetGFXBufferFormat(internalFormat, &buffer_format)) {
3458     InsertError(GL_INVALID_ENUM, "Invalid buffer format");
3459     return error::kNoError;
3460   }
3461 
3462   gfx::BufferUsage buffer_usage;
3463   if (!GetGFXBufferUsage(bufferUsage, &buffer_usage)) {
3464     InsertError(GL_INVALID_ENUM, "Invalid buffer usage");
3465     return error::kNoError;
3466   }
3467 
3468   if (!GetContextGroup()->image_factory()) {
3469     InsertError(GL_INVALID_OPERATION, "Cannot create GL image");
3470     return error::kNoError;
3471   }
3472 
3473   bool is_cleared;
3474   scoped_refptr<gl::GLImage> image =
3475       GetContextGroup()->image_factory()->CreateAnonymousImage(
3476           gfx::Size(width, height), buffer_format, buffer_usage,
3477           gpu::kNullSurfaceHandle, &is_cleared);
3478   if (!image || !image->BindTexImage(target)) {
3479     InsertError(GL_INVALID_OPERATION, "Failed to create or bind GL Image");
3480     return error::kNoError;
3481   }
3482 
3483   bound_texture.texture->SetLevelImage(target, 0, image.get());
3484 
3485   // Target is already validated
3486   UpdateTextureSizeFromTarget(target);
3487 
3488   return error::kNoError;
3489 }
3490 
DoGenQueriesEXT(GLsizei n,volatile GLuint * queries)3491 error::Error GLES2DecoderPassthroughImpl::DoGenQueriesEXT(
3492     GLsizei n,
3493     volatile GLuint* queries) {
3494   return GenHelper(
3495       n, queries, &query_id_map_, [this](GLsizei n, GLuint* queries) {
3496         if (feature_info_->feature_flags().occlusion_query_boolean) {
3497           // glGenQueries is not loaded unless GL_EXT_occlusion_query_boolean is
3498           // present. All queries must be emulated so they don't need to be
3499           // generated.
3500           api()->glGenQueriesFn(n, queries);
3501         } else {
3502           for (GLsizei i = 0; i < n; i++) {
3503             queries[i] = 0;
3504           }
3505         }
3506       });
3507 }
3508 
DoDeleteQueriesEXT(GLsizei n,const volatile GLuint * queries)3509 error::Error GLES2DecoderPassthroughImpl::DoDeleteQueriesEXT(
3510     GLsizei n,
3511     const volatile GLuint* queries) {
3512   // Validate n is non-negative before allcoating a vector of size n
3513   if (n < 0) {
3514     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
3515     return error::kNoError;
3516   }
3517 
3518   std::vector<GLuint> queries_copy(queries, queries + n);
3519   // If any of these queries are pending or active, remove them from the lists
3520   for (GLuint query_client_id : queries_copy) {
3521     GLuint query_service_id = 0;
3522     if (!query_id_map_.GetServiceID(query_client_id, &query_service_id) ||
3523         query_service_id == 0) {
3524       continue;
3525     }
3526 
3527     QueryInfo query_info = query_info_map_[query_service_id];
3528     query_info_map_.erase(query_service_id);
3529 
3530     if (query_info.type == GL_NONE) {
3531       // Query was never started
3532       continue;
3533     }
3534 
3535     auto active_queries_iter = active_queries_.find(query_info.type);
3536     if (active_queries_iter != active_queries_.end()) {
3537       active_queries_.erase(active_queries_iter);
3538     }
3539 
3540     RemovePendingQuery(query_service_id);
3541   }
3542   return DeleteHelper(
3543       queries_copy.size(), queries_copy.data(), &query_id_map_,
3544       [this](GLsizei n, GLuint* queries) {
3545         if (feature_info_->feature_flags().occlusion_query_boolean) {
3546           // glDeleteQueries is not loaded unless GL_EXT_occlusion_query_boolean
3547           // is present. All queries must be emulated so they don't need to be
3548           // deleted.
3549           api()->glDeleteQueriesFn(n, queries);
3550         }
3551       });
3552 }
3553 
DoQueryCounterEXT(GLuint id,GLenum target,int32_t sync_shm_id,uint32_t sync_shm_offset,uint32_t submit_count)3554 error::Error GLES2DecoderPassthroughImpl::DoQueryCounterEXT(
3555     GLuint id,
3556     GLenum target,
3557     int32_t sync_shm_id,
3558     uint32_t sync_shm_offset,
3559     uint32_t submit_count) {
3560   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
3561   if (!buffer)
3562     return error::kInvalidArguments;
3563   QuerySync* sync = static_cast<QuerySync*>(
3564       buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
3565   if (!sync)
3566     return error::kOutOfBounds;
3567 
3568   GLuint service_id = GetQueryServiceID(id, &query_id_map_);
3569 
3570   if (IsEmulatedQueryTarget(target)) {
3571     DCHECK_EQ(target,
3572               static_cast<GLenum>(GL_COMMANDS_ISSUED_TIMESTAMP_CHROMIUM));
3573   } else {
3574     // glQueryCounter is not loaded unless GL_EXT_disjoint_timer_query is present
3575     if (!feature_info_->feature_flags().ext_disjoint_timer_query) {
3576       InsertError(GL_INVALID_ENUM, "Invalid query target.");
3577       return error::kNoError;
3578     }
3579 
3580     // Flush all previous errors
3581     CheckErrorCallbackState();
3582 
3583     api()->glQueryCounterFn(service_id, target);
3584 
3585     // Check if a new error was generated
3586     if (CheckErrorCallbackState()) {
3587       return error::kNoError;
3588     }
3589   }
3590 
3591   QueryInfo* query_info = &query_info_map_[service_id];
3592   query_info->type = target;
3593 
3594   // Make sure to stop tracking this query if it was still pending a result from
3595   // a previous glEndQuery
3596   RemovePendingQuery(service_id);
3597 
3598   PendingQuery pending_query;
3599   pending_query.target = target;
3600   pending_query.service_id = service_id;
3601   pending_query.shm = std::move(buffer);
3602   pending_query.sync = sync;
3603   pending_query.submit_count = submit_count;
3604   if (target == GL_COMMANDS_ISSUED_TIMESTAMP_CHROMIUM)
3605     pending_query.commands_issued_timestamp = base::TimeTicks::Now();
3606   pending_queries_.push_back(std::move(pending_query));
3607 
3608   return ProcessQueries(false);
3609 }
3610 
DoBeginQueryEXT(GLenum target,GLuint id,int32_t sync_shm_id,uint32_t sync_shm_offset)3611 error::Error GLES2DecoderPassthroughImpl::DoBeginQueryEXT(
3612     GLenum target,
3613     GLuint id,
3614     int32_t sync_shm_id,
3615     uint32_t sync_shm_offset) {
3616   GLuint service_id = GetQueryServiceID(id, &query_id_map_);
3617   QueryInfo* query_info = &query_info_map_[service_id];
3618 
3619   scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
3620   if (!buffer)
3621     return error::kInvalidArguments;
3622   QuerySync* sync = static_cast<QuerySync*>(
3623       buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
3624   if (!sync)
3625     return error::kOutOfBounds;
3626 
3627   if (target == GL_PROGRAM_COMPLETION_QUERY_CHROMIUM) {
3628     linking_program_service_id_ = 0u;
3629   }
3630   if (IsEmulatedQueryTarget(target)) {
3631     if (active_queries_.find(target) != active_queries_.end()) {
3632       InsertError(GL_INVALID_OPERATION, "Query already active on target.");
3633       return error::kNoError;
3634     }
3635 
3636     if (id == 0) {
3637       InsertError(GL_INVALID_OPERATION, "Query id is 0.");
3638       return error::kNoError;
3639     }
3640 
3641     if (query_info->type != GL_NONE && query_info->type != target) {
3642       InsertError(GL_INVALID_OPERATION,
3643                   "Query type does not match the target.");
3644       return error::kNoError;
3645     }
3646   } else {
3647     // glBeginQuery is not loaded unless GL_EXT_occlusion_query_boolean is
3648     // present
3649     if (!feature_info_->feature_flags().occlusion_query_boolean) {
3650       InsertError(GL_INVALID_ENUM, "Invalid query target.");
3651       return error::kNoError;
3652     }
3653 
3654     // Flush all previous errors
3655     CheckErrorCallbackState();
3656 
3657     api()->glBeginQueryFn(target, service_id);
3658 
3659     // Check if a new error was generated
3660     if (CheckErrorCallbackState()) {
3661       return error::kNoError;
3662     }
3663   }
3664 
3665   query_info->type = target;
3666 
3667   // Make sure to stop tracking this query if it was still pending a result from
3668   // a previous glEndQuery
3669   RemovePendingQuery(service_id);
3670 
3671   ActiveQuery query;
3672   query.service_id = service_id;
3673   query.shm = std::move(buffer);
3674   query.sync = sync;
3675   if (target == GL_COMMANDS_ISSUED_CHROMIUM)
3676     query.command_processing_start_time = base::TimeTicks::Now();
3677   active_queries_[target] = std::move(query);
3678 
3679   return error::kNoError;
3680 }
3681 
DoBeginTransformFeedback(GLenum primitivemode)3682 error::Error GLES2DecoderPassthroughImpl::DoBeginTransformFeedback(
3683     GLenum primitivemode) {
3684   api()->glBeginTransformFeedbackFn(primitivemode);
3685   return error::kNoError;
3686 }
3687 
DoEndQueryEXT(GLenum target,uint32_t submit_count)3688 error::Error GLES2DecoderPassthroughImpl::DoEndQueryEXT(GLenum target,
3689                                                         uint32_t submit_count) {
3690   if (IsEmulatedQueryTarget(target)) {
3691     auto active_query_iter = active_queries_.find(target);
3692     if (active_query_iter == active_queries_.end()) {
3693       InsertError(GL_INVALID_OPERATION, "No active query on target.");
3694       return error::kNoError;
3695     }
3696     if (target == GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM &&
3697         !pending_read_pixels_.empty()) {
3698       GLuint query_service_id = active_query_iter->second.service_id;
3699       pending_read_pixels_.back().waiting_async_pack_queries.insert(
3700           query_service_id);
3701     }
3702   } else {
3703     // glEndQuery is not loaded unless GL_EXT_occlusion_query_boolean is present
3704     if (!feature_info_->feature_flags().occlusion_query_boolean) {
3705       InsertError(GL_INVALID_ENUM, "Invalid query target.");
3706       return error::kNoError;
3707     }
3708 
3709     // Flush all previous errors
3710     CheckErrorCallbackState();
3711 
3712     api()->glEndQueryFn(target);
3713 
3714     // Check if a new error was generated
3715     if (CheckErrorCallbackState()) {
3716       return error::kNoError;
3717     }
3718   }
3719 
3720   DCHECK(active_queries_.find(target) != active_queries_.end());
3721   ActiveQuery active_query = std::move(active_queries_[target]);
3722   active_queries_.erase(target);
3723 
3724   PendingQuery pending_query;
3725   pending_query.target = target;
3726   pending_query.service_id = active_query.service_id;
3727   pending_query.shm = std::move(active_query.shm);
3728   pending_query.sync = active_query.sync;
3729   pending_query.submit_count = submit_count;
3730   switch (target) {
3731     case GL_COMMANDS_COMPLETED_CHROMIUM:
3732       pending_query.commands_completed_fence = gl::GLFence::Create();
3733       break;
3734 
3735     case GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM:
3736       pending_query.buffer_shadow_update_fence = gl::GLFence::Create();
3737       pending_query.buffer_shadow_updates = std::move(buffer_shadow_updates_);
3738       buffer_shadow_updates_.clear();
3739       break;
3740 
3741     case GL_PROGRAM_COMPLETION_QUERY_CHROMIUM:
3742       pending_query.program_service_id = linking_program_service_id_;
3743       break;
3744 
3745     case GL_COMMANDS_ISSUED_CHROMIUM:
3746       pending_query.commands_issued_time =
3747           active_query.active_time +
3748           (base::TimeTicks::Now() - active_query.command_processing_start_time);
3749       break;
3750 
3751     default:
3752       break;
3753   }
3754   pending_queries_.push_back(std::move(pending_query));
3755   return ProcessQueries(false);
3756 }
3757 
DoEndTransformFeedback()3758 error::Error GLES2DecoderPassthroughImpl::DoEndTransformFeedback() {
3759   api()->glEndTransformFeedbackFn();
3760   return error::kNoError;
3761 }
3762 
DoSetDisjointValueSyncCHROMIUM(DisjointValueSync * sync)3763 error::Error GLES2DecoderPassthroughImpl::DoSetDisjointValueSyncCHROMIUM(
3764     DisjointValueSync* sync) {
3765   NOTIMPLEMENTED();
3766   return error::kNoError;
3767 }
3768 
DoInsertEventMarkerEXT(GLsizei length,const char * marker)3769 error::Error GLES2DecoderPassthroughImpl::DoInsertEventMarkerEXT(
3770     GLsizei length,
3771     const char* marker) {
3772   api()->glInsertEventMarkerEXTFn(length, marker);
3773   return error::kNoError;
3774 }
3775 
DoPushGroupMarkerEXT(GLsizei length,const char * marker)3776 error::Error GLES2DecoderPassthroughImpl::DoPushGroupMarkerEXT(
3777     GLsizei length,
3778     const char* marker) {
3779   api()->glPushGroupMarkerEXTFn(length, marker);
3780   return error::kNoError;
3781 }
3782 
DoPopGroupMarkerEXT()3783 error::Error GLES2DecoderPassthroughImpl::DoPopGroupMarkerEXT() {
3784   api()->glPopGroupMarkerEXTFn();
3785   return error::kNoError;
3786 }
3787 
DoGenVertexArraysOES(GLsizei n,volatile GLuint * arrays)3788 error::Error GLES2DecoderPassthroughImpl::DoGenVertexArraysOES(
3789     GLsizei n,
3790     volatile GLuint* arrays) {
3791   return GenHelper(n, arrays, &vertex_array_id_map_,
3792                    [this](GLsizei n, GLuint* arrays) {
3793                      api()->glGenVertexArraysOESFn(n, arrays);
3794                    });
3795 }
3796 
DoDeleteVertexArraysOES(GLsizei n,const volatile GLuint * arrays)3797 error::Error GLES2DecoderPassthroughImpl::DoDeleteVertexArraysOES(
3798     GLsizei n,
3799     const volatile GLuint* arrays) {
3800   return DeleteHelper(n, arrays, &vertex_array_id_map_,
3801                       [this](GLsizei n, GLuint* arrays) {
3802                         api()->glDeleteVertexArraysOESFn(n, arrays);
3803                       });
3804 }
3805 
DoIsVertexArrayOES(GLuint array,uint32_t * result)3806 error::Error GLES2DecoderPassthroughImpl::DoIsVertexArrayOES(GLuint array,
3807                                                              uint32_t* result) {
3808   *result = api()->glIsVertexArrayOESFn(
3809       GetVertexArrayServiceID(array, &vertex_array_id_map_));
3810   return error::kNoError;
3811 }
3812 
DoBindVertexArrayOES(GLuint array)3813 error::Error GLES2DecoderPassthroughImpl::DoBindVertexArrayOES(GLuint array) {
3814   api()->glBindVertexArrayOESFn(
3815       GetVertexArrayServiceID(array, &vertex_array_id_map_));
3816   return error::kNoError;
3817 }
3818 
DoSwapBuffers(uint64_t swap_id,GLbitfield flags)3819 error::Error GLES2DecoderPassthroughImpl::DoSwapBuffers(uint64_t swap_id,
3820                                                         GLbitfield flags) {
3821   ca_layer_shared_state_ = nullptr;
3822 
3823   if (offscreen_) {
3824     if (offscreen_single_buffer_) {
3825       return error::kNoError;
3826     }
3827 
3828     DCHECK(emulated_back_buffer_);
3829 
3830     // Make sure the emulated front buffer is allocated and the correct size
3831     if (emulated_front_buffer_ &&
3832         emulated_front_buffer_->size != emulated_back_buffer_->size) {
3833       emulated_front_buffer_->Destroy(true);
3834       emulated_front_buffer_ = nullptr;
3835     }
3836 
3837     if (emulated_front_buffer_ == nullptr) {
3838       if (!available_color_textures_.empty()) {
3839         emulated_front_buffer_ = std::move(available_color_textures_.back());
3840         available_color_textures_.pop_back();
3841       } else {
3842         emulated_front_buffer_ = std::make_unique<EmulatedColorBuffer>(
3843             api(), emulated_default_framebuffer_format_);
3844         emulated_front_buffer_->Resize(emulated_back_buffer_->size);
3845       }
3846     }
3847 
3848     DCHECK_EQ(emulated_front_buffer_->size, emulated_back_buffer_->size);
3849 
3850     if (emulated_default_framebuffer_format_.samples > 0) {
3851       // Resolve the multisampled renderbuffer into the emulated_front_buffer_
3852       emulated_back_buffer_->Blit(emulated_front_buffer_.get());
3853     } else {
3854       DCHECK(emulated_back_buffer_->color_texture != nullptr);
3855       // If the offscreen buffer should be preserved, copy the old backbuffer
3856       // into the new one
3857       if (offscreen_target_buffer_preserved_) {
3858         emulated_back_buffer_->Blit(emulated_front_buffer_.get());
3859       }
3860 
3861       // Swap the front and back buffer textures and update the framebuffer
3862       // attachment.
3863       std::unique_ptr<EmulatedColorBuffer> old_front_buffer =
3864           std::move(emulated_front_buffer_);
3865       emulated_front_buffer_ =
3866           emulated_back_buffer_->SetColorBuffer(std::move(old_front_buffer));
3867     }
3868 
3869     return error::kNoError;
3870   }
3871 
3872   client()->OnSwapBuffers(swap_id, flags);
3873   if (surface_->SupportsAsyncSwap()) {
3874     TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id);
3875     surface_->SwapBuffersAsync(
3876         base::BindOnce(
3877             &GLES2DecoderPassthroughImpl::CheckSwapBuffersAsyncResult,
3878             weak_ptr_factory_.GetWeakPtr(), "SwapBuffers", swap_id),
3879         base::DoNothing());
3880     return error::kNoError;
3881   } else {
3882     return CheckSwapBuffersResult(surface_->SwapBuffers(base::DoNothing()),
3883                                   "SwapBuffers");
3884   }
3885 }
3886 
DoGetMaxValueInBufferCHROMIUM(GLuint buffer_id,GLsizei count,GLenum type,GLuint offset,uint32_t * result)3887 error::Error GLES2DecoderPassthroughImpl::DoGetMaxValueInBufferCHROMIUM(
3888     GLuint buffer_id,
3889     GLsizei count,
3890     GLenum type,
3891     GLuint offset,
3892     uint32_t* result) {
3893   NOTIMPLEMENTED();
3894   return error::kNoError;
3895 }
3896 
DoEnableFeatureCHROMIUM(const char * feature)3897 error::Error GLES2DecoderPassthroughImpl::DoEnableFeatureCHROMIUM(
3898     const char* feature) {
3899   NOTIMPLEMENTED();
3900   return error::kNoError;
3901 }
3902 
DoMapBufferRange(GLenum target,GLintptr offset,GLsizeiptr size,GLbitfield access,void * ptr,int32_t data_shm_id,uint32_t data_shm_offset,uint32_t * result)3903 error::Error GLES2DecoderPassthroughImpl::DoMapBufferRange(
3904     GLenum target,
3905     GLintptr offset,
3906     GLsizeiptr size,
3907     GLbitfield access,
3908     void* ptr,
3909     int32_t data_shm_id,
3910     uint32_t data_shm_offset,
3911     uint32_t* result) {
3912   CheckErrorCallbackState();
3913 
3914   GLbitfield filtered_access = access;
3915 
3916   // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined
3917   // behaviors.
3918   filtered_access = (filtered_access & ~GL_MAP_UNSYNCHRONIZED_BIT);
3919 
3920   if ((filtered_access & GL_MAP_INVALIDATE_BUFFER_BIT) != 0) {
3921     // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
3922     // GL_MAP_INVALIDATE_RANGE_BIT.
3923     filtered_access = (filtered_access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
3924     filtered_access = (filtered_access | GL_MAP_INVALIDATE_RANGE_BIT);
3925   }
3926   if ((filtered_access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
3927     // If this user intends to use this buffer without invalidating the data, we
3928     // need to also add GL_MAP_READ_BIT to preserve the original data when
3929     // copying it to shared memory.
3930     filtered_access = (filtered_access | GL_MAP_READ_BIT);
3931   }
3932 
3933   void* mapped_ptr =
3934       api()->glMapBufferRangeFn(target, offset, size, filtered_access);
3935   if (CheckErrorCallbackState() || mapped_ptr == nullptr) {
3936     // Had an error while mapping, don't copy any data
3937     *result = 0;
3938     return error::kNoError;
3939   }
3940 
3941   if ((filtered_access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
3942     memcpy(ptr, mapped_ptr, size);
3943   }
3944 
3945   // Track the mapping of this buffer so that data can be synchronized when it
3946   // is unmapped
3947   DCHECK(bound_buffers_.find(target) != bound_buffers_.end());
3948   GLuint client_buffer = bound_buffers_.at(target);
3949 
3950   MappedBuffer mapped_buffer_info;
3951   mapped_buffer_info.size = size;
3952   mapped_buffer_info.original_access = access;
3953   mapped_buffer_info.filtered_access = filtered_access;
3954   mapped_buffer_info.map_ptr = static_cast<uint8_t*>(mapped_ptr);
3955   mapped_buffer_info.data_shm_id = data_shm_id;
3956   mapped_buffer_info.data_shm_offset = data_shm_offset;
3957 
3958   DCHECK(resources_->mapped_buffer_map.find(client_buffer) ==
3959          resources_->mapped_buffer_map.end());
3960   resources_->mapped_buffer_map.insert(
3961       std::make_pair(client_buffer, mapped_buffer_info));
3962 
3963   *result = 1;
3964   return error::kNoError;
3965 }
3966 
DoUnmapBuffer(GLenum target)3967 error::Error GLES2DecoderPassthroughImpl::DoUnmapBuffer(GLenum target) {
3968   auto bound_buffers_iter = bound_buffers_.find(target);
3969   if (bound_buffers_iter == bound_buffers_.end()) {
3970     InsertError(GL_INVALID_ENUM, "Invalid buffer target.");
3971     return error::kNoError;
3972   }
3973 
3974   if (bound_buffers_iter->second == 0) {
3975     InsertError(GL_INVALID_OPERATION, "No buffer bound to this target.");
3976     return error::kNoError;
3977   }
3978 
3979   GLuint client_buffer = bound_buffers_iter->second;
3980   auto mapped_buffer_info_iter =
3981       resources_->mapped_buffer_map.find(client_buffer);
3982   if (mapped_buffer_info_iter == resources_->mapped_buffer_map.end()) {
3983     InsertError(GL_INVALID_OPERATION, "Buffer is not mapped.");
3984     return error::kNoError;
3985   }
3986 
3987   const MappedBuffer& map_info = mapped_buffer_info_iter->second;
3988   if ((map_info.filtered_access & GL_MAP_WRITE_BIT) != 0 &&
3989       (map_info.filtered_access & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
3990     uint8_t* mem = GetSharedMemoryAs<uint8_t*>(
3991         map_info.data_shm_id, map_info.data_shm_offset, map_info.size);
3992     if (!mem) {
3993       return error::kOutOfBounds;
3994     }
3995 
3996     memcpy(map_info.map_ptr, mem, map_info.size);
3997   }
3998 
3999   api()->glUnmapBufferFn(target);
4000 
4001   resources_->mapped_buffer_map.erase(mapped_buffer_info_iter);
4002 
4003   return error::kNoError;
4004 }
4005 
DoResizeCHROMIUM(GLuint width,GLuint height,GLfloat scale_factor,gfx::ColorSpace color_space,GLboolean alpha)4006 error::Error GLES2DecoderPassthroughImpl::DoResizeCHROMIUM(
4007     GLuint width,
4008     GLuint height,
4009     GLfloat scale_factor,
4010     gfx::ColorSpace color_space,
4011     GLboolean alpha) {
4012   // gfx::Size uses integers, make sure width and height do not overflow
4013   static_assert(sizeof(GLuint) >= sizeof(int), "Unexpected GLuint size.");
4014   static const GLuint kMaxDimension =
4015       static_cast<GLuint>(std::numeric_limits<int>::max());
4016   gfx::Size safe_size(base::ClampToRange(width, 1U, kMaxDimension),
4017                       base::ClampToRange(height, 1U, kMaxDimension));
4018   if (offscreen_) {
4019     if (!ResizeOffscreenFramebuffer(safe_size)) {
4020       LOG(ERROR) << "GLES2DecoderPassthroughImpl: Context lost because "
4021                  << "ResizeOffscreenFramebuffer failed.";
4022       return error::kLostContext;
4023     }
4024   } else {
4025     if (!surface_->Resize(safe_size, scale_factor, color_space, !!alpha)) {
4026       LOG(ERROR)
4027           << "GLES2DecoderPassthroughImpl: Context lost because resize failed.";
4028       return error::kLostContext;
4029     }
4030     DCHECK(context_->IsCurrent(surface_.get()));
4031     if (!context_->IsCurrent(surface_.get())) {
4032       LOG(ERROR) << "GLES2DecoderPassthroughImpl: Context lost because context "
4033                     "no longer current after resize callback.";
4034       return error::kLostContext;
4035     }
4036   }
4037   return error::kNoError;
4038 }
4039 
DoGetRequestableExtensionsCHROMIUM(const char ** extensions)4040 error::Error GLES2DecoderPassthroughImpl::DoGetRequestableExtensionsCHROMIUM(
4041     const char** extensions) {
4042   *extensions = reinterpret_cast<const char*>(
4043       api()->glGetStringFn(GL_REQUESTABLE_EXTENSIONS_ANGLE));
4044   return error::kNoError;
4045 }
4046 
DoRequestExtensionCHROMIUM(const char * extension)4047 error::Error GLES2DecoderPassthroughImpl::DoRequestExtensionCHROMIUM(
4048     const char* extension) {
4049   api()->glRequestExtensionANGLEFn(extension);
4050 
4051   // Make sure there are no pending GL errors before re-initializing feature
4052   // info
4053   FlushErrors();
4054 
4055   // Make sure newly enabled extensions are exposed and usable.
4056   context_->ReinitializeDynamicBindings();
4057   InitializeFeatureInfo(feature_info_->context_type(),
4058                         feature_info_->disallowed_features(), true);
4059 
4060   // Support for CHROMIUM_texture_storage_image depends on the underlying
4061   // ImageFactory's ability to create anonymous images.
4062   gpu::ImageFactory* image_factory = group_->image_factory();
4063   if (image_factory && image_factory->SupportsCreateAnonymousImage()) {
4064     feature_info_->EnableCHROMIUMTextureStorageImage();
4065   }
4066 
4067   return error::kNoError;
4068 }
4069 
DoGetProgramInfoCHROMIUM(GLuint program,std::vector<uint8_t> * data)4070 error::Error GLES2DecoderPassthroughImpl::DoGetProgramInfoCHROMIUM(
4071     GLuint program,
4072     std::vector<uint8_t>* data) {
4073   GLuint service_program = 0;
4074   if (!resources_->program_id_map.GetServiceID(program, &service_program)) {
4075     return error::kNoError;
4076   }
4077 
4078   GLint num_attributes = 0;
4079   api()->glGetProgramivFn(service_program, GL_ACTIVE_ATTRIBUTES,
4080                           &num_attributes);
4081 
4082   GLint num_uniforms = 0;
4083   api()->glGetProgramivFn(service_program, GL_ACTIVE_UNIFORMS, &num_uniforms);
4084 
4085   const base::CheckedNumeric<size_t> buffer_header_size(
4086       sizeof(ProgramInfoHeader));
4087   const base::CheckedNumeric<size_t> buffer_block_size(sizeof(ProgramInput));
4088   const base::CheckedNumeric<size_t> attribute_block_size =
4089       buffer_block_size * num_attributes;
4090   const base::CheckedNumeric<size_t> uniform_block_size =
4091       buffer_block_size * num_uniforms;
4092   data->resize((buffer_header_size + attribute_block_size + uniform_block_size)
4093                    .ValueOrDie(),
4094                0);
4095 
4096   GLint link_status = 0;
4097   api()->glGetProgramivFn(service_program, GL_LINK_STATUS, &link_status);
4098 
4099   ProgramInfoHeader header;
4100   header.link_status = link_status;
4101   header.num_attribs = num_attributes;
4102   header.num_uniforms = num_uniforms;
4103   InsertValueIntoBuffer(data, header, 0);
4104 
4105   GLint active_attribute_max_length = 0;
4106   api()->glGetProgramivFn(service_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
4107                           &active_attribute_max_length);
4108 
4109   std::vector<char> attrib_name_buf(active_attribute_max_length, 0);
4110   for (GLint attrib_index = 0; attrib_index < num_attributes; attrib_index++) {
4111     GLsizei length = 0;
4112     GLint size = 0;
4113     GLenum type = GL_NONE;
4114     api()->glGetActiveAttribFn(service_program, attrib_index,
4115                                attrib_name_buf.size(), &length, &size, &type,
4116                                attrib_name_buf.data());
4117 
4118     ProgramInput input;
4119     input.size = size;
4120     input.type = type;
4121 
4122     int32_t location =
4123         api()->glGetAttribLocationFn(service_program, attrib_name_buf.data());
4124     input.location_offset = data->size();
4125     AppendValueToBuffer(data, location);
4126 
4127     input.name_offset = data->size();
4128     input.name_length = length;
4129     AppendStringToBuffer(data, attrib_name_buf.data(), length);
4130 
4131     InsertValueIntoBuffer(
4132         data, input,
4133         (buffer_header_size + (buffer_block_size * attrib_index)).ValueOrDie());
4134   }
4135 
4136   GLint active_uniform_max_length = 0;
4137   api()->glGetProgramivFn(service_program, GL_ACTIVE_UNIFORM_MAX_LENGTH,
4138                           &active_uniform_max_length);
4139 
4140   std::vector<char> uniform_name_buf(active_uniform_max_length, 0);
4141   for (GLint uniform_index = 0; uniform_index < num_uniforms; uniform_index++) {
4142     GLsizei length = 0;
4143     GLint size = 0;
4144     GLenum type = GL_NONE;
4145     api()->glGetActiveUniformFn(service_program, uniform_index,
4146                                 uniform_name_buf.size(), &length, &size, &type,
4147                                 uniform_name_buf.data());
4148 
4149     ProgramInput input;
4150     input.size = size;
4151     input.type = type;
4152 
4153     input.location_offset = data->size();
4154     int32_t base_location =
4155         api()->glGetUniformLocationFn(service_program, uniform_name_buf.data());
4156     AppendValueToBuffer(data, base_location);
4157 
4158     GLSLArrayName parsed_service_name(uniform_name_buf.data());
4159     if (size > 1 || parsed_service_name.IsArrayName()) {
4160       for (GLint location_index = 1; location_index < size; location_index++) {
4161         std::string array_element_name = parsed_service_name.base_name() + "[" +
4162                                          base::NumberToString(location_index) +
4163                                          "]";
4164         int32_t element_location = api()->glGetUniformLocationFn(
4165             service_program, array_element_name.c_str());
4166         AppendValueToBuffer(data, element_location);
4167       }
4168     }
4169 
4170     input.name_offset = data->size();
4171     input.name_length = length;
4172     AppendStringToBuffer(data, uniform_name_buf.data(), length);
4173 
4174     InsertValueIntoBuffer(data, input,
4175                           (buffer_header_size + attribute_block_size +
4176                            (buffer_block_size * uniform_index))
4177                               .ValueOrDie());
4178   }
4179 
4180   return error::kNoError;
4181 }
4182 
DoGetUniformBlocksCHROMIUM(GLuint program,std::vector<uint8_t> * data)4183 error::Error GLES2DecoderPassthroughImpl::DoGetUniformBlocksCHROMIUM(
4184     GLuint program,
4185     std::vector<uint8_t>* data) {
4186   GLuint service_program = 0;
4187   if (!resources_->program_id_map.GetServiceID(program, &service_program)) {
4188     return error::kNoError;
4189   }
4190 
4191   GLint num_uniform_blocks = 0;
4192   api()->glGetProgramivFn(service_program, GL_ACTIVE_UNIFORM_BLOCKS,
4193                           &num_uniform_blocks);
4194 
4195   // Resize the data to fit the headers and info objects so that strings can be
4196   // appended.
4197   const base::CheckedNumeric<size_t> buffer_header_size(
4198       sizeof(UniformBlocksHeader));
4199   const base::CheckedNumeric<size_t> buffer_block_size(
4200       sizeof(UniformBlockInfo));
4201   data->resize((buffer_header_size + (num_uniform_blocks * buffer_block_size))
4202                    .ValueOrDie(),
4203                0);
4204 
4205   UniformBlocksHeader header;
4206   header.num_uniform_blocks = num_uniform_blocks;
4207   InsertValueIntoBuffer(data, header, 0);
4208 
4209   GLint active_uniform_block_max_length = 0;
4210   api()->glGetProgramivFn(service_program,
4211                           GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH,
4212                           &active_uniform_block_max_length);
4213 
4214   std::vector<char> uniform_block_name_buf(active_uniform_block_max_length, 0);
4215   for (GLint uniform_block_index = 0; uniform_block_index < num_uniform_blocks;
4216        uniform_block_index++) {
4217     UniformBlockInfo block_info;
4218 
4219     GLint uniform_block_binding = 0;
4220     api()->glGetActiveUniformBlockivFn(service_program, uniform_block_index,
4221                                        GL_UNIFORM_BLOCK_BINDING,
4222                                        &uniform_block_binding);
4223     block_info.binding = uniform_block_binding;
4224 
4225     GLint uniform_block_data_size = 0;
4226     api()->glGetActiveUniformBlockivFn(service_program, uniform_block_index,
4227                                        GL_UNIFORM_BLOCK_DATA_SIZE,
4228                                        &uniform_block_data_size);
4229     block_info.data_size = uniform_block_data_size;
4230 
4231     GLint uniform_block_name_length = 0;
4232     api()->glGetActiveUniformBlockNameFn(
4233         service_program, uniform_block_index, active_uniform_block_max_length,
4234         &uniform_block_name_length, uniform_block_name_buf.data());
4235 
4236     DCHECK(uniform_block_name_length + 1 <= active_uniform_block_max_length);
4237     block_info.name_offset = data->size();
4238     block_info.name_length = uniform_block_name_length + 1;
4239     AppendStringToBuffer(data, uniform_block_name_buf.data(),
4240                          uniform_block_name_length + 1);
4241 
4242     GLint uniform_block_active_uniforms = 0;
4243     api()->glGetActiveUniformBlockivFn(service_program, uniform_block_index,
4244                                        GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
4245                                        &uniform_block_active_uniforms);
4246     block_info.active_uniforms = uniform_block_active_uniforms;
4247 
4248     std::vector<GLint> uniform_block_indices_buf(uniform_block_active_uniforms,
4249                                                  0);
4250     api()->glGetActiveUniformBlockivFn(service_program, uniform_block_index,
4251                                        GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
4252                                        uniform_block_indices_buf.data());
4253     block_info.active_uniform_offset = data->size();
4254     for (GLint uniform_block_uniform_index_index = 0;
4255          uniform_block_uniform_index_index < uniform_block_active_uniforms;
4256          uniform_block_uniform_index_index++) {
4257       AppendValueToBuffer(
4258           data,
4259           static_cast<uint32_t>(
4260               uniform_block_indices_buf[uniform_block_uniform_index_index]));
4261     }
4262 
4263     GLint uniform_block_referenced_by_vertex_shader = 0;
4264     api()->glGetActiveUniformBlockivFn(
4265         service_program, uniform_block_index,
4266         GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER,
4267         &uniform_block_referenced_by_vertex_shader);
4268     block_info.referenced_by_vertex_shader =
4269         uniform_block_referenced_by_vertex_shader;
4270 
4271     GLint uniform_block_referenced_by_fragment_shader = 0;
4272     api()->glGetActiveUniformBlockivFn(
4273         service_program, uniform_block_index,
4274         GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER,
4275         &uniform_block_referenced_by_fragment_shader);
4276     block_info.referenced_by_fragment_shader =
4277         uniform_block_referenced_by_fragment_shader;
4278 
4279     InsertValueIntoBuffer(
4280         data, block_info,
4281         (buffer_header_size + (buffer_block_size * uniform_block_index))
4282             .ValueOrDie());
4283   }
4284 
4285   return error::kNoError;
4286 }
4287 
4288 error::Error
DoGetTransformFeedbackVaryingsCHROMIUM(GLuint program,std::vector<uint8_t> * data)4289 GLES2DecoderPassthroughImpl::DoGetTransformFeedbackVaryingsCHROMIUM(
4290     GLuint program,
4291     std::vector<uint8_t>* data) {
4292   GLuint service_program = 0;
4293   if (!resources_->program_id_map.GetServiceID(program, &service_program)) {
4294     return error::kNoError;
4295   }
4296 
4297   GLint transform_feedback_buffer_mode = 0;
4298   api()->glGetProgramivFn(service_program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE,
4299                           &transform_feedback_buffer_mode);
4300 
4301   GLint num_transform_feedback_varyings = 0;
4302   api()->glGetProgramivFn(service_program, GL_TRANSFORM_FEEDBACK_VARYINGS,
4303                           &num_transform_feedback_varyings);
4304 
4305   // Resize the data to fit the headers and info objects so that strings can be
4306   // appended.
4307   const base::CheckedNumeric<size_t> buffer_header_size(
4308       sizeof(TransformFeedbackVaryingsHeader));
4309   const base::CheckedNumeric<size_t> buffer_block_size(
4310       sizeof(TransformFeedbackVaryingInfo));
4311   data->resize((buffer_header_size +
4312                 (num_transform_feedback_varyings * buffer_block_size))
4313                    .ValueOrDie(),
4314                0);
4315 
4316   TransformFeedbackVaryingsHeader header;
4317   header.transform_feedback_buffer_mode = transform_feedback_buffer_mode;
4318   header.num_transform_feedback_varyings = num_transform_feedback_varyings;
4319   InsertValueIntoBuffer(data, header, 0);
4320 
4321   GLint max_transform_feedback_varying_length = 0;
4322   api()->glGetProgramivFn(service_program,
4323                           GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH,
4324                           &max_transform_feedback_varying_length);
4325 
4326   std::vector<char> transform_feedback_varying_name_buf(
4327       max_transform_feedback_varying_length, 0);
4328   for (GLint transform_feedback_varying_index = 0;
4329        transform_feedback_varying_index < num_transform_feedback_varyings;
4330        transform_feedback_varying_index++) {
4331     GLsizei length = 0;
4332     GLint size = 0;
4333     GLenum type = GL_NONE;
4334     api()->glGetTransformFeedbackVaryingFn(
4335         service_program, transform_feedback_varying_index,
4336         max_transform_feedback_varying_length, &length, &size, &type,
4337         transform_feedback_varying_name_buf.data());
4338 
4339     TransformFeedbackVaryingInfo varying_info;
4340     varying_info.size = size;
4341     varying_info.type = type;
4342 
4343     DCHECK(length + 1 <= max_transform_feedback_varying_length);
4344     varying_info.name_length = data->size();
4345     varying_info.name_length = length + 1;
4346     AppendStringToBuffer(data, transform_feedback_varying_name_buf.data(),
4347                          length + 1);
4348 
4349     InsertValueIntoBuffer(
4350         data, varying_info,
4351         (buffer_header_size +
4352          (buffer_block_size * transform_feedback_varying_index))
4353             .ValueOrDie());
4354   }
4355 
4356   return error::kNoError;
4357 }
4358 
DoGetUniformsES3CHROMIUM(GLuint program,std::vector<uint8_t> * data)4359 error::Error GLES2DecoderPassthroughImpl::DoGetUniformsES3CHROMIUM(
4360     GLuint program,
4361     std::vector<uint8_t>* data) {
4362   GLuint service_program = 0;
4363   if (!resources_->program_id_map.GetServiceID(program, &service_program)) {
4364     return error::kNoError;
4365   }
4366 
4367   GLint num_uniforms = 0;
4368   api()->glGetProgramivFn(service_program, GL_ACTIVE_UNIFORMS, &num_uniforms);
4369 
4370   UniformsES3Header header;
4371   header.num_uniforms = num_uniforms;
4372   AppendValueToBuffer(data, header);
4373 
4374   for (GLuint uniform_index = 0;
4375        uniform_index < static_cast<GLuint>(num_uniforms); uniform_index++) {
4376     UniformES3Info uniform_info;
4377 
4378     GLint uniform_block_index = 0;
4379     api()->glGetActiveUniformsivFn(service_program, 1, &uniform_index,
4380                                    GL_UNIFORM_BLOCK_INDEX,
4381                                    &uniform_block_index);
4382     uniform_info.block_index = uniform_block_index;
4383 
4384     GLint uniform_offset = 0;
4385     api()->glGetActiveUniformsivFn(service_program, 1, &uniform_index,
4386                                    GL_UNIFORM_OFFSET, &uniform_offset);
4387     uniform_info.offset = uniform_offset;
4388 
4389     GLint uniform_array_stride = 0;
4390     api()->glGetActiveUniformsivFn(service_program, 1, &uniform_index,
4391                                    GL_UNIFORM_ARRAY_STRIDE,
4392                                    &uniform_array_stride);
4393     uniform_info.array_stride = uniform_array_stride;
4394 
4395     GLint uniform_matrix_stride = 0;
4396     api()->glGetActiveUniformsivFn(service_program, 1, &uniform_index,
4397                                    GL_UNIFORM_MATRIX_STRIDE,
4398                                    &uniform_matrix_stride);
4399     uniform_info.matrix_stride = uniform_matrix_stride;
4400 
4401     GLint uniform_is_row_major = 0;
4402     api()->glGetActiveUniformsivFn(service_program, 1, &uniform_index,
4403                                    GL_UNIFORM_IS_ROW_MAJOR,
4404                                    &uniform_is_row_major);
4405     uniform_info.is_row_major = uniform_is_row_major;
4406 
4407     AppendValueToBuffer(data, uniform_info);
4408   }
4409 
4410   return error::kNoError;
4411 }
4412 
DoGetTranslatedShaderSourceANGLE(GLuint shader,std::string * source)4413 error::Error GLES2DecoderPassthroughImpl::DoGetTranslatedShaderSourceANGLE(
4414     GLuint shader,
4415     std::string* source) {
4416   CheckErrorCallbackState();
4417   GLuint service_id = GetShaderServiceID(shader, resources_);
4418   GLint translated_source_length = 0;
4419   api()->glGetShaderivFn(service_id, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE,
4420                          &translated_source_length);
4421   if (CheckErrorCallbackState()) {
4422     return error::kNoError;
4423   }
4424 
4425   if (translated_source_length > 0) {
4426     std::vector<char> buffer(translated_source_length, 0);
4427     GLsizei length = 0;
4428     api()->glGetTranslatedShaderSourceANGLEFn(
4429         service_id, translated_source_length, &length, buffer.data());
4430     DCHECK(length <= translated_source_length);
4431     *source = length > 0 ? std::string(buffer.data(), length) : std::string();
4432   } else {
4433     *source = std::string();
4434   }
4435   return error::kNoError;
4436 }
4437 
DoSwapBuffersWithBoundsCHROMIUM(uint64_t swap_id,GLsizei count,const volatile GLint * rects,GLbitfield flags)4438 error::Error GLES2DecoderPassthroughImpl::DoSwapBuffersWithBoundsCHROMIUM(
4439     uint64_t swap_id,
4440     GLsizei count,
4441     const volatile GLint* rects,
4442     GLbitfield flags) {
4443   if (count < 0) {
4444     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
4445     return error::kNoError;
4446   }
4447 
4448   ca_layer_shared_state_ = nullptr;
4449 
4450   std::vector<gfx::Rect> bounds(count);
4451   for (GLsizei i = 0; i < count; ++i) {
4452     bounds[i] = gfx::Rect(rects[i * 4 + 0], rects[i * 4 + 1], rects[i * 4 + 2],
4453                           rects[i * 4 + 3]);
4454   }
4455 
4456   client()->OnSwapBuffers(swap_id, flags);
4457   return CheckSwapBuffersResult(
4458       surface_->SwapBuffersWithBounds(bounds, base::DoNothing()),
4459       "SwapBuffersWithBounds");
4460 }
4461 
DoPostSubBufferCHROMIUM(uint64_t swap_id,GLint x,GLint y,GLint width,GLint height,GLbitfield flags)4462 error::Error GLES2DecoderPassthroughImpl::DoPostSubBufferCHROMIUM(
4463     uint64_t swap_id,
4464     GLint x,
4465     GLint y,
4466     GLint width,
4467     GLint height,
4468     GLbitfield flags) {
4469   if (!surface_->SupportsPostSubBuffer()) {
4470     InsertError(GL_INVALID_OPERATION,
4471                 "glPostSubBufferCHROMIUM is not supported for this surface.");
4472     return error::kNoError;
4473   }
4474 
4475   ca_layer_shared_state_ = nullptr;
4476 
4477   client()->OnSwapBuffers(swap_id, flags);
4478   if (surface_->SupportsAsyncSwap()) {
4479     TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id);
4480     surface_->PostSubBufferAsync(
4481         x, y, width, height,
4482         base::BindOnce(
4483             &GLES2DecoderPassthroughImpl::CheckSwapBuffersAsyncResult,
4484             weak_ptr_factory_.GetWeakPtr(), "PostSubBuffer", swap_id),
4485         base::DoNothing());
4486     return error::kNoError;
4487   } else {
4488     return CheckSwapBuffersResult(
4489         surface_->PostSubBuffer(x, y, width, height, base::DoNothing()),
4490         "PostSubBuffer");
4491   }
4492 }
4493 
DoCopyTextureCHROMIUM(GLuint source_id,GLint source_level,GLenum dest_target,GLuint dest_id,GLint dest_level,GLint internalformat,GLenum dest_type,GLboolean unpack_flip_y,GLboolean unpack_premultiply_alpha,GLboolean unpack_unmultiply_alpha)4494 error::Error GLES2DecoderPassthroughImpl::DoCopyTextureCHROMIUM(
4495     GLuint source_id,
4496     GLint source_level,
4497     GLenum dest_target,
4498     GLuint dest_id,
4499     GLint dest_level,
4500     GLint internalformat,
4501     GLenum dest_type,
4502     GLboolean unpack_flip_y,
4503     GLboolean unpack_premultiply_alpha,
4504     GLboolean unpack_unmultiply_alpha) {
4505   ScopedEnableTextureRectangleInShaderCompiler enable(this);
4506   BindPendingImageForClientIDIfNeeded(source_id);
4507   api()->glCopyTextureCHROMIUMFn(
4508       GetTextureServiceID(api(), source_id, resources_, false), source_level,
4509       dest_target, GetTextureServiceID(api(), dest_id, resources_, false),
4510       dest_level, internalformat, dest_type, unpack_flip_y,
4511       unpack_premultiply_alpha, unpack_unmultiply_alpha);
4512 
4513   UpdateTextureSizeFromClientID(dest_id);
4514 
4515   return error::kNoError;
4516 }
4517 
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)4518 error::Error GLES2DecoderPassthroughImpl::DoCopySubTextureCHROMIUM(
4519     GLuint source_id,
4520     GLint source_level,
4521     GLenum dest_target,
4522     GLuint dest_id,
4523     GLint dest_level,
4524     GLint xoffset,
4525     GLint yoffset,
4526     GLint x,
4527     GLint y,
4528     GLsizei width,
4529     GLsizei height,
4530     GLboolean unpack_flip_y,
4531     GLboolean unpack_premultiply_alpha,
4532     GLboolean unpack_unmultiply_alpha) {
4533   ScopedEnableTextureRectangleInShaderCompiler enable(this);
4534   BindPendingImageForClientIDIfNeeded(source_id);
4535   api()->glCopySubTextureCHROMIUMFn(
4536       GetTextureServiceID(api(), source_id, resources_, false), source_level,
4537       dest_target, GetTextureServiceID(api(), dest_id, resources_, false),
4538       dest_level, xoffset, yoffset, x, y, width, height, unpack_flip_y,
4539       unpack_premultiply_alpha, unpack_unmultiply_alpha);
4540   return error::kNoError;
4541 }
4542 
DoDrawArraysInstancedANGLE(GLenum mode,GLint first,GLsizei count,GLsizei primcount)4543 error::Error GLES2DecoderPassthroughImpl::DoDrawArraysInstancedANGLE(
4544     GLenum mode,
4545     GLint first,
4546     GLsizei count,
4547     GLsizei primcount) {
4548   BindPendingImagesForSamplersIfNeeded();
4549   api()->glDrawArraysInstancedANGLEFn(mode, first, count, primcount);
4550   return error::kNoError;
4551 }
4552 
4553 error::Error
DoDrawArraysInstancedBaseInstanceANGLE(GLenum mode,GLint first,GLsizei count,GLsizei primcount,GLuint baseinstance)4554 GLES2DecoderPassthroughImpl::DoDrawArraysInstancedBaseInstanceANGLE(
4555     GLenum mode,
4556     GLint first,
4557     GLsizei count,
4558     GLsizei primcount,
4559     GLuint baseinstance) {
4560   BindPendingImagesForSamplersIfNeeded();
4561   api()->glDrawArraysInstancedBaseInstanceANGLEFn(mode, first, count, primcount,
4562                                                   baseinstance);
4563   return error::kNoError;
4564 }
4565 
DoDrawElementsInstancedANGLE(GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount)4566 error::Error GLES2DecoderPassthroughImpl::DoDrawElementsInstancedANGLE(
4567     GLenum mode,
4568     GLsizei count,
4569     GLenum type,
4570     const void* indices,
4571     GLsizei primcount) {
4572   BindPendingImagesForSamplersIfNeeded();
4573   api()->glDrawElementsInstancedANGLEFn(mode, count, type, indices, primcount);
4574   return error::kNoError;
4575 }
4576 
4577 error::Error
DoDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount,GLint basevertex,GLuint baseinstance)4578 GLES2DecoderPassthroughImpl::DoDrawElementsInstancedBaseVertexBaseInstanceANGLE(
4579     GLenum mode,
4580     GLsizei count,
4581     GLenum type,
4582     const void* indices,
4583     GLsizei primcount,
4584     GLint basevertex,
4585     GLuint baseinstance) {
4586   BindPendingImagesForSamplersIfNeeded();
4587   api()->glDrawElementsInstancedBaseVertexBaseInstanceANGLEFn(
4588       mode, count, type, indices, primcount, basevertex, baseinstance);
4589   return error::kNoError;
4590 }
4591 
DoVertexAttribDivisorANGLE(GLuint index,GLuint divisor)4592 error::Error GLES2DecoderPassthroughImpl::DoVertexAttribDivisorANGLE(
4593     GLuint index,
4594     GLuint divisor) {
4595   api()->glVertexAttribDivisorANGLEFn(index, divisor);
4596   return error::kNoError;
4597 }
4598 
DoProduceTextureDirectCHROMIUM(GLuint texture_client_id,const volatile GLbyte * mailbox)4599 error::Error GLES2DecoderPassthroughImpl::DoProduceTextureDirectCHROMIUM(
4600     GLuint texture_client_id,
4601     const volatile GLbyte* mailbox) {
4602   scoped_refptr<TexturePassthrough> texture = nullptr;
4603   if (!resources_->texture_object_map.GetServiceID(texture_client_id,
4604                                                    &texture) ||
4605       texture == nullptr) {
4606     InsertError(GL_INVALID_OPERATION, "Unknown texture.");
4607     return error::kNoError;
4608   }
4609 
4610   const Mailbox& mb = Mailbox::FromVolatile(
4611       *reinterpret_cast<const volatile Mailbox*>(mailbox));
4612   mailbox_manager_->ProduceTexture(mb, texture.get());
4613   return error::kNoError;
4614 }
4615 
DoCreateAndConsumeTextureINTERNAL(GLuint texture_client_id,const volatile GLbyte * mailbox)4616 error::Error GLES2DecoderPassthroughImpl::DoCreateAndConsumeTextureINTERNAL(
4617     GLuint texture_client_id,
4618     const volatile GLbyte* mailbox) {
4619   if (!texture_client_id ||
4620       resources_->texture_id_map.HasClientID(texture_client_id)) {
4621     return error::kInvalidArguments;
4622   }
4623 
4624   const Mailbox& mb = Mailbox::FromVolatile(
4625       *reinterpret_cast<const volatile Mailbox*>(mailbox));
4626   scoped_refptr<TexturePassthrough> texture = TexturePassthrough::CheckedCast(
4627       group_->mailbox_manager()->ConsumeTexture(mb));
4628   if (texture == nullptr) {
4629     // Create texture to handle invalid mailbox (see http://crbug.com/472465 and
4630     // http://crbug.com/851878).
4631     DoGenTextures(1, &texture_client_id);
4632     InsertError(GL_INVALID_OPERATION, "Invalid mailbox name.");
4633     return error::kNoError;
4634   }
4635 
4636   // Update id mappings
4637   resources_->texture_id_map.RemoveClientID(texture_client_id);
4638   resources_->texture_id_map.SetIDMapping(texture_client_id,
4639                                           texture->service_id());
4640   resources_->texture_object_map.RemoveClientID(texture_client_id);
4641   resources_->texture_object_map.SetIDMapping(texture_client_id, texture);
4642 
4643   return error::kNoError;
4644 }
4645 
DoBindUniformLocationCHROMIUM(GLuint program,GLint location,const char * name)4646 error::Error GLES2DecoderPassthroughImpl::DoBindUniformLocationCHROMIUM(
4647     GLuint program,
4648     GLint location,
4649     const char* name) {
4650   api()->glBindUniformLocationCHROMIUMFn(
4651       GetProgramServiceID(program, resources_), location, name);
4652   return error::kNoError;
4653 }
4654 
DoBindTexImage2DCHROMIUM(GLenum target,GLint imageId)4655 error::Error GLES2DecoderPassthroughImpl::DoBindTexImage2DCHROMIUM(
4656     GLenum target,
4657     GLint imageId) {
4658   return BindTexImage2DCHROMIUMImpl(target, 0, imageId);
4659 }
4660 
4661 error::Error
DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target,GLenum internalformat,GLint imageId)4662 GLES2DecoderPassthroughImpl::DoBindTexImage2DWithInternalformatCHROMIUM(
4663     GLenum target,
4664     GLenum internalformat,
4665     GLint imageId) {
4666   return BindTexImage2DCHROMIUMImpl(target, internalformat, imageId);
4667 }
4668 
DoReleaseTexImage2DCHROMIUM(GLenum target,GLint imageId)4669 error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM(
4670     GLenum target,
4671     GLint imageId) {
4672   TextureTarget target_enum = GLenumToTextureTarget(target);
4673   if (target_enum == TextureTarget::kCubeMap ||
4674       target_enum == TextureTarget::kUnkown) {
4675     InsertError(GL_INVALID_ENUM, "Invalid target");
4676     return error::kNoError;
4677   }
4678 
4679   const BoundTexture& bound_texture =
4680       bound_textures_[static_cast<size_t>(target_enum)][active_texture_unit_];
4681   if (bound_texture.texture == nullptr) {
4682     InsertError(GL_INVALID_OPERATION, "No texture bound");
4683     return error::kNoError;
4684   }
4685 
4686   gl::GLImage* image = group_->image_manager()->LookupImage(imageId);
4687   if (image == nullptr) {
4688     InsertError(GL_INVALID_OPERATION, "No image found with the given ID");
4689     return error::kNoError;
4690   }
4691 
4692   // Only release the image if it is currently bound
4693   if (bound_texture.texture->GetLevelImage(target, 0) == image) {
4694     image->ReleaseTexImage(target);
4695     bound_texture.texture->SetLevelImage(target, 0, nullptr);
4696   }
4697 
4698   // Target is already validated
4699   UpdateTextureSizeFromTarget(target);
4700 
4701   return error::kNoError;
4702 }
4703 
DoTraceBeginCHROMIUM(const char * category_name,const char * trace_name)4704 error::Error GLES2DecoderPassthroughImpl::DoTraceBeginCHROMIUM(
4705     const char* category_name,
4706     const char* trace_name) {
4707   if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
4708     InsertError(GL_INVALID_OPERATION, "Failed to create begin trace");
4709     return error::kNoError;
4710   }
4711   debug_marker_manager_.PushGroup(trace_name);
4712   return error::kNoError;
4713 }
4714 
DoTraceEndCHROMIUM()4715 error::Error GLES2DecoderPassthroughImpl::DoTraceEndCHROMIUM() {
4716   if (!gpu_tracer_->End(kTraceCHROMIUM)) {
4717     InsertError(GL_INVALID_OPERATION, "No trace to end");
4718     return error::kNoError;
4719   }
4720   debug_marker_manager_.PopGroup();
4721   return error::kNoError;
4722 }
4723 
DoDiscardFramebufferEXT(GLenum target,GLsizei count,const volatile GLenum * attachments)4724 error::Error GLES2DecoderPassthroughImpl::DoDiscardFramebufferEXT(
4725     GLenum target,
4726     GLsizei count,
4727     const volatile GLenum* attachments) {
4728   // Validate that count is non-negative before allocating a vector
4729   if (count < 0) {
4730     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
4731     return error::kNoError;
4732   }
4733   std::vector<GLenum> attachments_copy(attachments, attachments + count);
4734 
4735   if (feature_info_->gl_version_info().is_es3) {
4736     api()->glInvalidateFramebufferFn(target, count, attachments_copy.data());
4737   } else {
4738     api()->glDiscardFramebufferEXTFn(target, count, attachments_copy.data());
4739   }
4740 
4741   return error::kNoError;
4742 }
4743 
DoLoseContextCHROMIUM(GLenum current,GLenum other)4744 error::Error GLES2DecoderPassthroughImpl::DoLoseContextCHROMIUM(GLenum current,
4745                                                                 GLenum other) {
4746   if (!ValidContextLostReason(current) || !ValidContextLostReason(other)) {
4747     InsertError(GL_INVALID_ENUM, "invalid context loss reason.");
4748     return error::kNoError;
4749   }
4750 
4751   MarkContextLost(GetContextLostReasonFromResetStatus(current));
4752   group_->LoseContexts(GetContextLostReasonFromResetStatus(other));
4753   reset_by_robustness_extension_ = true;
4754   return error::kNoError;
4755 }
4756 
DoDescheduleUntilFinishedCHROMIUM()4757 error::Error GLES2DecoderPassthroughImpl::DoDescheduleUntilFinishedCHROMIUM() {
4758   if (!gl::GLFence::IsSupported()) {
4759     return error::kNoError;
4760   }
4761   deschedule_until_finished_fences_.push_back(gl::GLFence::Create());
4762 
4763   if (deschedule_until_finished_fences_.size() == 1) {
4764     return error::kNoError;
4765   }
4766 
4767   DCHECK_EQ(2u, deschedule_until_finished_fences_.size());
4768   if (deschedule_until_finished_fences_[0]->HasCompleted()) {
4769     deschedule_until_finished_fences_.erase(
4770         deschedule_until_finished_fences_.begin());
4771     return error::kNoError;
4772   }
4773 
4774   TRACE_EVENT_ASYNC_BEGIN0(
4775       "cc", "GLES2DecoderPassthroughImpl::DescheduleUntilFinished", this);
4776   client()->OnDescheduleUntilFinished();
4777   return error::kDeferLaterCommands;
4778 }
4779 
DoDrawBuffersEXT(GLsizei count,const volatile GLenum * bufs)4780 error::Error GLES2DecoderPassthroughImpl::DoDrawBuffersEXT(
4781     GLsizei count,
4782     const volatile GLenum* bufs) {
4783   if (!feature_info_->feature_flags().ext_draw_buffers &&
4784       !feature_info_->gl_version_info().is_es3) {
4785     return error::kUnknownCommand;
4786   }
4787 
4788   // Validate that count is non-negative before allocating a vector
4789   if (count < 0) {
4790     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
4791     return error::kNoError;
4792   }
4793   std::vector<GLenum> bufs_copy(bufs, bufs + count);
4794   api()->glDrawBuffersARBFn(count, bufs_copy.data());
4795   return error::kNoError;
4796 }
4797 
DoDiscardBackbufferCHROMIUM()4798 error::Error GLES2DecoderPassthroughImpl::DoDiscardBackbufferCHROMIUM() {
4799   NOTIMPLEMENTED();
4800   return error::kNoError;
4801 }
4802 
DoScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,GLenum plane_transform,GLuint overlay_texture_id,GLint bounds_x,GLint bounds_y,GLint bounds_width,GLint bounds_height,GLfloat uv_x,GLfloat uv_y,GLfloat uv_width,GLfloat uv_height,bool enable_blend,GLuint gpu_fence_id)4803 error::Error GLES2DecoderPassthroughImpl::DoScheduleOverlayPlaneCHROMIUM(
4804     GLint plane_z_order,
4805     GLenum plane_transform,
4806     GLuint overlay_texture_id,
4807     GLint bounds_x,
4808     GLint bounds_y,
4809     GLint bounds_width,
4810     GLint bounds_height,
4811     GLfloat uv_x,
4812     GLfloat uv_y,
4813     GLfloat uv_width,
4814     GLfloat uv_height,
4815     bool enable_blend,
4816     GLuint gpu_fence_id) {
4817   scoped_refptr<TexturePassthrough> passthrough_texture = nullptr;
4818   if (!resources_->texture_object_map.GetServiceID(overlay_texture_id,
4819                                                    &passthrough_texture) ||
4820       passthrough_texture == nullptr) {
4821     InsertError(GL_INVALID_VALUE, "invalid texture id");
4822     return error::kNoError;
4823   }
4824 
4825   gl::GLImage* image =
4826       passthrough_texture->GetLevelImage(passthrough_texture->target(), 0);
4827   if (!image) {
4828     InsertError(GL_INVALID_VALUE, "texture has no image");
4829     return error::kNoError;
4830   }
4831 
4832   gfx::OverlayTransform transform = GetGFXOverlayTransform(plane_transform);
4833   if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
4834     InsertError(GL_INVALID_ENUM, "invalid transform enum");
4835     return error::kNoError;
4836   }
4837 
4838   std::unique_ptr<gfx::GpuFence> gpu_fence;
4839   if (gpu_fence_id != 0) {
4840     gpu_fence = GetGpuFenceManager()->GetGpuFence(gpu_fence_id);
4841     if (!gpu_fence) {
4842       InsertError(GL_INVALID_ENUM, "unknown fence");
4843       return error::kNoError;
4844     }
4845   }
4846 
4847   if (!surface_->ScheduleOverlayPlane(
4848           plane_z_order, transform, image,
4849           gfx::Rect(bounds_x, bounds_y, bounds_width, bounds_height),
4850           gfx::RectF(uv_x, uv_y, uv_width, uv_height), enable_blend,
4851           std::move(gpu_fence))) {
4852     InsertError(GL_INVALID_OPERATION, "failed to schedule overlay");
4853     return error::kNoError;
4854   }
4855 
4856   return error::kNoError;
4857 }
4858 
DoScheduleCALayerSharedStateCHROMIUM(GLfloat opacity,GLboolean is_clipped,const GLfloat * clip_rect,const GLfloat * rounded_corner_bounds,GLint sorting_context_id,const GLfloat * transform)4859 error::Error GLES2DecoderPassthroughImpl::DoScheduleCALayerSharedStateCHROMIUM(
4860     GLfloat opacity,
4861     GLboolean is_clipped,
4862     const GLfloat* clip_rect,
4863     const GLfloat* rounded_corner_bounds,
4864     GLint sorting_context_id,
4865     const GLfloat* transform) {
4866   if (!ca_layer_shared_state_) {
4867     ca_layer_shared_state_.reset(new CALayerSharedState);
4868   }
4869 
4870   ca_layer_shared_state_->opacity = opacity;
4871   ca_layer_shared_state_->is_clipped = is_clipped;
4872   ca_layer_shared_state_->clip_rect = gfx::ToEnclosingRect(
4873       gfx::RectF(clip_rect[0], clip_rect[1], clip_rect[2], clip_rect[3]));
4874 
4875   ca_layer_shared_state_->rounded_corner_bounds =
4876       gfx::RRectF(rounded_corner_bounds[0], rounded_corner_bounds[1],
4877                   rounded_corner_bounds[2], rounded_corner_bounds[3],
4878                   rounded_corner_bounds[4]);
4879   ca_layer_shared_state_->sorting_context_id = sorting_context_id;
4880   ca_layer_shared_state_->transform =
4881       gfx::Transform(transform[0], transform[4], transform[8], transform[12],
4882                      transform[1], transform[5], transform[9], transform[13],
4883                      transform[2], transform[6], transform[10], transform[14],
4884                      transform[3], transform[7], transform[11], transform[15]);
4885   return error::kNoError;
4886 }
4887 
DoScheduleCALayerCHROMIUM(GLuint contents_texture_id,const GLfloat * contents_rect,GLuint background_color,GLuint edge_aa_mask,GLenum filter,const GLfloat * bounds_rect)4888 error::Error GLES2DecoderPassthroughImpl::DoScheduleCALayerCHROMIUM(
4889     GLuint contents_texture_id,
4890     const GLfloat* contents_rect,
4891     GLuint background_color,
4892     GLuint edge_aa_mask,
4893     GLenum filter,
4894     const GLfloat* bounds_rect) {
4895   if (!ca_layer_shared_state_) {
4896     InsertError(GL_INVALID_OPERATION,
4897                 "glScheduleCALayerSharedStateCHROMIUM has not been called");
4898     return error::kNoError;
4899   }
4900 
4901   gl::GLImage* image = nullptr;
4902   if (contents_texture_id) {
4903     scoped_refptr<TexturePassthrough> passthrough_texture;
4904     if (!resources_->texture_object_map.GetServiceID(contents_texture_id,
4905                                                      &passthrough_texture) ||
4906         passthrough_texture == nullptr) {
4907       InsertError(GL_INVALID_VALUE, "unknown texture");
4908       return error::kNoError;
4909     }
4910     DCHECK(passthrough_texture);
4911     image =
4912         passthrough_texture->GetLevelImage(passthrough_texture->target(), 0);
4913     if (!image) {
4914       InsertError(GL_INVALID_VALUE, "unsupported texture format");
4915       return error::kNoError;
4916     }
4917   }
4918 
4919   ui::CARendererLayerParams params = ui::CARendererLayerParams(
4920       ca_layer_shared_state_->is_clipped, ca_layer_shared_state_->clip_rect,
4921       ca_layer_shared_state_->rounded_corner_bounds,
4922       ca_layer_shared_state_->sorting_context_id,
4923       ca_layer_shared_state_->transform, image,
4924       gfx::RectF(contents_rect[0], contents_rect[1], contents_rect[2],
4925                  contents_rect[3]),
4926       gfx::ToEnclosingRect(gfx::RectF(bounds_rect[0], bounds_rect[1],
4927                                       bounds_rect[2], bounds_rect[3])),
4928       background_color, edge_aa_mask, ca_layer_shared_state_->opacity, filter);
4929   if (!surface_->ScheduleCALayer(params)) {
4930     InsertError(GL_INVALID_OPERATION, "failed to schedule CALayer");
4931     return error::kNoError;
4932   }
4933 
4934   return error::kNoError;
4935 }
4936 
DoScheduleCALayerInUseQueryCHROMIUM(GLsizei n,const volatile GLuint * textures)4937 error::Error GLES2DecoderPassthroughImpl::DoScheduleCALayerInUseQueryCHROMIUM(
4938     GLsizei n,
4939     const volatile GLuint* textures) {
4940   // Validate that count is non-negative before allocating a vector
4941   if (n < 0) {
4942     InsertError(GL_INVALID_VALUE, "count cannot be negative.");
4943     return error::kNoError;
4944   }
4945 
4946   std::vector<gl::GLSurface::CALayerInUseQuery> queries;
4947   queries.reserve(n);
4948   for (GLsizei i = 0; i < n; ++i) {
4949     gl::GLImage* image = nullptr;
4950     GLuint texture_id = textures[i];
4951     if (texture_id) {
4952       // If a |texture_id| is invalid (due to a client error), report that it
4953       // is not in use. Failing the GL call can result in compositor hangs.
4954       // https://crbug.com/1120795
4955       scoped_refptr<TexturePassthrough> passthrough_texture;
4956       if (resources_->texture_object_map.GetServiceID(texture_id,
4957                                                       &passthrough_texture)) {
4958         if (passthrough_texture) {
4959           image = passthrough_texture->GetLevelImage(
4960               passthrough_texture->target(), 0);
4961         }
4962       }
4963     }
4964     gl::GLSurface::CALayerInUseQuery query;
4965     query.image = image;
4966     query.texture = texture_id;
4967     queries.push_back(query);
4968   }
4969 
4970   surface_->ScheduleCALayerInUseQuery(std::move(queries));
4971   return error::kNoError;
4972 }
4973 
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)4974 error::Error GLES2DecoderPassthroughImpl::DoScheduleDCLayerCHROMIUM(
4975     GLuint texture_0,
4976     GLuint texture_1,
4977     GLint z_order,
4978     GLint content_x,
4979     GLint content_y,
4980     GLint content_width,
4981     GLint content_height,
4982     GLint quad_x,
4983     GLint quad_y,
4984     GLint quad_width,
4985     GLint quad_height,
4986     GLfloat transform_c1r1,
4987     GLfloat transform_c2r1,
4988     GLfloat transform_c1r2,
4989     GLfloat transform_c2r2,
4990     GLfloat transform_tx,
4991     GLfloat transform_ty,
4992     GLboolean is_clipped,
4993     GLint clip_x,
4994     GLint clip_y,
4995     GLint clip_width,
4996     GLint clip_height,
4997     GLuint protected_video_type) {
4998   if (protected_video_type >
4999       static_cast<GLuint>(gfx::ProtectedVideoType::kMaxValue)) {
5000     InsertError(GL_INVALID_VALUE, "invalid protected video type");
5001     return error::kNoError;
5002   }
5003 
5004   if (!texture_0) {
5005     InsertError(GL_INVALID_VALUE, "invalid texture");
5006     return error::kNoError;
5007   }
5008 
5009   ui::DCRendererLayerParams params;
5010   GLuint texture_ids[] = {texture_0, texture_1};
5011   size_t i = 0;
5012   for (GLuint texture_id : texture_ids) {
5013     if (!texture_id)
5014       break;
5015     scoped_refptr<TexturePassthrough> passthrough_texture;
5016     if (!resources_->texture_object_map.GetServiceID(texture_id,
5017                                                      &passthrough_texture) ||
5018         passthrough_texture == nullptr) {
5019       InsertError(GL_INVALID_VALUE, "unknown texture");
5020       return error::kNoError;
5021     }
5022     DCHECK(passthrough_texture);
5023     gl::GLImage* image =
5024         passthrough_texture->GetLevelImage(passthrough_texture->target(), 0);
5025     if (!image) {
5026       InsertError(GL_INVALID_VALUE, "unsupported texture format");
5027       return error::kNoError;
5028     }
5029     params.images[i++] = scoped_refptr<gl::GLImage>(image);
5030   }
5031   params.z_order = z_order;
5032   params.content_rect =
5033       gfx::Rect(content_x, content_y, content_width, content_height);
5034   params.quad_rect = gfx::Rect(quad_x, quad_y, quad_width, quad_height);
5035   params.transform =
5036       gfx::Transform(transform_c1r1, transform_c2r1, transform_c1r2,
5037                      transform_c2r2, transform_tx, transform_ty);
5038   params.is_clipped = is_clipped;
5039   params.clip_rect = gfx::Rect(clip_x, clip_y, clip_width, clip_height);
5040   params.protected_video_type =
5041       static_cast<gfx::ProtectedVideoType>(protected_video_type);
5042 
5043   if (!surface_->ScheduleDCLayer(params))
5044     InsertError(GL_INVALID_OPERATION, "failed to schedule DCLayer");
5045 
5046   return error::kNoError;
5047 }
5048 
DoCommitOverlayPlanesCHROMIUM(uint64_t swap_id,GLbitfield flags)5049 error::Error GLES2DecoderPassthroughImpl::DoCommitOverlayPlanesCHROMIUM(
5050     uint64_t swap_id,
5051     GLbitfield flags) {
5052   if (!surface_->SupportsCommitOverlayPlanes()) {
5053     InsertError(GL_INVALID_OPERATION,
5054                 "glCommitOverlayPlanes not supported by surface.");
5055     return error::kNoError;
5056   }
5057 
5058   ca_layer_shared_state_ = nullptr;
5059 
5060   client()->OnSwapBuffers(swap_id, flags);
5061   if (surface_->SupportsAsyncSwap()) {
5062     TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", swap_id);
5063     surface_->CommitOverlayPlanesAsync(
5064         base::BindOnce(
5065             &GLES2DecoderPassthroughImpl::CheckSwapBuffersAsyncResult,
5066             weak_ptr_factory_.GetWeakPtr(), "CommitOverlayPlanes", swap_id),
5067         base::DoNothing());
5068     return error::kNoError;
5069   } else {
5070     return CheckSwapBuffersResult(
5071         surface_->CommitOverlayPlanes(base::DoNothing()),
5072         "CommitOverlayPlanes");
5073   }
5074 }
5075 
DoSetColorSpaceMetadataCHROMIUM(GLuint texture_id,gfx::ColorSpace color_space)5076 error::Error GLES2DecoderPassthroughImpl::DoSetColorSpaceMetadataCHROMIUM(
5077     GLuint texture_id,
5078     gfx::ColorSpace color_space) {
5079   scoped_refptr<TexturePassthrough> passthrough_texture = nullptr;
5080   if (!resources_->texture_object_map.GetServiceID(texture_id,
5081                                                    &passthrough_texture) ||
5082       passthrough_texture == nullptr) {
5083     InsertError(GL_INVALID_VALUE, "unknown texture.");
5084     return error::kNoError;
5085   }
5086 
5087   scoped_refptr<gl::GLImage> image =
5088       passthrough_texture->GetLevelImage(passthrough_texture->target(), 0);
5089   if (image == nullptr) {
5090     InsertError(GL_INVALID_VALUE, "no image associated with texture.");
5091     return error::kNoError;
5092   }
5093 
5094   image->SetColorSpace(color_space);
5095   return error::kNoError;
5096 }
5097 
DoFlushDriverCachesCHROMIUM()5098 error::Error GLES2DecoderPassthroughImpl::DoFlushDriverCachesCHROMIUM() {
5099   // On Adreno Android devices we need to use a workaround to force caches to
5100   // clear.
5101   if (feature_info_->workarounds().unbind_egl_context_to_flush_driver_caches) {
5102     context_->ReleaseCurrent(nullptr);
5103     context_->MakeCurrent(surface_.get());
5104   }
5105   return error::kNoError;
5106 }
5107 
DoCoverageModulationCHROMIUM(GLenum components)5108 error::Error GLES2DecoderPassthroughImpl::DoCoverageModulationCHROMIUM(
5109     GLenum components) {
5110   NOTIMPLEMENTED();
5111   return error::kNoError;
5112 }
5113 
DoBlendBarrierKHR()5114 error::Error GLES2DecoderPassthroughImpl::DoBlendBarrierKHR() {
5115   NOTIMPLEMENTED();
5116   return error::kNoError;
5117 }
5118 
DoBindFragDataLocationIndexedEXT(GLuint program,GLuint colorNumber,GLuint index,const char * name)5119 error::Error GLES2DecoderPassthroughImpl::DoBindFragDataLocationIndexedEXT(
5120     GLuint program,
5121     GLuint colorNumber,
5122     GLuint index,
5123     const char* name) {
5124   api()->glBindFragDataLocationIndexedFn(
5125       GetProgramServiceID(program, resources_), colorNumber, index, name);
5126   return error::kNoError;
5127 }
5128 
DoBindFragDataLocationEXT(GLuint program,GLuint colorNumber,const char * name)5129 error::Error GLES2DecoderPassthroughImpl::DoBindFragDataLocationEXT(
5130     GLuint program,
5131     GLuint colorNumber,
5132     const char* name) {
5133   api()->glBindFragDataLocationFn(GetProgramServiceID(program, resources_),
5134                                   colorNumber, name);
5135   return error::kNoError;
5136 }
5137 
DoGetFragDataIndexEXT(GLuint program,const char * name,GLint * index)5138 error::Error GLES2DecoderPassthroughImpl::DoGetFragDataIndexEXT(
5139     GLuint program,
5140     const char* name,
5141     GLint* index) {
5142   *index = api()->glGetFragDataIndexFn(GetProgramServiceID(program, resources_),
5143                                        name);
5144   return error::kNoError;
5145 }
5146 
DoSetDrawRectangleCHROMIUM(GLint x,GLint y,GLint width,GLint height)5147 error::Error GLES2DecoderPassthroughImpl::DoSetDrawRectangleCHROMIUM(
5148     GLint x,
5149     GLint y,
5150     GLint width,
5151     GLint height) {
5152   GLint current_framebuffer = 0;
5153   api()->glGetIntegervFn(GL_FRAMEBUFFER_BINDING, &current_framebuffer);
5154   if (current_framebuffer != 0) {
5155     InsertError(GL_INVALID_OPERATION, "framebuffer must not be bound.");
5156     return error::kNoError;
5157   }
5158 
5159   if (!surface_->SupportsDCLayers()) {
5160     InsertError(GL_INVALID_OPERATION,
5161                 "surface doesn't support SetDrawRectangle.");
5162     return error::kNoError;
5163   }
5164 
5165   gfx::Rect rect(x, y, width, height);
5166   if (!surface_->SetDrawRectangle(rect)) {
5167     InsertError(GL_INVALID_OPERATION, "SetDrawRectangle failed on surface");
5168     // If SetDrawRectangle failed, we may not have a current context any
5169     // more, make sure to report lost context.
5170     MarkContextLost(error::kUnknown);
5171     group_->LoseContexts(error::kUnknown);
5172     return error::kLostContext;
5173   }
5174 
5175   ApplySurfaceDrawOffset();
5176 
5177   return error::kNoError;
5178 }
5179 
DoSetEnableDCLayersCHROMIUM(GLboolean enable)5180 error::Error GLES2DecoderPassthroughImpl::DoSetEnableDCLayersCHROMIUM(
5181     GLboolean enable) {
5182   GLint current_framebuffer = 0;
5183   api()->glGetIntegervFn(GL_FRAMEBUFFER_BINDING, &current_framebuffer);
5184   if (current_framebuffer != 0) {
5185     InsertError(GL_INVALID_OPERATION, "framebuffer must not be bound.");
5186     return error::kNoError;
5187   }
5188 
5189   if (!surface_->SupportsDCLayers()) {
5190     InsertError(GL_INVALID_OPERATION,
5191                 "surface doesn't support SetDrawRectangle.");
5192     return error::kNoError;
5193   }
5194 
5195   if (!surface_->SetEnableDCLayers(!!enable)) {
5196     InsertError(GL_INVALID_OPERATION, "SetEnableDCLayers failed on surface.");
5197     // If SetEnableDCLayers failed, we may not have a current context any
5198     // more, make sure to report lost context.
5199     MarkContextLost(error::kUnknown);
5200     group_->LoseContexts(error::kUnknown);
5201     return error::kLostContext;
5202   }
5203 
5204   return error::kNoError;
5205 }
5206 
DoBeginRasterCHROMIUM(GLuint texture_id,GLuint sk_color,GLuint msaa_sample_count,GLboolean can_use_lcd_text,GLint color_type)5207 error::Error GLES2DecoderPassthroughImpl::DoBeginRasterCHROMIUM(
5208     GLuint texture_id,
5209     GLuint sk_color,
5210     GLuint msaa_sample_count,
5211     GLboolean can_use_lcd_text,
5212     GLint color_type) {
5213   NOTIMPLEMENTED();
5214   return error::kNoError;
5215 }
5216 
DoRasterCHROMIUM(GLuint raster_shm_id,GLuint raster_shm_offset,GLsizeiptr raster_shm_size,GLuint font_shm_id,GLuint font_shm_offset,GLsizeiptr font_shm_size)5217 error::Error GLES2DecoderPassthroughImpl::DoRasterCHROMIUM(
5218     GLuint raster_shm_id,
5219     GLuint raster_shm_offset,
5220     GLsizeiptr raster_shm_size,
5221     GLuint font_shm_id,
5222     GLuint font_shm_offset,
5223     GLsizeiptr font_shm_size) {
5224   // TODO(enne): Add CHROMIUM_raster_transport extension support to the
5225   // passthrough command buffer.
5226   NOTIMPLEMENTED();
5227   return error::kNoError;
5228 }
5229 
DoEndRasterCHROMIUM()5230 error::Error GLES2DecoderPassthroughImpl::DoEndRasterCHROMIUM() {
5231   NOTIMPLEMENTED();
5232   return error::kNoError;
5233 }
5234 
DoCreateTransferCacheEntryINTERNAL(GLuint entry_type,GLuint entry_id,GLuint handle_shm_id,GLuint handle_shm_offset,GLuint data_shm_id,GLuint data_shm_offset,GLuint data_size)5235 error::Error GLES2DecoderPassthroughImpl::DoCreateTransferCacheEntryINTERNAL(
5236     GLuint entry_type,
5237     GLuint entry_id,
5238     GLuint handle_shm_id,
5239     GLuint handle_shm_offset,
5240     GLuint data_shm_id,
5241     GLuint data_shm_offset,
5242     GLuint data_size) {
5243   NOTIMPLEMENTED();
5244   return error::kNoError;
5245 }
5246 
DoUnlockTransferCacheEntryINTERNAL(GLuint entry_type,GLuint entry_id)5247 error::Error GLES2DecoderPassthroughImpl::DoUnlockTransferCacheEntryINTERNAL(
5248     GLuint entry_type,
5249     GLuint entry_id) {
5250   NOTIMPLEMENTED();
5251   return error::kNoError;
5252 }
5253 
DoDeleteTransferCacheEntryINTERNAL(GLuint entry_type,GLuint entry_id)5254 error::Error GLES2DecoderPassthroughImpl::DoDeleteTransferCacheEntryINTERNAL(
5255     GLuint entry_type,
5256     GLuint entry_id) {
5257   NOTIMPLEMENTED();
5258   return error::kNoError;
5259 }
5260 
DoWindowRectanglesEXT(GLenum mode,GLsizei n,const volatile GLint * box)5261 error::Error GLES2DecoderPassthroughImpl::DoWindowRectanglesEXT(
5262     GLenum mode,
5263     GLsizei n,
5264     const volatile GLint* box) {
5265   std::vector<GLint> box_copy(box, box + (n * 4));
5266   api()->glWindowRectanglesEXTFn(mode, n, box_copy.data());
5267   return error::kNoError;
5268 }
5269 
DoCreateGpuFenceINTERNAL(GLuint gpu_fence_id)5270 error::Error GLES2DecoderPassthroughImpl::DoCreateGpuFenceINTERNAL(
5271     GLuint gpu_fence_id) {
5272   if (!feature_info_->feature_flags().chromium_gpu_fence)
5273     return error::kUnknownCommand;
5274   if (!GetGpuFenceManager()->CreateGpuFence(gpu_fence_id))
5275     return error::kInvalidArguments;
5276   return error::kNoError;
5277 }
5278 
DoWaitGpuFenceCHROMIUM(GLuint gpu_fence_id)5279 error::Error GLES2DecoderPassthroughImpl::DoWaitGpuFenceCHROMIUM(
5280     GLuint gpu_fence_id) {
5281   if (!feature_info_->feature_flags().chromium_gpu_fence)
5282     return error::kUnknownCommand;
5283   if (!GetGpuFenceManager()->GpuFenceServerWait(gpu_fence_id))
5284     return error::kInvalidArguments;
5285   return error::kNoError;
5286 }
5287 
DoDestroyGpuFenceCHROMIUM(GLuint gpu_fence_id)5288 error::Error GLES2DecoderPassthroughImpl::DoDestroyGpuFenceCHROMIUM(
5289     GLuint gpu_fence_id) {
5290   if (!feature_info_->feature_flags().chromium_gpu_fence)
5291     return error::kUnknownCommand;
5292   if (!GetGpuFenceManager()->RemoveGpuFence(gpu_fence_id))
5293     return error::kInvalidArguments;
5294   return error::kNoError;
5295 }
5296 
DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint src_texture,GLuint dst_texture,GLint x,GLint y,GLsizei width,GLsizei height)5297 error::Error GLES2DecoderPassthroughImpl::DoUnpremultiplyAndDitherCopyCHROMIUM(
5298     GLuint src_texture,
5299     GLuint dst_texture,
5300     GLint x,
5301     GLint y,
5302     GLsizei width,
5303     GLsizei height) {
5304   NOTIMPLEMENTED();
5305   return error::kNoError;
5306 }
5307 
5308 error::Error
DoSetReadbackBufferShadowAllocationINTERNAL(GLuint buffer_id,GLuint shm_id,GLuint shm_offset,GLuint size)5309 GLES2DecoderPassthroughImpl::DoSetReadbackBufferShadowAllocationINTERNAL(
5310     GLuint buffer_id,
5311     GLuint shm_id,
5312     GLuint shm_offset,
5313     GLuint size) {
5314   BufferShadowUpdate update;
5315   update.shm = GetSharedMemoryBuffer(shm_id);
5316   update.shm_offset = shm_offset;
5317   update.size = size;
5318 
5319   GLuint buffer_service_id = 0;
5320   if (!resources_->buffer_id_map.GetServiceID(buffer_id, &buffer_service_id)) {
5321     InsertError(GL_INVALID_OPERATION, "Invalid buffer ID");
5322     return error::kNoError;
5323   }
5324 
5325   if (!update.shm) {
5326     return error::kInvalidArguments;
5327   }
5328   if (update.shm->GetRemainingSize(shm_offset) < size) {
5329     return error::kOutOfBounds;
5330   }
5331 
5332   buffer_shadow_updates_.emplace(buffer_id, std::move(update));
5333 
5334   return error::kNoError;
5335 }
5336 
DoMaxShaderCompilerThreadsKHR(GLuint count)5337 error::Error GLES2DecoderPassthroughImpl::DoMaxShaderCompilerThreadsKHR(
5338     GLuint count) {
5339   api()->glMaxShaderCompilerThreadsKHRFn(count);
5340   return error::kNoError;
5341 }
5342 
5343 error::Error
DoInitializeDiscardableTextureCHROMIUM(GLuint texture_id,ServiceDiscardableHandle && discardable_handle)5344 GLES2DecoderPassthroughImpl::DoInitializeDiscardableTextureCHROMIUM(
5345     GLuint texture_id,
5346     ServiceDiscardableHandle&& discardable_handle) {
5347   scoped_refptr<TexturePassthrough> texture_passthrough = nullptr;
5348   if (!resources_->texture_object_map.GetServiceID(texture_id,
5349                                                    &texture_passthrough) ||
5350       texture_passthrough == nullptr) {
5351     InsertError(GL_INVALID_VALUE, "Invalid texture ID");
5352     return error::kNoError;
5353   }
5354 
5355   group_->passthrough_discardable_manager()->InitializeTexture(
5356       texture_id, group_.get(), texture_passthrough->estimated_size(),
5357       std::move(discardable_handle));
5358 
5359   return error::kNoError;
5360 }
5361 
DoLockDiscardableTextureCHROMIUM(GLuint texture_id)5362 error::Error GLES2DecoderPassthroughImpl::DoLockDiscardableTextureCHROMIUM(
5363     GLuint texture_id) {
5364   if (!group_->passthrough_discardable_manager()->LockTexture(texture_id,
5365                                                               group_.get())) {
5366     InsertError(GL_INVALID_VALUE, "Texture ID not initialized");
5367     return error::kNoError;
5368   }
5369 
5370   return error::kNoError;
5371 }
5372 
DoUnlockDiscardableTextureCHROMIUM(GLuint texture_id)5373 error::Error GLES2DecoderPassthroughImpl::DoUnlockDiscardableTextureCHROMIUM(
5374     GLuint texture_id) {
5375   TexturePassthrough* texture_to_unbind = nullptr;
5376   if (!group_->passthrough_discardable_manager()->UnlockTexture(
5377           texture_id, group_.get(), &texture_to_unbind)) {
5378     InsertError(GL_INVALID_VALUE, "Texture ID not initialized");
5379     return error::kNoError;
5380   }
5381 
5382   if (texture_to_unbind != nullptr) {
5383     UpdateTextureBinding(texture_to_unbind->target(), texture_id, nullptr);
5384   }
5385   return error::kNoError;
5386 }
5387 
5388 error::Error
DoCreateAndTexStorage2DSharedImageINTERNAL(GLuint texture_client_id,GLenum internalformat,const volatile GLbyte * mailbox)5389 GLES2DecoderPassthroughImpl::DoCreateAndTexStorage2DSharedImageINTERNAL(
5390     GLuint texture_client_id,
5391     GLenum internalformat,
5392     const volatile GLbyte* mailbox) {
5393   // RGB emulation is not needed here.
5394   if (internalformat != GL_NONE) {
5395     InsertError(GL_INVALID_ENUM, "internal format not supported.");
5396     return error::kNoError;
5397   }
5398 
5399   if (!texture_client_id ||
5400       resources_->texture_id_map.HasClientID(texture_client_id)) {
5401     InsertError(GL_INVALID_OPERATION, "invalid client ID");
5402     return error::kNoError;
5403   }
5404 
5405   const Mailbox& mb = Mailbox::FromVolatile(
5406       *reinterpret_cast<const volatile Mailbox*>(mailbox));
5407   auto shared_image = group_->shared_image_representation_factory()
5408                           ->ProduceGLTexturePassthrough(mb);
5409   if (shared_image == nullptr) {
5410     // Create texture to handle invalid mailbox (see http://crbug.com/472465 and
5411     // http://crbug.com/851878).
5412     DoGenTextures(1, &texture_client_id);
5413     InsertError(GL_INVALID_OPERATION, "invalid mailbox name.");
5414     return error::kNoError;
5415   }
5416 
5417   auto texture = shared_image->GetTexturePassthrough();
5418 
5419   // Update id mappings
5420   resources_->texture_id_map.RemoveClientID(texture_client_id);
5421   resources_->texture_id_map.SetIDMapping(texture_client_id,
5422                                           texture->service_id());
5423   resources_->texture_object_map.RemoveClientID(texture_client_id);
5424   resources_->texture_object_map.SetIDMapping(texture_client_id, texture);
5425   resources_->texture_shared_image_map[texture_client_id] =
5426       PassthroughResources::SharedImageData(std::move(shared_image));
5427 
5428   return error::kNoError;
5429 }
5430 
5431 error::Error
DoBeginSharedImageAccessDirectCHROMIUM(GLuint client_id,GLenum mode)5432 GLES2DecoderPassthroughImpl::DoBeginSharedImageAccessDirectCHROMIUM(
5433     GLuint client_id,
5434     GLenum mode) {
5435   if (mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM &&
5436       mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM &&
5437       mode != GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM) {
5438     InsertError(GL_INVALID_ENUM, "unrecognized access mode");
5439     return error::kNoError;
5440   }
5441 
5442   auto found = resources_->texture_shared_image_map.find(client_id);
5443   if (found == resources_->texture_shared_image_map.end()) {
5444     InsertError(GL_INVALID_OPERATION, "texture is not a shared image");
5445     return error::kNoError;
5446   }
5447 
5448   if (found->second.is_being_accessed()) {
5449     InsertError(GL_INVALID_OPERATION, "shared image is being accessed.");
5450     return error::kNoError;
5451   }
5452 
5453   if (!found->second.BeginAccess(mode, api())) {
5454     InsertError(GL_INVALID_OPERATION, "unable to begin access");
5455     return error::kNoError;
5456   }
5457 
5458   return error::kNoError;
5459 }
5460 
DoEndSharedImageAccessDirectCHROMIUM(GLuint client_id)5461 error::Error GLES2DecoderPassthroughImpl::DoEndSharedImageAccessDirectCHROMIUM(
5462     GLuint client_id) {
5463   auto found = resources_->texture_shared_image_map.find(client_id);
5464   if (found == resources_->texture_shared_image_map.end()) {
5465     InsertError(GL_INVALID_OPERATION, "texture is not a shared image");
5466     return error::kNoError;
5467   }
5468   if (!found->second.is_being_accessed()) {
5469     InsertError(GL_INVALID_OPERATION, "shared image is not being accessed.");
5470     return error::kNoError;
5471   }
5472   found->second.EndAccess();
5473   return error::kNoError;
5474 }
5475 
5476 error::Error
DoBeginBatchReadAccessSharedImageCHROMIUM()5477 GLES2DecoderPassthroughImpl::DoBeginBatchReadAccessSharedImageCHROMIUM() {
5478   DCHECK(group_->shared_image_manager());
5479   group_->shared_image_manager()->BeginBatchReadAccess();
5480   return error::kNoError;
5481 }
5482 
5483 error::Error
DoEndBatchReadAccessSharedImageCHROMIUM()5484 GLES2DecoderPassthroughImpl::DoEndBatchReadAccessSharedImageCHROMIUM() {
5485   DCHECK(group_->shared_image_manager());
5486   group_->shared_image_manager()->EndBatchReadAccess();
5487   return error::kNoError;
5488 }
5489 
DoEnableiOES(GLenum target,GLuint index)5490 error::Error GLES2DecoderPassthroughImpl::DoEnableiOES(GLenum target,
5491                                                        GLuint index) {
5492   api()->glEnableiOESFn(target, index);
5493   return error::kNoError;
5494 }
5495 
DoDisableiOES(GLenum target,GLuint index)5496 error::Error GLES2DecoderPassthroughImpl::DoDisableiOES(GLenum target,
5497                                                         GLuint index) {
5498   api()->glDisableiOESFn(target, index);
5499   return error::kNoError;
5500 }
5501 
5502 }  // namespace gles2
5503 }  // namespace gpu
5504