1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_
27 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_
28 
29 #include <memory>
30 
31 #include "base/containers/mru_cache.h"
32 #include "base/macros.h"
33 #include "base/numerics/checked_math.h"
34 #include "base/optional.h"
35 #include "base/single_thread_task_runner.h"
36 #include "device/vr/public/mojom/vr_service.mojom-blink.h"
37 #include "third_party/blink/public/platform/platform.h"
38 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
39 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
40 #include "third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.h"
41 #include "third_party/blink/renderer/core/core_export.h"
42 #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
43 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
44 #include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h"
45 #include "third_party/blink/renderer/core/layout/content_change_type.h"
46 #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
47 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
48 #include "third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h"
49 #include "third_party/blink/renderer/modules/webgl/webgl_extension_name.h"
50 #include "third_party/blink/renderer/modules/webgl/webgl_fast_call.h"
51 #include "third_party/blink/renderer/modules/webgl/webgl_texture.h"
52 #include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h"
53 #include "third_party/blink/renderer/platform/bindings/name_client.h"
54 #include "third_party/blink/renderer/platform/bindings/script_state.h"
55 #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
56 #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
57 #include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
58 #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
59 #include "third_party/blink/renderer/platform/timer.h"
60 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
61 #include "third_party/khronos/GLES2/gl2.h"
62 #include "third_party/khronos/GLES3/gl31.h"
63 #include "third_party/skia/include/core/SkData.h"
64 #include "v8/include/v8-fast-api-calls.h"
65 
66 namespace cc {
67 class Layer;
68 }
69 
70 namespace gpu {
71 namespace gles2 {
72 class GLES2Interface;
73 }
74 }  // namespace gpu
75 
76 namespace blink {
77 
78 class AcceleratedStaticBitmapImage;
79 class CanvasResourceProvider;
80 class EXTDisjointTimerQuery;
81 class EXTDisjointTimerQueryWebGL2;
82 class ExceptionState;
83 class HTMLCanvasElementOrOffscreenCanvas;
84 class HTMLImageElement;
85 class HTMLVideoElement;
86 class ImageBitmap;
87 class ImageData;
88 class IntSize;
89 class OESVertexArrayObject;
90 class WebGLActiveInfo;
91 class WebGLBuffer;
92 class WebGLCompressedTextureASTC;
93 class WebGLCompressedTextureETC;
94 class WebGLCompressedTextureETC1;
95 class WebGLCompressedTexturePVRTC;
96 class WebGLCompressedTextureS3TC;
97 class WebGLCompressedTextureS3TCsRGB;
98 class WebGLContextGroup;
99 class WebGLContextObject;
100 class WebGLDebugShaders;
101 class WebGLDrawBuffers;
102 class WebGLExtension;
103 class WebGLFramebuffer;
104 class WebGLObject;
105 class WebGLProgram;
106 class WebGLRenderbuffer;
107 class WebGLShader;
108 class WebGLShaderPrecisionFormat;
109 class WebGLUniformLocation;
110 class WebGLVertexArrayObjectBase;
111 
112 using GLenumHashSet = HashSet<GLenum,
113                               WTF::AlreadyHashed,
114                               WTF::UnsignedWithZeroKeyHashTraits<GLenum>>;
115 
116 // This class uses the color mask to prevent drawing to the alpha channel, if
117 // the DrawingBuffer requires RGB emulation.
118 class ScopedRGBEmulationColorMask {
119   STACK_ALLOCATED();
120 
121  public:
122   ScopedRGBEmulationColorMask(WebGLRenderingContextBase*,
123                               GLboolean* color_mask,
124                               DrawingBuffer*);
125   ~ScopedRGBEmulationColorMask();
126 
127  private:
128   WebGLRenderingContextBase* context_;
129   GLboolean color_mask_[4];
130   const bool requires_emulation_;
131 };
132 
133 class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
134                                                  public DrawingBuffer::Client {
135  public:
136   ~WebGLRenderingContextBase() override;
137 
canvas()138   HTMLCanvasElement* canvas() const {
139     if (Host()->IsOffscreenCanvas())
140       return nullptr;
141     return static_cast<HTMLCanvasElement*>(Host());
142   }
143 
GetUkmParameters()144   const UkmParameters GetUkmParameters() const {
145     return Host()->GetUkmParameters();
146   }
147 
148   virtual String ContextName() const = 0;
149   virtual void RegisterContextExtensions() = 0;
150 
151   virtual void InitializeNewContext();
152 
153   static unsigned GetWebGLVersion(const CanvasRenderingContext*);
154 
155   static std::unique_ptr<WebGraphicsContext3DProvider>
156   CreateWebGraphicsContext3DProvider(CanvasRenderingContextHost*,
157                                      const CanvasContextCreationAttributesCore&,
158                                      Platform::ContextType context_type,
159                                      bool* using_gpu_compositing);
160   static void ForceNextWebGLContextCreationToFail();
161 
ContextType()162   Platform::ContextType ContextType() const { return context_type_; }
163 
164   int drawingBufferWidth() const;
165   int drawingBufferHeight() const;
166 
167   void activeTexture(GLenum texture);
168   void attachShader(WebGLProgram*, WebGLShader*);
169   void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
170   void bindBuffer(GLenum target, WebGLBuffer* buffer);
171   virtual void bindFramebuffer(GLenum target, WebGLFramebuffer*);
172   void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
173   void bindTexture(GLenum target, WebGLTexture*);
174   void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
175   void blendEquation(GLenum mode);
176   void blendEquationSeparate(GLenum mode_rgb, GLenum mode_alpha);
177   void blendFunc(GLenum sfactor, GLenum dfactor);
178   void blendFuncSeparate(GLenum src_rgb,
179                          GLenum dst_rgb,
180                          GLenum src_alpha,
181                          GLenum dst_alpha);
182 
183   void bufferData(GLenum target, int64_t size, GLenum usage);
184   void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
185   void bufferData(GLenum target,
186                   MaybeShared<DOMArrayBufferView> data,
187                   GLenum usage);
188   void bufferSubData(GLenum target, int64_t offset, DOMArrayBuffer* data);
189   void bufferSubData(GLenum target,
190                      int64_t offset,
191                      const FlexibleArrayBufferView& data);
192 
193   GLenum checkFramebufferStatus(GLenum target);
194   void clear(GLbitfield mask);
195   void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
196   void clearDepth(GLfloat);
197   void clearStencil(GLint);
198   void colorMask(GLboolean red,
199                  GLboolean green,
200                  GLboolean blue,
201                  GLboolean alpha);
202   void compileShader(WebGLShader*);
203 
204   void compressedTexImage2D(GLenum target,
205                             GLint level,
206                             GLenum internalformat,
207                             GLsizei width,
208                             GLsizei height,
209                             GLint border,
210                             MaybeShared<DOMArrayBufferView> data);
211   void compressedTexSubImage2D(GLenum target,
212                                GLint level,
213                                GLint xoffset,
214                                GLint yoffset,
215                                GLsizei width,
216                                GLsizei height,
217                                GLenum format,
218                                MaybeShared<DOMArrayBufferView> data);
219 
220   void copyTexImage2D(GLenum target,
221                       GLint level,
222                       GLenum internalformat,
223                       GLint x,
224                       GLint y,
225                       GLsizei width,
226                       GLsizei height,
227                       GLint border);
228   void copyTexSubImage2D(GLenum target,
229                          GLint level,
230                          GLint xoffset,
231                          GLint yoffset,
232                          GLint x,
233                          GLint y,
234                          GLsizei width,
235                          GLsizei height);
236 
237   WebGLBuffer* createBuffer();
238   WebGLFramebuffer* createFramebuffer();
239   WebGLProgram* createProgram();
240   WebGLRenderbuffer* createRenderbuffer();
241   WebGLShader* createShader(GLenum type);
242   WebGLTexture* createTexture();
243 
244   void cullFace(GLenum mode);
245 
246   void deleteBuffer(WebGLBuffer*);
247   virtual void deleteFramebuffer(WebGLFramebuffer*);
248   void deleteProgram(WebGLProgram*);
249   void deleteRenderbuffer(WebGLRenderbuffer*);
250   void deleteShader(WebGLShader*);
251   void deleteTexture(WebGLTexture*);
252 
253   void depthFunc(GLenum);
254   void depthMask(GLboolean);
255   void depthRange(GLfloat z_near, GLfloat z_far);
256   void detachShader(WebGLProgram*, WebGLShader*);
257   void disable(GLenum cap);
258   void disableVertexAttribArray(GLuint index);
259 
260   void drawArraysImpl(GLenum mode, GLint first, GLsizei count);
drawArrays(GLenum mode,GLint first,GLsizei count)261   void drawArrays(GLenum mode, GLint first, GLsizei count) {
262     if (fast_call_.FlushDeferredEvents(this)) {
263       return;
264     }
265     drawArraysImpl(mode, first, count);
266   }
drawArrays(GLenum mode,GLint first,GLsizei count,v8::FastApiCallbackOptions & options)267   void drawArrays(GLenum mode,
268                   GLint first,
269                   GLsizei count,
270                   v8::FastApiCallbackOptions& options) {
271     auto scoped_call = fast_call_.EnterScoped(&options.fallback);
272     drawArraysImpl(mode, first, count);
273   }
274 
275   void drawElementsImpl(GLenum mode,
276                         GLsizei count,
277                         GLenum type,
278                         int64_t offset);
drawElements(GLenum mode,GLsizei count,GLenum type,int64_t offset)279   void drawElements(GLenum mode, GLsizei count, GLenum type, int64_t offset) {
280     if (fast_call_.FlushDeferredEvents(this)) {
281       return;
282     }
283     drawElementsImpl(mode, count, type, offset);
284   }
drawElements(GLenum mode,GLsizei count,GLenum type,int64_t offset,v8::FastApiCallbackOptions & options)285   void drawElements(GLenum mode,
286                     GLsizei count,
287                     GLenum type,
288                     int64_t offset,
289                     v8::FastApiCallbackOptions& options) {
290     auto scoped_call = fast_call_.EnterScoped(&options.fallback);
291     drawElementsImpl(mode, count, type, offset);
292   }
293 
294   void DrawArraysInstancedANGLE(GLenum mode,
295                                 GLint first,
296                                 GLsizei count,
297                                 GLsizei primcount);
298   void DrawElementsInstancedANGLE(GLenum mode,
299                                   GLsizei count,
300                                   GLenum type,
301                                   int64_t offset,
302                                   GLsizei primcount);
303 
304   void enable(GLenum cap);
305   void enableVertexAttribArray(GLuint index);
306   void finish();
307   void flush();
308   void framebufferRenderbuffer(GLenum target,
309                                GLenum attachment,
310                                GLenum renderbuffertarget,
311                                WebGLRenderbuffer*);
312   void framebufferTexture2D(GLenum target,
313                             GLenum attachment,
314                             GLenum textarget,
315                             WebGLTexture*,
316                             GLint level);
317   void frontFace(GLenum mode);
318   void generateMipmap(GLenum target);
319 
320   WebGLActiveInfo* getActiveAttrib(WebGLProgram*, GLuint index);
321   WebGLActiveInfo* getActiveUniform(WebGLProgram*, GLuint index);
322   bool getAttachedShaders(WebGLProgram*, HeapVector<Member<WebGLShader>>&);
323   base::Optional<HeapVector<Member<WebGLShader>>> getAttachedShaders(
324       WebGLProgram*);
325   GLint getAttribLocation(WebGLProgram*, const String& name);
326   ScriptValue getBufferParameter(ScriptState*, GLenum target, GLenum pname);
327   WebGLContextAttributes* getContextAttributes() const;
328   GLenum getError();
329   ScriptValue getExtension(ScriptState*, const String& name);
330   virtual ScriptValue getFramebufferAttachmentParameter(ScriptState*,
331                                                         GLenum target,
332                                                         GLenum attachment,
333                                                         GLenum pname);
334   virtual ScriptValue getParameter(ScriptState*, GLenum pname);
335   ScriptValue getProgramParameter(ScriptState*, WebGLProgram*, GLenum pname);
336   String getProgramInfoLog(WebGLProgram*);
337   ScriptValue getRenderbufferParameter(ScriptState*,
338                                        GLenum target,
339                                        GLenum pname);
340   ScriptValue getShaderParameter(ScriptState*, WebGLShader*, GLenum pname);
341   String getShaderInfoLog(WebGLShader*);
342   WebGLShaderPrecisionFormat* getShaderPrecisionFormat(GLenum shader_type,
343                                                        GLenum precision_type);
344   String getShaderSource(WebGLShader*);
345   base::Optional<Vector<String>> getSupportedExtensions();
346   virtual ScriptValue getTexParameter(ScriptState*,
347                                       GLenum target,
348                                       GLenum pname);
349   ScriptValue getUniform(ScriptState*,
350                          WebGLProgram*,
351                          const WebGLUniformLocation*);
352   WebGLUniformLocation* getUniformLocation(WebGLProgram*, const String&);
353   ScriptValue getVertexAttrib(ScriptState*, GLuint index, GLenum pname);
354   int64_t getVertexAttribOffset(GLuint index, GLenum pname);
355 
356   void hint(GLenum target, GLenum mode);
357   GLboolean isBuffer(WebGLBuffer*);
358   bool isContextLost() const override;
359   GLboolean isEnabled(GLenum cap);
360   GLboolean isFramebuffer(WebGLFramebuffer*);
361   GLboolean isProgram(WebGLProgram*);
362   GLboolean isRenderbuffer(WebGLRenderbuffer*);
363   GLboolean isShader(WebGLShader*);
364   GLboolean isTexture(WebGLTexture*);
365 
366   void lineWidth(GLfloat);
367   void linkProgram(WebGLProgram*);
368   virtual void pixelStorei(GLenum pname, GLint param);
369   void polygonOffset(GLfloat factor, GLfloat units);
370   virtual void readPixels(GLint x,
371                           GLint y,
372                           GLsizei width,
373                           GLsizei height,
374                           GLenum format,
375                           GLenum type,
376                           MaybeShared<DOMArrayBufferView> pixels);
377   void renderbufferStorage(GLenum target,
378                            GLenum internalformat,
379                            GLsizei width,
380                            GLsizei height);
381   void sampleCoverage(GLfloat value, GLboolean invert);
382   void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
383   void shaderSource(WebGLShader*, const String&);
384   void stencilFunc(GLenum func, GLint ref, GLuint mask);
385   void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
386   void stencilMask(GLuint);
387   void stencilMaskSeparate(GLenum face, GLuint mask);
388   void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
389   void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
390 
391   void texImage2D(GLenum target,
392                   GLint level,
393                   GLint internalformat,
394                   GLsizei width,
395                   GLsizei height,
396                   GLint border,
397                   GLenum format,
398                   GLenum type,
399                   MaybeShared<DOMArrayBufferView>);
400   void texImage2D(GLenum target,
401                   GLint level,
402                   GLint internalformat,
403                   GLenum format,
404                   GLenum type,
405                   ImageData*);
406   void texImage2D(ExecutionContext*,
407                   GLenum target,
408                   GLint level,
409                   GLint internalformat,
410                   GLenum format,
411                   GLenum type,
412                   HTMLImageElement*,
413                   ExceptionState&);
414   void texImage2D(ExecutionContext*,
415                   GLenum target,
416                   GLint level,
417                   GLint internalformat,
418                   GLenum format,
419                   GLenum type,
420                   CanvasRenderingContextHost*,
421                   ExceptionState&);
422   void texImage2D(ExecutionContext*,
423                   GLenum target,
424                   GLint level,
425                   GLint internalformat,
426                   GLenum format,
427                   GLenum type,
428                   HTMLVideoElement*,
429                   ExceptionState&);
430   void texImage2D(GLenum target,
431                   GLint level,
432                   GLint internalformat,
433                   GLenum format,
434                   GLenum type,
435                   ImageBitmap*,
436                   ExceptionState&);
437 
438   void texParameterf(GLenum target, GLenum pname, GLfloat param);
439   void texParameteri(GLenum target, GLenum pname, GLint param);
440 
441   void texSubImage2D(GLenum target,
442                      GLint level,
443                      GLint xoffset,
444                      GLint yoffset,
445                      GLsizei width,
446                      GLsizei height,
447                      GLenum format,
448                      GLenum type,
449                      MaybeShared<DOMArrayBufferView>);
450   void texSubImage2D(GLenum target,
451                      GLint level,
452                      GLint xoffset,
453                      GLint yoffset,
454                      GLenum format,
455                      GLenum type,
456                      ImageData*);
457   void texSubImage2D(ExecutionContext*,
458                      GLenum target,
459                      GLint level,
460                      GLint xoffset,
461                      GLint yoffset,
462                      GLenum format,
463                      GLenum type,
464                      HTMLImageElement*,
465                      ExceptionState&);
466   void texSubImage2D(ExecutionContext*,
467                      GLenum target,
468                      GLint level,
469                      GLint xoffset,
470                      GLint yoffset,
471                      GLenum format,
472                      GLenum type,
473                      CanvasRenderingContextHost*,
474                      ExceptionState&);
475   void texSubImage2D(ExecutionContext*,
476                      GLenum target,
477                      GLint level,
478                      GLint xoffset,
479                      GLint yoffset,
480                      GLenum format,
481                      GLenum type,
482                      HTMLVideoElement*,
483                      ExceptionState&);
484   void texSubImage2D(GLenum target,
485                      GLint level,
486                      GLint xoffset,
487                      GLint yoffset,
488                      GLenum format,
489                      GLenum type,
490                      ImageBitmap*,
491                      ExceptionState&);
492 
493   void uniform1f(const WebGLUniformLocation*, GLfloat x);
494   void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
495   void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&);
496   void uniform1i(const WebGLUniformLocation*, GLint x);
497   void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
498   void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&);
499   void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
500   void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
501   void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&);
502   void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
503   void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
504   void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&);
505   void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
506   void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
507   void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&);
508   void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
509   void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
510   void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&);
511   void uniform4f(const WebGLUniformLocation*,
512                  GLfloat x,
513                  GLfloat y,
514                  GLfloat z,
515                  GLfloat w);
516   void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
517   void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&);
518   void uniform4i(const WebGLUniformLocation*,
519                  GLint x,
520                  GLint y,
521                  GLint z,
522                  GLint w);
523   void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
524   void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
525   void uniformMatrix2fv(const WebGLUniformLocation*,
526                         GLboolean transpose,
527                         MaybeShared<DOMFloat32Array> value);
528   void uniformMatrix2fv(const WebGLUniformLocation*,
529                         GLboolean transpose,
530                         Vector<GLfloat>& value);
531   void uniformMatrix3fv(const WebGLUniformLocation*,
532                         GLboolean transpose,
533                         MaybeShared<DOMFloat32Array> value);
534   void uniformMatrix3fv(const WebGLUniformLocation*,
535                         GLboolean transpose,
536                         Vector<GLfloat>& value);
537   void uniformMatrix4fv(const WebGLUniformLocation*,
538                         GLboolean transpose,
539                         MaybeShared<DOMFloat32Array> value);
540   void uniformMatrix4fv(const WebGLUniformLocation*,
541                         GLboolean transpose,
542                         Vector<GLfloat>& value);
543 
544   virtual void useProgram(WebGLProgram*);
545   void validateProgram(WebGLProgram*);
546 
547   void vertexAttrib1f(GLuint index, GLfloat x);
548   void vertexAttrib1fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
549   void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values);
550   void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
551   void vertexAttrib2fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
552   void vertexAttrib2fv(GLuint index, const Vector<GLfloat>& values);
553   void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
554   void vertexAttrib3fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
555   void vertexAttrib3fv(GLuint index, const Vector<GLfloat>& values);
556   void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
557   void vertexAttrib4fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
558   void vertexAttrib4fv(GLuint index, const Vector<GLfloat>& values);
559   void vertexAttribPointer(GLuint index,
560                            GLint size,
561                            GLenum type,
562                            GLboolean normalized,
563                            GLsizei stride,
564                            int64_t offset);
565 
566   void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
567 
568   void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
569 
570   // WEBGL_lose_context support
571   enum AutoRecoveryMethod {
572     // Don't restore automatically.
573     kManual,
574 
575     // Restore when resources are available.
576     kWhenAvailable,
577 
578     // Restore as soon as possible, but only when
579     // the canvas is visible.
580     kAuto
581   };
582   void LoseContext(LostContextMode) override;
583   void ForceLostContext(LostContextMode, AutoRecoveryMethod);
584   void ForceRestoreContext();
585   void LoseContextImpl(LostContextMode, AutoRecoveryMethod);
586   uint32_t NumberOfContextLosses() const;
587 
588   // Utilities to restore GL state to match the rendering context's
589   // saved state. Use these after contextGL()-based state changes that
590   // bypass the rendering context.
591   void RestoreScissorEnabled();
592   void RestoreScissorBox();
593   void RestoreClearColor();
594   void RestoreColorMask();
595 
ContextGL()596   gpu::gles2::GLES2Interface* ContextGL() const {
597     DrawingBuffer* d = GetDrawingBuffer();
598     if (!d)
599       return nullptr;
600     return d->ContextGL();
601   }
ContextGroup()602   WebGLContextGroup* ContextGroup() const { return context_group_.Get(); }
603   Extensions3DUtil* ExtensionsUtil();
604 
605   void Reshape(int width, int height) override;
606 
607   void MarkLayerComposited() override;
608 
609   sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer) override;
610 
MaxVertexAttribs()611   unsigned MaxVertexAttribs() const { return max_vertex_attribs_; }
612 
613   void Trace(Visitor*) const override;
614 
615   // Returns approximate gpu memory allocated per pixel.
616   int ExternallyAllocatedBufferCountPerPixel() override;
617 
618   // Returns the drawing buffer size after it is, probably, has scaled down
619   // to the maximum supported canvas size.
620   IntSize DrawingBufferSize() const override;
621   DrawingBuffer* GetDrawingBuffer() const;
622 
623   class TextureUnitState {
624     DISALLOW_NEW();
625 
626    public:
627     Member<WebGLTexture> texture2d_binding_;
628     Member<WebGLTexture> texture_cube_map_binding_;
629     Member<WebGLTexture> texture3d_binding_;
630     Member<WebGLTexture> texture2d_array_binding_;
631     Member<WebGLTexture> texture_video_image_binding_;
632 
633     void Trace(Visitor*) const;
634   };
635 
636   scoped_refptr<StaticBitmapImage> GetImage() override;
637   void SetFilterQuality(SkFilterQuality) override;
IsWebGL2()638   bool IsWebGL2() { return context_type_ == Platform::kWebGL2ContextType; }
639 
640   void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const;
641 
642   void commit();
643 
644   ScriptPromise makeXRCompatible(ScriptState*, ExceptionState&);
645   bool IsXRCompatible() const;
646 
647   void UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta);
648 
649  protected:
650   // WebGL object types.
651   friend class WebGLContextObject;
652   friend class WebGLObject;
653   friend class WebGLQuery;
654   friend class WebGLTimerQueryEXT;
655   friend class WebGLVertexArrayObjectBase;
656 
657   // Implementation helpers.
658   friend class ScopedDrawingBufferBinder;
659   friend class ScopedFramebufferRestorer;
660   friend class ScopedTexture2DRestorer;
661   friend class ScopedUnpackParametersResetRestore;
662 
663   // WebGL extensions.
664   friend class EXTDisjointTimerQuery;
665   friend class EXTDisjointTimerQueryWebGL2;
666   friend class EXTTextureCompressionBPTC;
667   friend class EXTTextureCompressionRGTC;
668   friend class OESVertexArrayObject;
669   friend class OVRMultiview2;
670   friend class WebGLCompressedTextureASTC;
671   friend class WebGLCompressedTextureETC;
672   friend class WebGLCompressedTextureETC1;
673   friend class WebGLCompressedTexturePVRTC;
674   friend class WebGLCompressedTextureS3TC;
675   friend class WebGLCompressedTextureS3TCsRGB;
676   friend class WebGLDebugShaders;
677   friend class WebGLDrawBuffers;
678   friend class WebGLDrawInstancedBaseVertexBaseInstance;
679   friend class WebGLFramebuffer;
680   friend class WebGLMultiDraw;
681   friend class WebGLMultiDrawCommon;
682   friend class WebGLMultiDrawInstancedBaseVertexBaseInstance;
683   friend class WebGLVideoTexture;
684 
685   WebGLRenderingContextBase(CanvasRenderingContextHost*,
686                             std::unique_ptr<WebGraphicsContext3DProvider>,
687                             bool using_gpu_compositing,
688                             const CanvasContextCreationAttributesCore&,
689                             Platform::ContextType);
690   scoped_refptr<DrawingBuffer> CreateDrawingBuffer(
691       std::unique_ptr<WebGraphicsContext3DProvider>,
692       bool using_gpu_compositing);
693   void SetupFlags();
694 
695   // CanvasRenderingContext implementation.
Is3d()696   bool Is3d() const override { return true; }
IsComposited()697   bool IsComposited() const override { return true; }
IsAccelerated()698   bool IsAccelerated() const override { return true; }
699   bool UsingSwapChain() const override;
700   bool IsOriginTopLeft() const override;
701   void SetIsInHiddenPage(bool) override;
SetIsBeingDisplayed(bool)702   void SetIsBeingDisplayed(bool) override {}
703   bool PaintRenderingResultsToCanvas(SourceDrawingBuffer) override;
704   cc::Layer* CcLayer() const override;
705   void Stop() override;
706   void DidDraw(const SkIRect&) override;
707   void DidDraw() override;
708   void FinalizeFrame() override;
709   bool PushFrame() override;
710 
711   // DrawingBuffer::Client implementation.
712   bool DrawingBufferClientIsBoundForDraw() override;
713   void DrawingBufferClientRestoreScissorTest() override;
714   void DrawingBufferClientRestoreMaskAndClearValues() override;
715   void DrawingBufferClientRestorePixelPackParameters() override;
716   void DrawingBufferClientRestoreTexture2DBinding() override;
717   void DrawingBufferClientRestoreTextureCubeMapBinding() override;
718   void DrawingBufferClientRestoreRenderbufferBinding() override;
719   void DrawingBufferClientRestoreFramebufferBinding() override;
720   void DrawingBufferClientRestorePixelUnpackBufferBinding() override;
721   void DrawingBufferClientRestorePixelPackBufferBinding() override;
722   bool DrawingBufferClientUserAllocatedMultisampledRenderbuffers() override;
723   void DrawingBufferClientForceLostContextWithAutoRecovery() override;
724 
725   virtual void DestroyContext();
726   void MarkContextChanged(ContentChangeType);
727 
728   void OnErrorMessage(const char*, int32_t id);
729 
730   scoped_refptr<base::SingleThreadTaskRunner> GetContextTaskRunner();
731 
732   // Query if depth_stencil buffer is supported.
IsDepthStencilSupported()733   bool IsDepthStencilSupported() { return is_depth_stencil_supported_; }
734 
735   // Check if each enabled vertex attribute is bound to a buffer.
736   bool ValidateRenderingState(const char*);
737 
738   // Helper function for APIs which can legally receive null objects, including
739   // the bind* calls (bindBuffer, bindTexture, etc.) and useProgram. Checks that
740   // the object belongs to this context and that it's not marked for deletion.
741   // Returns false if the caller should return without further processing.
742   // Performs a context loss check internally.
743   // This returns true for null WebGLObject arguments!
744   bool ValidateNullableWebGLObject(const char* function_name, WebGLObject*);
745 
746   // Validates the incoming WebGL object, which is assumed to be non-null.
747   // Checks that the object belongs to this context and that it's not marked for
748   // deletion. Performs a context loss check internally.
749   bool ValidateWebGLObject(const char* function_name, WebGLObject*);
750 
751   // Validates the incoming WebGL program or shader, which is assumed to be
752   // non-null. OpenGL ES's validation rules differ for these types of objetcts
753   // compared to others. Performs a context loss check internally.
754   bool ValidateWebGLProgramOrShader(const char* function_name, WebGLObject*);
755 
756   // Adds a compressed texture format.
757   void AddCompressedTextureFormat(GLenum);
758   void RemoveAllCompressedTextureFormats();
759 
760   // Set UNPACK_ALIGNMENT to 1, all other parameters to 0.
761   virtual void ResetUnpackParameters();
762   // Restore the client unpack parameters.
763   virtual void RestoreUnpackParameters();
764 
765   scoped_refptr<Image> DrawImageIntoBuffer(scoped_refptr<Image>,
766                                            int width,
767                                            int height,
768                                            const char* function_name);
769 
770   scoped_refptr<Image> VideoFrameToImage(
771       HTMLVideoElement*,
772       int already_uploaded_id,
773       WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);
774 
775   // Structure for rendering to a DrawingBuffer, instead of directly
776   // to the back-buffer of m_context.
777   scoped_refptr<DrawingBuffer> drawing_buffer_;
778 
779   Member<WebGLContextGroup> context_group_;
780 
781   bool is_origin_top_left_ = false;
782 
783   bool is_hidden_ = false;
784   LostContextMode context_lost_mode_ = kNotLostContext;
785   AutoRecoveryMethod auto_recovery_method_ = kManual;
786   // Dispatches a context lost event once it is determined that one is needed.
787   // This is used for synthetic, WEBGL_lose_context and real context losses. For
788   // real ones, it's likely that there's no JavaScript on the stack, but that
789   // might be dependent on how exactly the platform discovers that the context
790   // was lost. For better portability we always defer the dispatch of the event.
791   TaskRunnerTimer<WebGLRenderingContextBase> dispatch_context_lost_event_timer_;
792   bool restore_allowed_ = false;
793   TaskRunnerTimer<WebGLRenderingContextBase> restore_timer_;
794   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
795 
796   bool destruction_in_progress_ = false;
797   bool marked_canvas_dirty_;
798   // For performance reasons we must separately track whether we've
799   // copied WebGL's drawing buffer to the canvas's backing store, for
800   // example for printing.
801   bool must_paint_to_canvas_;
802 
803   // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and
804   // stored values for ELEMENT_ARRAY_BUFFER
805   Member<WebGLBuffer> bound_array_buffer_;
806 
807   Member<WebGLVertexArrayObjectBase> default_vertex_array_object_;
808   Member<WebGLVertexArrayObjectBase> bound_vertex_array_object_;
809   void SetBoundVertexArrayObject(WebGLVertexArrayObjectBase*);
810 
811   enum VertexAttribValueType {
812     kFloat32ArrayType,
813     kInt32ArrayType,
814     kUint32ArrayType,
815   };
816 
817   Vector<VertexAttribValueType> vertex_attrib_type_;
818   unsigned max_vertex_attribs_;
819   void SetVertexAttribType(GLuint index, VertexAttribValueType);
820 
821   Member<WebGLProgram> current_program_;
822   Member<WebGLFramebuffer> framebuffer_binding_;
823   Member<WebGLRenderbuffer> renderbuffer_binding_;
824 
825   static bool MakeXrCompatibleSync(CanvasRenderingContextHost* host);
826   static bool IsXrCompatibleFromResult(
827       device::mojom::blink::XrCompatibleResult result);
828   static bool DidGpuRestart(device::mojom::blink::XrCompatibleResult result);
829   void MakeXrCompatibleAsync();
830   void OnMakeXrCompatibleFinished(
831       device::mojom::blink::XrCompatibleResult xr_compatible_result);
832   void CompleteXrCompatiblePromiseIfPending(DOMExceptionCode exception_code);
833   bool xr_compatible_;
834   Member<ScriptPromiseResolver> make_xr_compatible_resolver_;
835 
836   HeapVector<TextureUnitState> texture_units_;
837   wtf_size_t active_texture_unit_;
838 
839   Vector<GLenum> compressed_texture_formats_;
840 
841   // Fixed-size cache of reusable resource providers for video texImage2D calls.
842   class LRUCanvasResourceProviderCache {
843    public:
844     explicit LRUCanvasResourceProviderCache(wtf_size_t capacity);
845     // The pointer returned is owned by the image buffer map.
846     CanvasResourceProvider* GetCanvasResourceProvider(const IntSize&);
847 
848    private:
849     void BubbleToFront(wtf_size_t idx);
850     Vector<std::unique_ptr<CanvasResourceProvider>> resource_providers_;
851   };
852   LRUCanvasResourceProviderCache generated_image_cache_ =
853       LRUCanvasResourceProviderCache(4);
854 
855   GLint max_texture_size_;
856   GLint max_cube_map_texture_size_;
857   GLint max3d_texture_size_;
858   GLint max_array_texture_layers_;
859   GLint max_renderbuffer_size_;
860   GLint max_viewport_dims_[2];
861   GLint max_texture_level_;
862   GLint max_cube_map_texture_level_;
863   GLint max3d_texture_level_;
864 
865   GLint max_draw_buffers_;
866   GLint max_color_attachments_;
867   GLenum back_draw_buffer_;
868   bool draw_buffers_web_gl_requirements_checked_;
869   bool draw_buffers_supported_;
870 
871   GLenum read_buffer_of_default_framebuffer_;
872 
873   GLint pack_alignment_ = 4;
874   GLint unpack_alignment_ = 4;
875   bool unpack_flip_y_ = false;
876   bool unpack_premultiply_alpha_ = false;
877   GLenum unpack_colorspace_conversion_ = GC3D_BROWSER_DEFAULT_WEBGL;
878   // The following three unpack params belong to WebGL2 only.
879   GLint unpack_skip_pixels_ = 0;
880   GLint unpack_skip_rows_ = 0;
881   GLint unpack_row_length_ = 0;
882 
883   GLfloat clear_color_[4];
884   bool scissor_enabled_;
885   GLint scissor_box_[4];
886   GLfloat clear_depth_;
887   GLint clear_stencil_;
888   GLboolean color_mask_[4];
889   GLboolean depth_mask_;
890 
891   bool stencil_enabled_;
892   GLuint stencil_mask_, stencil_mask_back_;
893   GLint stencil_func_ref_,
894       stencil_func_ref_back_;  // Note that these are the user specified values,
895                                // not the internal clamped value.
896   GLuint stencil_func_mask_, stencil_func_mask_back_;
897 
898   bool is_depth_stencil_supported_;
899 
900   bool synthesized_errors_to_console_ = true;
901   int num_gl_errors_to_console_allowed_;
902 
903   wtf_size_t one_plus_max_non_default_texture_unit_ = 0;
904 
905   std::unique_ptr<Extensions3DUtil> extensions_util_;
906 
907   enum ExtensionFlags {
908     kApprovedExtension = 0x00,
909     // Extension that is behind the draft extensions runtime flag:
910     kDraftExtension = 0x01,
911   };
912 
913   class ExtensionTracker : public GarbageCollected<ExtensionTracker>,
914                            public NameClient {
915    public:
ExtensionTracker(ExtensionFlags flags,const char * const * prefixes)916     ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
917         : draft_(flags & kDraftExtension), prefixes_(prefixes) {}
918 
Draft()919     bool Draft() const { return draft_; }
920 
921     const char* const* Prefixes() const;
922     bool MatchesNameWithPrefixes(const String&) const;
923 
924     virtual WebGLExtension* GetExtension(WebGLRenderingContextBase*) = 0;
925     virtual bool Supported(WebGLRenderingContextBase*) const = 0;
926     virtual const char* ExtensionName() const = 0;
927     virtual void LoseExtension(bool) = 0;
928 
929     // This is only used for keeping the JS wrappers of extensions alive.
930     virtual WebGLExtension* GetExtensionObjectIfAlreadyEnabled() = 0;
931 
Trace(Visitor * visitor)932     virtual void Trace(Visitor* visitor) const {}
NameInHeapSnapshot()933     const char* NameInHeapSnapshot() const override {
934       return "ExtensionTracker";
935     }
936 
937    private:
938     bool draft_;
939     const char* const* prefixes_;
940   };
941 
942   template <typename T>
943   class TypedExtensionTracker final : public ExtensionTracker {
944    public:
TypedExtensionTracker(Member<T> & extension_field,ExtensionFlags flags,const char * const * prefixes)945     TypedExtensionTracker(Member<T>& extension_field,
946                           ExtensionFlags flags,
947                           const char* const* prefixes)
948         : ExtensionTracker(flags, prefixes),
949           extension_field_(extension_field) {}
950 
GetExtension(WebGLRenderingContextBase * context)951     WebGLExtension* GetExtension(WebGLRenderingContextBase* context) override {
952       if (!extension_) {
953         extension_ = MakeGarbageCollected<T>(context);
954         extension_field_ = extension_;
955       }
956 
957       return extension_;
958     }
959 
Supported(WebGLRenderingContextBase * context)960     bool Supported(WebGLRenderingContextBase* context) const override {
961       return T::Supported(context);
962     }
963 
ExtensionName()964     const char* ExtensionName() const override { return T::ExtensionName(); }
965 
LoseExtension(bool force)966     void LoseExtension(bool force) override {
967       if (extension_) {
968         extension_->Lose(force);
969         if (extension_->IsLost())
970           extension_ = nullptr;
971       }
972     }
973 
GetExtensionObjectIfAlreadyEnabled()974     WebGLExtension* GetExtensionObjectIfAlreadyEnabled() override {
975       return extension_;
976     }
977 
Trace(Visitor * visitor)978     void Trace(Visitor* visitor) const override {
979       visitor->Trace(extension_);
980       ExtensionTracker::Trace(visitor);
981     }
982 
983    private:
984     GC_PLUGIN_IGNORE("http://crbug.com/519953")
985     Member<T>& extension_field_;
986     // ExtensionTracker holds it's own reference to the extension to ensure
987     // that it is not deleted before this object's destructor is called
988     Member<T> extension_;
989   };
990 
991   bool extension_enabled_[kWebGLExtensionNameCount];
992   HeapVector<Member<ExtensionTracker>> extensions_;
993   HashSet<String> disabled_extensions_;
994 
995   template <typename T>
996   void RegisterExtension(Member<T>& extension_ptr,
997                          ExtensionFlags flags = kApprovedExtension,
998                          const char* const* prefixes = nullptr) {
999     extensions_.push_back(MakeGarbageCollected<TypedExtensionTracker<T>>(
1000         extension_ptr, flags, prefixes));
1001   }
1002 
1003   bool ExtensionSupportedAndAllowed(const ExtensionTracker*);
1004 
ExtensionEnabled(WebGLExtensionName name)1005   inline bool ExtensionEnabled(WebGLExtensionName name) {
1006     return extension_enabled_[name];
1007   }
1008 
1009   // ScopedDrawingBufferBinder is used for
1010   // ReadPixels/CopyTexImage2D/CopySubImage2D to read from a multisampled
1011   // DrawingBuffer. In this situation, we need to blit to a single sampled
1012   // buffer for reading, during which the bindings could be changed and need to
1013   // be recovered.
1014   class ScopedDrawingBufferBinder {
1015     STACK_ALLOCATED();
1016 
1017    public:
ScopedDrawingBufferBinder(DrawingBuffer * drawing_buffer,WebGLFramebuffer * framebuffer_binding)1018     ScopedDrawingBufferBinder(DrawingBuffer* drawing_buffer,
1019                               WebGLFramebuffer* framebuffer_binding)
1020         : drawing_buffer_(drawing_buffer),
1021           read_framebuffer_binding_(framebuffer_binding) {
1022       // Commit DrawingBuffer if needed (e.g., for multisampling)
1023       if (!read_framebuffer_binding_ && drawing_buffer_)
1024         drawing_buffer_->ResolveAndBindForReadAndDraw();
1025     }
1026 
~ScopedDrawingBufferBinder()1027     ~ScopedDrawingBufferBinder() {
1028       // Restore DrawingBuffer if needed
1029       if (!read_framebuffer_binding_ && drawing_buffer_)
1030         drawing_buffer_->RestoreFramebufferBindings();
1031     }
1032 
1033    private:
1034     DrawingBuffer* drawing_buffer_;
1035     WebGLFramebuffer* read_framebuffer_binding_;
1036   };
1037 
1038   // Errors raised by synthesizeGLError() while the context is lost.
1039   Vector<GLenum> lost_context_errors_;
1040   // Other errors raised by synthesizeGLError().
1041   Vector<GLenum> synthetic_errors_;
1042 
1043   bool is_web_gl2_formats_types_added_ = false;
1044   bool is_web_gl2_tex_image_source_formats_types_added_ = false;
1045   bool is_web_gl2_internal_formats_copy_tex_image_added_ = false;
1046   bool is_oes_texture_float_formats_types_added_ = false;
1047   bool is_oes_texture_half_float_formats_types_added_ = false;
1048   bool is_web_gl_depth_texture_formats_types_added_ = false;
1049   bool is_ext_srgb_formats_types_added_ = false;
1050   bool is_ext_color_buffer_float_formats_added_ = false;
1051   bool is_ext_color_buffer_half_float_formats_added_ = false;
1052   bool is_ext_texture_norm16_added_ = false;
1053 
1054   GLenumHashSet supported_internal_formats_;
1055   GLenumHashSet supported_tex_image_source_internal_formats_;
1056   GLenumHashSet supported_internal_formats_copy_tex_image_;
1057   GLenumHashSet supported_formats_;
1058   GLenumHashSet supported_tex_image_source_formats_;
1059   GLenumHashSet supported_types_;
1060   GLenumHashSet supported_tex_image_source_types_;
1061 
1062   // Helpers for getParameter and others
1063   ScriptValue GetBooleanParameter(ScriptState*, GLenum);
1064   ScriptValue GetBooleanArrayParameter(ScriptState*, GLenum);
1065   ScriptValue GetFloatParameter(ScriptState*, GLenum);
1066   ScriptValue GetIntParameter(ScriptState*, GLenum);
1067   ScriptValue GetInt64Parameter(ScriptState*, GLenum);
1068   ScriptValue GetUnsignedIntParameter(ScriptState*, GLenum);
1069   ScriptValue GetWebGLFloatArrayParameter(ScriptState*, GLenum);
1070   ScriptValue GetWebGLIntArrayParameter(ScriptState*, GLenum);
1071 
1072   // Clear the backbuffer if it was composited since the last operation.
1073   // clearMask is set to the bitfield of any clear that would happen anyway at
1074   // this time and the function returns |CombinedClear| if that clear is now
1075   // unnecessary.
1076   enum HowToClear {
1077     // Skip clearing the backbuffer.
1078     kSkipped,
1079     // Clear the backbuffer.
1080     kJustClear,
1081     // Combine webgl.clear() API with the backbuffer clear, so webgl.clear()
1082     // doesn't have to call glClear() again.
1083     kCombinedClear
1084   };
1085   HowToClear ClearIfComposited(GLbitfield clear_mask = 0);
1086 
1087   // Convert texture internal format.
1088   GLenum ConvertTexInternalFormat(GLenum internalformat, GLenum type);
1089 
1090   enum TexImageFunctionType {
1091     kTexImage,
1092     kTexSubImage,
1093     kCopyTexImage,
1094     kCompressedTexImage
1095   };
1096 
1097   // This must stay in sync with WebMediaPlayer::TexImageFunctionID.
1098   enum TexImageFunctionID {
1099     kTexImage2D,
1100     kTexSubImage2D,
1101     kTexImage3D,
1102     kTexSubImage3D
1103   };
1104 
1105   enum TexImageDimension { kTex2D, kTex3D };
1106   void TexImage2DBase(GLenum target,
1107                       GLint level,
1108                       GLint internalformat,
1109                       GLsizei width,
1110                       GLsizei height,
1111                       GLint border,
1112                       GLenum format,
1113                       GLenum type,
1114                       const void* pixels);
1115   void TexImageImpl(TexImageFunctionID,
1116                     GLenum target,
1117                     GLint level,
1118                     GLint internalformat,
1119                     GLint xoffset,
1120                     GLint yoffset,
1121                     GLint zoffset,
1122                     GLenum format,
1123                     GLenum type,
1124                     Image*,
1125                     WebGLImageConversion::ImageHtmlDomSource,
1126                     bool flip_y,
1127                     bool premultiply_alpha,
1128                     const IntRect&,
1129                     GLsizei depth,
1130                     GLint unpack_image_height);
1131   template <typename T>
GetTextureSourceSize(T * texture_source)1132   IntRect GetTextureSourceSize(T* texture_source) {
1133     return IntRect(0, 0, texture_source->width(), texture_source->height());
1134   }
1135 
1136   template <typename T>
ValidateTexImageSubRectangle(const char * function_name,TexImageFunctionID function_id,T * image,const IntRect & sub_rect,GLsizei depth,GLint unpack_image_height,bool * selecting_sub_rectangle)1137   bool ValidateTexImageSubRectangle(const char* function_name,
1138                                     TexImageFunctionID function_id,
1139                                     T* image,
1140                                     const IntRect& sub_rect,
1141                                     GLsizei depth,
1142                                     GLint unpack_image_height,
1143                                     bool* selecting_sub_rectangle) {
1144     DCHECK(function_name);
1145     DCHECK(selecting_sub_rectangle);
1146     if (!image) {
1147       // Probably indicates a failure to allocate the image.
1148       SynthesizeGLError(GL_OUT_OF_MEMORY, function_name, "out of memory");
1149       return false;
1150     }
1151 
1152     int image_width = static_cast<int>(image->width());
1153     int image_height = static_cast<int>(image->height());
1154     *selecting_sub_rectangle =
1155         !(sub_rect.X() == 0 && sub_rect.Y() == 0 &&
1156           sub_rect.Width() == image_width && sub_rect.Height() == image_height);
1157     // If the source image rect selects anything except the entire
1158     // contents of the image, assert that we're running WebGL 2.0 or
1159     // higher, since this should never happen for WebGL 1.0 (even though
1160     // the code could support it). If the image is null, that will be
1161     // signaled as an error later.
1162     DCHECK(!*selecting_sub_rectangle || IsWebGL2())
1163         << "subRect = (" << sub_rect.Width() << " x " << sub_rect.Height()
1164         << ") @ (" << sub_rect.X() << ", " << sub_rect.Y() << "), image = ("
1165         << image_width << " x " << image_height << ")";
1166 
1167     if (!sub_rect.IsValid() || sub_rect.X() < 0 || sub_rect.Y() < 0 ||
1168         sub_rect.MaxX() > image_width || sub_rect.MaxY() > image_height ||
1169         sub_rect.Width() < 0 || sub_rect.Height() < 0) {
1170       SynthesizeGLError(GL_INVALID_OPERATION, function_name,
1171                         "source sub-rectangle specified via pixel unpack "
1172                         "parameters is invalid");
1173       return false;
1174     }
1175 
1176     if (function_id == kTexImage3D || function_id == kTexSubImage3D) {
1177       DCHECK_GE(unpack_image_height, 0);
1178 
1179       if (depth < 1) {
1180         SynthesizeGLError(GL_INVALID_OPERATION, function_name,
1181                           "Can't define a 3D texture with depth < 1");
1182         return false;
1183       }
1184 
1185       // According to the WebGL 2.0 spec, specifying depth > 1 means
1186       // to select multiple rectangles stacked vertically.
1187       base::CheckedNumeric<GLint> max_y_accessed;
1188       if (unpack_image_height) {
1189         max_y_accessed = unpack_image_height;
1190       } else {
1191         max_y_accessed = sub_rect.Height();
1192       }
1193       max_y_accessed *= depth - 1;
1194       max_y_accessed += sub_rect.Height();
1195       max_y_accessed += sub_rect.Y();
1196 
1197       if (!max_y_accessed.IsValid()) {
1198         SynthesizeGLError(GL_INVALID_OPERATION, function_name,
1199                           "Out-of-range parameters passed for 3D texture "
1200                           "upload");
1201         return false;
1202       }
1203 
1204       if (max_y_accessed.ValueOrDie() > image_height) {
1205         SynthesizeGLError(GL_INVALID_OPERATION, function_name,
1206                           "Not enough data supplied to upload to a 3D texture "
1207                           "with depth > 1");
1208         return false;
1209       }
1210     } else {
1211       DCHECK_EQ(depth, 1);
1212       DCHECK_EQ(unpack_image_height, 0);
1213     }
1214     return true;
1215   }
1216 
1217   virtual WebGLImageConversion::PixelStoreParams GetPackPixelStoreParams();
1218   virtual WebGLImageConversion::PixelStoreParams GetUnpackPixelStoreParams(
1219       TexImageDimension);
1220 
1221   // Helper function for copyTex{Sub}Image, check whether the internalformat
1222   // and the color buffer format of the current bound framebuffer combination
1223   // is valid.
1224   bool IsTexInternalFormatColorBufferCombinationValid(
1225       GLenum tex_internal_format,
1226       GLenum color_buffer_format);
1227 
1228   // Helper function to verify limits on the length of uniform and attribute
1229   // locations.
GetMaxWebGLLocationLength()1230   virtual unsigned GetMaxWebGLLocationLength() const { return 256; }
1231   bool ValidateLocationLength(const char* function_name, const String&);
1232 
1233   // Helper function to check if size is non-negative.
1234   // Generate GL error and return false for negative inputs; otherwise, return
1235   // true.
1236   bool ValidateSize(const char* function_name, GLint x, GLint y, GLint z = 0);
1237 
1238   // Helper function to check if a character belongs to the ASCII subset as
1239   // defined in GLSL ES 1.0 spec section 3.1.
1240   bool ValidateCharacter(unsigned char c);
1241 
1242   // Helper function to check if all characters in the string belong to the
1243   // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
1244   bool ValidateString(const char* function_name, const String&);
1245 
1246   // Helper function to check if an identifier starts with reserved prefixes.
1247   bool IsPrefixReserved(const String& name);
1248 
1249   virtual bool ValidateShaderType(const char* function_name,
1250                                   GLenum shader_type);
1251 
1252   // Helper function to check texture binding target and texture bound to the
1253   // target.  Generate GL errors and return 0 if target is invalid or texture
1254   // bound is null.  Otherwise, return the texture bound to the target.
1255   WebGLTexture* ValidateTextureBinding(const char* function_name,
1256                                        GLenum target);
1257 
1258   // Wrapper function for validateTexture2D(3D)Binding, used in TexImageHelper
1259   // functions.
1260   virtual WebGLTexture* ValidateTexImageBinding(const char*,
1261                                                 TexImageFunctionID,
1262                                                 GLenum);
1263 
1264   // Helper function to check texture 2D target and texture bound to the target.
1265   // Generate GL errors and return 0 if target is invalid or texture bound is
1266   // null.  Otherwise, return the texture bound to the target.
1267   WebGLTexture* ValidateTexture2DBinding(const char* function_name,
1268                                          GLenum target);
1269 
1270   void AddExtensionSupportedFormatsTypes();
1271   void AddExtensionSupportedFormatsTypesWebGL2();
1272 
1273   // Helper function to check input internalformat/format/type for functions
1274   // Tex{Sub}Image taking TexImageSource source data.  Generates GL error and
1275   // returns false if parameters are invalid.
1276   bool ValidateTexImageSourceFormatAndType(const char* function_name,
1277                                            TexImageFunctionType,
1278                                            GLenum internalformat,
1279                                            GLenum format,
1280                                            GLenum type);
1281 
1282   // Helper function to check input internalformat/format/type for functions
1283   // Tex{Sub}Image.  Generates GL error and returns false if parameters are
1284   // invalid.
1285   bool ValidateTexFuncFormatAndType(const char* function_name,
1286                                     TexImageFunctionType,
1287                                     GLenum internalformat,
1288                                     GLenum format,
1289                                     GLenum type,
1290                                     GLint level);
1291 
1292   // Helper function to check readbuffer validity for copyTex{Sub}Image.
1293   // If yes, obtains the bound read framebuffer, returns true.
1294   // If not, generates a GL error, returns false.
1295   bool ValidateReadBufferAndGetInfo(
1296       const char* function_name,
1297       WebGLFramebuffer*& read_framebuffer_binding);
1298 
1299   // Helper function to check format/type and ArrayBuffer view type for
1300   // readPixels.
1301   // Generates INVALID_ENUM and returns false if parameters are invalid.
1302   // Generates INVALID_OPERATION if ArrayBuffer view type is incompatible with
1303   // type.
1304   virtual bool ValidateReadPixelsFormatAndType(GLenum format,
1305                                                GLenum type,
1306                                                DOMArrayBufferView*);
1307 
1308   // Helper function to check parameters of readPixels. Returns true if all
1309   // parameters are valid. Otherwise, generates appropriate error and returns
1310   // false.
1311   bool ValidateReadPixelsFuncParameters(GLsizei width,
1312                                         GLsizei height,
1313                                         GLenum format,
1314                                         GLenum type,
1315                                         DOMArrayBufferView*,
1316                                         int64_t buffer_size);
1317 
1318   virtual GLint GetMaxTextureLevelForTarget(GLenum target);
1319 
1320   // Helper function to check input level for functions {copy}Tex{Sub}Image.
1321   // Generates GL error and returns false if level is invalid.
1322   bool ValidateTexFuncLevel(const char* function_name,
1323                             GLenum target,
1324                             GLint level);
1325 
1326   // Helper function to check if a 64-bit value is non-negative and can fit into
1327   // a 32-bit integer.  Generates GL error and returns false if not.
1328   bool ValidateValueFitNonNegInt32(const char* function_name,
1329                                    const char* param_name,
1330                                    int64_t value);
1331 
1332   enum TexFuncValidationSourceType {
1333     kSourceArrayBufferView,
1334     kSourceImageData,
1335     kSourceHTMLImageElement,
1336     kSourceHTMLCanvasElement,
1337     kSourceHTMLVideoElement,
1338     kSourceImageBitmap,
1339     kSourceUnpackBuffer,
1340   };
1341 
1342   // Helper function for tex{Sub}Image{2|3}D to check if the input
1343   // format/type/level/target/width/height/depth/border/xoffset/yoffset/zoffset
1344   // are valid.  Otherwise, it would return quickly without doing other work.
1345   bool ValidateTexFunc(const char* function_name,
1346                        TexImageFunctionType,
1347                        TexFuncValidationSourceType,
1348                        GLenum target,
1349                        GLint level,
1350                        GLenum internalformat,
1351                        GLsizei width,
1352                        GLsizei height,
1353                        GLsizei depth,
1354                        GLint border,
1355                        GLenum format,
1356                        GLenum type,
1357                        GLint xoffset,
1358                        GLint yoffset,
1359                        GLint zoffset);
1360 
1361   // Helper function to check input width and height for functions {copy,
1362   // compressed}Tex{Sub}Image.  Generates GL error and returns false if width or
1363   // height is invalid.
1364   bool ValidateTexFuncDimensions(const char* function_name,
1365                                  TexImageFunctionType,
1366                                  GLenum target,
1367                                  GLint level,
1368                                  GLsizei width,
1369                                  GLsizei height,
1370                                  GLsizei depth);
1371 
1372   // Helper function to check input parameters for functions
1373   // {copy}Tex{Sub}Image.  Generates GL error and returns false if parameters
1374   // are invalid.
1375   bool ValidateTexFuncParameters(const char* function_name,
1376                                  TexImageFunctionType,
1377                                  TexFuncValidationSourceType,
1378                                  GLenum target,
1379                                  GLint level,
1380                                  GLenum internalformat,
1381                                  GLsizei width,
1382                                  GLsizei height,
1383                                  GLsizei depth,
1384                                  GLint border,
1385                                  GLenum format,
1386                                  GLenum type);
1387 
1388   enum NullDisposition { kNullAllowed, kNullNotAllowed, kNullNotReachable };
1389 
1390   // Helper function to validate that the given ArrayBufferView
1391   // is of the correct type and contains enough data for the texImage call.
1392   // Generates GL error and returns false if parameters are invalid.
1393   bool ValidateTexFuncData(const char* function_name,
1394                            TexImageDimension,
1395                            GLint level,
1396                            GLsizei width,
1397                            GLsizei height,
1398                            GLsizei depth,
1399                            GLenum format,
1400                            GLenum type,
1401                            DOMArrayBufferView* pixels,
1402                            NullDisposition,
1403                            GLuint src_offset);
1404 
1405   // Helper function to validate a given texture format is settable as in
1406   // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
1407   // copyTexSubImage2D.
1408   // Generates GL error and returns false if the format is not settable.
1409   bool ValidateSettableTexFormat(const char* function_name, GLenum format);
1410 
1411   // Helper function to validate format for CopyTexImage.
1412   bool ValidateCopyTexFormat(const char* function_name, GLenum format);
1413 
1414   // Helper function for validating compressed texture formats.
1415   bool ValidateCompressedTexFormat(const char* function_name, GLenum format);
1416 
1417   // Helper function to validate stencil or depth func.
1418   bool ValidateStencilOrDepthFunc(const char* function_name, GLenum);
1419 
1420   // Helper function for texParameterf and texParameteri.
1421   void TexParameter(GLenum target,
1422                     GLenum pname,
1423                     GLfloat paramf,
1424                     GLint parami,
1425                     bool is_float);
1426 
1427   // Helper function to print GL errors to console.
1428   void PrintGLErrorToConsole(const String&);
1429 
1430   // Helper function to print warnings to console. Currently
1431   // used only to warn about use of obsolete functions.
1432   void PrintWarningToConsole(const String&);
1433 
1434   // Wrap probe::DidFireWebGLErrorOrWarning and friends, but defer inside a
1435   // FastCall.
1436   void NotifyWebGLErrorOrWarning(const String& message);
1437   void NotifyWebGLError(const String& error_type);
1438   void NotifyWebGLWarning();
1439 
1440   // Helper function to validate the target for checkFramebufferStatus and
1441   // validateFramebufferFuncParameters.
1442   virtual bool ValidateFramebufferTarget(GLenum target);
1443 
1444   // Get the framebuffer bound to given target
1445   virtual WebGLFramebuffer* GetFramebufferBinding(GLenum target);
1446 
1447   virtual WebGLFramebuffer* GetReadFramebufferBinding();
1448 
1449   // Helper function to validate input parameters for framebuffer functions.
1450   // Generate GL error if parameters are illegal.
1451   bool ValidateFramebufferFuncParameters(const char* function_name,
1452                                          GLenum target,
1453                                          GLenum attachment);
1454 
1455   // Helper function to validate blend equation mode.
1456   bool ValidateBlendEquation(const char* function_name, GLenum);
1457 
1458   // Helper function to validate blend func factors.
1459   bool ValidateBlendFuncFactors(const char* function_name,
1460                                 GLenum src,
1461                                 GLenum dst);
1462 
1463   // Helper function to validate a GL capability.
1464   virtual bool ValidateCapability(const char* function_name, GLenum);
1465 
1466   // Helper function to validate input parameters for uniform functions.
1467   bool ValidateUniformParameters(const char* function_name,
1468                                  const WebGLUniformLocation*,
1469                                  void*,
1470                                  GLsizei,
1471                                  GLsizei mod,
1472                                  GLuint src_offset,
1473                                  GLuint src_length);
1474   bool ValidateUniformMatrixParameters(const char* function_name,
1475                                        const WebGLUniformLocation*,
1476                                        GLboolean transpose,
1477                                        DOMFloat32Array*,
1478                                        GLsizei mod,
1479                                        GLuint src_offset,
1480                                        size_t src_length);
1481   bool ValidateUniformMatrixParameters(const char* function_name,
1482                                        const WebGLUniformLocation*,
1483                                        GLboolean transpose,
1484                                        void*,
1485                                        size_t size,
1486                                        GLsizei mod,
1487                                        GLuint src_offset,
1488                                        GLuint src_length);
1489 
1490   template <typename WTFTypedArray>
ValidateUniformParameters(const char * function_name,const WebGLUniformLocation * location,const TypedFlexibleArrayBufferView<WTFTypedArray> & v,GLsizei required_min_size,GLuint src_offset,size_t src_length)1491   bool ValidateUniformParameters(
1492       const char* function_name,
1493       const WebGLUniformLocation* location,
1494       const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
1495       GLsizei required_min_size,
1496       GLuint src_offset,
1497       size_t src_length) {
1498     GLuint length;
1499     if (!base::CheckedNumeric<GLuint>(src_length).AssignIfValid(&length)) {
1500       SynthesizeGLError(GL_INVALID_VALUE, function_name,
1501                         "src_length is too big");
1502       return false;
1503     }
1504     GLuint array_length;
1505     if (!base::CheckedNumeric<GLuint>(v.length())
1506              .AssignIfValid(&array_length)) {
1507       SynthesizeGLError(GL_INVALID_VALUE, function_name, "array is too big");
1508       return false;
1509     }
1510     if (!v.DataMaybeOnStack()) {
1511       SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
1512       return false;
1513     }
1514     return ValidateUniformMatrixParameters(
1515         function_name, location, false, v.DataMaybeOnStack(), array_length,
1516         required_min_size, src_offset, length);
1517   }
1518 
1519   // Helper function to validate the target for bufferData and
1520   // getBufferParameter.
1521   virtual bool ValidateBufferTarget(const char* function_name, GLenum target);
1522 
1523   // Helper function to validate the target for bufferData.
1524   // Return the current bound buffer to target, or 0 if the target is invalid.
1525   virtual WebGLBuffer* ValidateBufferDataTarget(const char* function_name,
1526                                                 GLenum target);
1527   // Helper function to validate the usage for bufferData.
1528   virtual bool ValidateBufferDataUsage(const char* function_name, GLenum usage);
1529 
1530   virtual bool ValidateAndUpdateBufferBindTarget(const char* function_name,
1531                                                  GLenum target,
1532                                                  WebGLBuffer*);
1533 
1534   virtual void RemoveBoundBuffer(WebGLBuffer*);
1535 
1536   // Helper function for tex{Sub}Image2D to make sure image is ready and
1537   // wouldn't taint Origin.
1538 
1539   bool ValidateHTMLImageElement(const SecurityOrigin*,
1540                                 const char* function_name,
1541                                 HTMLImageElement*,
1542                                 ExceptionState&);
1543 
1544   // Helper function for tex{Sub}Image2D to make sure canvas or OffscreenCanvas
1545   // is ready and wouldn't taint Origin.
1546   bool ValidateCanvasRenderingContextHost(const SecurityOrigin*,
1547                                           const char* function_name,
1548                                           CanvasRenderingContextHost*,
1549                                           ExceptionState&);
1550 
1551   // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't
1552   // taint Origin.
1553   bool ValidateHTMLVideoElement(const SecurityOrigin*,
1554                                 const char* function_name,
1555                                 HTMLVideoElement*,
1556                                 ExceptionState&);
1557 
1558   // Helper function for tex{Sub}Image2D to make sure imagebitmap is ready and
1559   // wouldn't taint Origin.
1560   bool ValidateImageBitmap(const char* function_name,
1561                            ImageBitmap*,
1562                            ExceptionState&);
1563 
1564   // Helper function to validate drawArrays(Instanced) calls
1565   bool ValidateDrawArrays(const char* function_name);
1566 
1567   // Helper function to validate drawElements(Instanced) calls
1568   bool ValidateDrawElements(const char* function_name,
1569                             GLenum type,
1570                             int64_t offset);
1571 
1572   // Helper function to check if the byte length of {data} fits into an integer
1573   // of type {T.} If so, the byte length is stored in {data_length}.
1574   template <typename T>
ExtractDataLengthIfValid(const char * function_name,MaybeShared<DOMArrayBufferView> data,T * data_length)1575   bool ExtractDataLengthIfValid(const char* function_name,
1576                                 MaybeShared<DOMArrayBufferView> data,
1577                                 T* data_length) {
1578     if (base::CheckedNumeric<T>(data.View()->byteLength())
1579             .AssignIfValid(data_length)) {
1580       return true;
1581     }
1582     SynthesizeGLError(GL_INVALID_VALUE, function_name,
1583                       "provided data exceeds the maximum supported length");
1584     return false;
1585   }
1586 
1587   // State updates and operations necessary before or at draw call time.
1588   virtual void OnBeforeDrawCall();
1589 
1590   // Helper functions to bufferData() and bufferSubData().
1591   void BufferDataImpl(GLenum target,
1592                       int64_t size,
1593                       const void* data,
1594                       GLenum usage);
1595   void BufferSubDataImpl(GLenum target,
1596                          int64_t offset,
1597                          GLsizeiptr,
1598                          const void* data);
1599 
1600   // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
1601   // Return false if caller should return without further processing.
1602   bool DeleteObject(WebGLObject*);
1603 
1604   void DispatchContextLostEvent(TimerBase*);
1605   // Helper for restoration after context lost.
1606   void MaybeRestoreContext(TimerBase*);
1607 
1608   enum ConsoleDisplayPreference { kDisplayInConsole, kDontDisplayInConsole };
1609 
1610   // Reports an error to glGetError, sends a message to the JavaScript
1611   // console.
1612   void SynthesizeGLError(GLenum,
1613                          const char* function_name,
1614                          const char* description,
1615                          ConsoleDisplayPreference = kDisplayInConsole);
1616   void EmitGLWarning(const char* function, const char* reason);
1617 
1618   String EnsureNotNull(const String&) const;
1619 
1620   // Enable or disable stencil test based on user setting and
1621   // whether the current FBO has a stencil buffer.
1622   void ApplyStencilTest();
1623 
1624   // Helper for enabling or disabling a capability.
1625   void EnableOrDisable(GLenum capability, bool enable);
1626 
1627   // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
1628   IntSize ClampedCanvasSize() const;
1629 
1630   // First time called, if EXT_draw_buffers is supported, query the value;
1631   // otherwise return 0.  Later, return the cached value.
1632   GLint MaxDrawBuffers();
1633   GLint MaxColorAttachments();
1634 
1635   void SetBackDrawBuffer(GLenum);
1636   void SetFramebuffer(GLenum, WebGLFramebuffer*);
1637 
1638   virtual void RestoreCurrentFramebuffer();
1639   void RestoreCurrentTexture2D();
1640   void RestoreCurrentTextureCubeMap();
1641 
1642   void FindNewMaxNonDefaultTextureUnit();
1643 
1644   virtual void RenderbufferStorageImpl(GLenum target,
1645                                        GLsizei samples,
1646                                        GLenum internalformat,
1647                                        GLsizei width,
1648                                        GLsizei height,
1649                                        const char* function_name);
1650 
1651   friend class WebGLStateRestorer;
1652   friend class WebGLRenderingContextEvictionManager;
1653 
1654   static void ActivateContext(WebGLRenderingContextBase*);
1655   static void DeactivateContext(WebGLRenderingContextBase*);
1656   static void AddToEvictedList(WebGLRenderingContextBase*);
1657   static void RemoveFromEvictedList(WebGLRenderingContextBase*);
1658   static void RestoreEvictedContext(WebGLRenderingContextBase*);
1659   static void ForciblyLoseOldestContext(const String& reason);
1660   // Return the least recently used context's position in the active context
1661   // vector.  If the vector is empty, return the maximum allowed active context
1662   // number.
1663   static WebGLRenderingContextBase* OldestContext();
1664   static WebGLRenderingContextBase* OldestEvictedContext();
1665 
1666   friend class ScopedRGBEmulationColorMask;
1667   unsigned active_scoped_rgb_emulation_color_masks_;
1668 
1669   ImageBitmap* TransferToImageBitmapBase(ScriptState*);
1670 
1671   // Helper functions for tex(Sub)Image2D && texSubImage3D
1672   void TexImageHelperDOMArrayBufferView(TexImageFunctionID,
1673                                         GLenum,
1674                                         GLint,
1675                                         GLint,
1676                                         GLsizei,
1677                                         GLsizei,
1678                                         GLsizei,
1679                                         GLint,
1680                                         GLenum,
1681                                         GLenum,
1682                                         GLint,
1683                                         GLint,
1684                                         GLint,
1685                                         DOMArrayBufferView*,
1686                                         NullDisposition,
1687                                         GLuint src_offset);
1688   void TexImageHelperImageData(TexImageFunctionID,
1689                                GLenum,
1690                                GLint,
1691                                GLint,
1692                                GLint,
1693                                GLenum,
1694                                GLenum,
1695                                GLsizei,
1696                                GLint,
1697                                GLint,
1698                                GLint,
1699                                ImageData*,
1700                                const IntRect&,
1701                                GLint);
1702 
1703   void TexImageHelperHTMLImageElement(const SecurityOrigin*,
1704                                       TexImageFunctionID,
1705                                       GLenum,
1706                                       GLint,
1707                                       GLint,
1708                                       GLenum,
1709                                       GLenum,
1710                                       GLint,
1711                                       GLint,
1712                                       GLint,
1713                                       HTMLImageElement*,
1714                                       const IntRect&,
1715                                       GLsizei,
1716                                       GLint,
1717                                       ExceptionState&);
1718 
1719   void TexImageHelperCanvasRenderingContextHost(const SecurityOrigin*,
1720                                                 TexImageFunctionID,
1721                                                 GLenum,
1722                                                 GLint,
1723                                                 GLint,
1724                                                 GLenum,
1725                                                 GLenum,
1726                                                 GLint,
1727                                                 GLint,
1728                                                 GLint,
1729                                                 CanvasRenderingContextHost*,
1730                                                 const IntRect&,
1731                                                 GLsizei,
1732                                                 GLint,
1733                                                 ExceptionState&);
1734 
1735   void TexImageHelperHTMLVideoElement(const SecurityOrigin*,
1736                                       TexImageFunctionID,
1737                                       GLenum,
1738                                       GLint,
1739                                       GLint,
1740                                       GLenum,
1741                                       GLenum,
1742                                       GLint,
1743                                       GLint,
1744                                       GLint,
1745                                       HTMLVideoElement*,
1746                                       const IntRect&,
1747                                       GLsizei,
1748                                       GLint,
1749                                       ExceptionState&);
1750   void TexImageHelperImageBitmap(TexImageFunctionID,
1751                                  GLenum,
1752                                  GLint,
1753                                  GLint,
1754                                  GLenum,
1755                                  GLenum,
1756                                  GLint,
1757                                  GLint,
1758                                  GLint,
1759                                  ImageBitmap*,
1760                                  const IntRect&,
1761                                  GLsizei,
1762                                  GLint,
1763                                  ExceptionState&);
1764   static const char* GetTexImageFunctionName(TexImageFunctionID);
1765   IntRect SentinelEmptyRect();
1766   IntRect SafeGetImageSize(Image*);
1767   IntRect GetImageDataSize(ImageData*);
1768 
1769   // Helper implementing readPixels for WebGL 1.0 and 2.0.
1770   void ReadPixelsHelper(GLint x,
1771                         GLint y,
1772                         GLsizei width,
1773                         GLsizei height,
1774                         GLenum format,
1775                         GLenum type,
1776                         DOMArrayBufferView* pixels,
1777                         int64_t offset);
1778 
1779  private:
1780   WebGLRenderingContextBase(CanvasRenderingContextHost*,
1781                             scoped_refptr<base::SingleThreadTaskRunner>,
1782                             std::unique_ptr<WebGraphicsContext3DProvider>,
1783                             bool using_gpu_compositing,
1784                             const CanvasContextCreationAttributesCore&,
1785                             Platform::ContextType);
1786   static bool SupportOwnOffscreenSurface(ExecutionContext*);
1787   static std::unique_ptr<WebGraphicsContext3DProvider>
1788   CreateContextProviderInternal(CanvasRenderingContextHost*,
1789                                 const CanvasContextCreationAttributesCore&,
1790                                 Platform::ContextType context_type,
1791                                 bool* using_gpu_compositing);
1792   // Copy from the source directly to the texture via the gpu, without
1793   // a read-back to system memory. Source can be a texture-backed
1794   // Image, or another canvas's WebGLRenderingContext.
1795   void TexImageViaGPU(TexImageFunctionID,
1796                       WebGLTexture*,
1797                       GLenum,
1798                       GLint,
1799                       GLint,
1800                       GLint,
1801                       GLint,
1802                       AcceleratedStaticBitmapImage*,
1803                       WebGLRenderingContextBase*,
1804                       const IntRect& source_sub_rectangle,
1805                       bool premultiply_alpha,
1806                       bool flip_y);
1807   bool CanUseTexImageViaGPU(GLenum format, GLenum type);
1808 
1809   const Platform::ContextType context_type_;
1810 
IsPaintable()1811   bool IsPaintable() const final { return GetDrawingBuffer(); }
1812 
1813   bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*,
1814                                              SourceDrawingBuffer);
1815   void HoldReferenceToDrawingBuffer(DrawingBuffer*);
1816 
1817   static void InitializeWebGLContextLimits(
1818       WebGraphicsContext3DProvider* context_provider);
1819   static unsigned CurrentMaxGLContexts();
1820 
1821   void RecordIdentifiableGLParameterDigest(GLenum pname,
1822                                            IdentifiableToken value);
1823 
1824   void RecordShaderPrecisionFormatForStudy(GLenum shader_type,
1825                                            GLenum precision_type,
1826                                            WebGLShaderPrecisionFormat* format);
1827 
1828   static bool webgl_context_limits_initialized_;
1829   static unsigned max_active_webgl_contexts_;
1830   static unsigned max_active_webgl_contexts_on_worker_;
1831 
1832   void addProgramCompletionQuery(WebGLProgram* program, GLuint query);
1833   void clearProgramCompletionQueries();
1834   bool checkProgramCompletionQueryAvailable(WebGLProgram* program,
1835                                             bool* completed);
1836   static constexpr unsigned int kMaxProgramCompletionQueries = 128u;
1837   base::MRUCache<WebGLProgram*, GLuint> program_completion_queries_;
1838 
1839   int number_of_user_allocated_multisampled_renderbuffers_;
1840 
1841   friend class WebGLFastCallHelper;
1842   WebGLFastCallHelper fast_call_;
1843 
1844   DISALLOW_COPY_AND_ASSIGN(WebGLRenderingContextBase);
1845 };
1846 
1847 template <>
1848 struct DowncastTraits<WebGLRenderingContextBase> {
1849   static bool AllowFrom(const CanvasRenderingContext& context) {
1850     return context.Is3d();
1851   }
1852 };
1853 
1854 }  // namespace blink
1855 
1856 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
1857     blink::WebGLRenderingContextBase::TextureUnitState)
1858 
1859 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_
1860