7a8b9f41780e67d1ba356798dcf15c8fdc3bba65
[platform/framework/web/crosswalk-tizen.git] /
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 WebGLRenderingContextBase_h
27 #define WebGLRenderingContextBase_h
28
29 #include "bindings/core/v8/Nullable.h"
30 #include "bindings/core/v8/ScriptState.h"
31 #include "bindings/core/v8/ScriptValue.h"
32 #include "bindings/core/v8/ScriptWrappable.h"
33 #include "bindings/core/v8/ScriptWrappableVisitor.h"
34 #include "core/CoreExport.h"
35 #include "core/dom/DOMTypedArray.h"
36 #include "core/dom/TypedFlexibleArrayBufferView.h"
37 #include "core/html/canvas/CanvasContextCreationAttributes.h"
38 #include "core/html/canvas/CanvasRenderingContext.h"
39 #include "core/layout/ContentChangeType.h"
40 #include "modules/webgl/WebGLContextAttributes.h"
41 #include "modules/webgl/WebGLExtensionName.h"
42 #include "modules/webgl/WebGLTexture.h"
43 #include "modules/webgl/WebGLVertexArrayObjectBase.h"
44 #include "platform/Timer.h"
45 #include "platform/graphics/ImageBuffer.h"
46 #include "platform/graphics/gpu/DrawingBuffer.h"
47 #include "platform/graphics/gpu/Extensions3DUtil.h"
48 #include "platform/graphics/gpu/WebGLImageConversion.h"
49 #include "public/platform/Platform.h"
50 #include "public/platform/WebGraphicsContext3DProvider.h"
51 #include "third_party/khronos/GLES2/gl2.h"
52 #include "wtf/CheckedNumeric.h"
53 #include "wtf/text/WTFString.h"
54 #include <memory>
55 #include <set>
56
57 namespace blink {
58 class WebLayer;
59 }
60
61 namespace gpu {
62 namespace gles2 {
63 class GLES2Interface;
64 }
65 }
66
67 namespace blink {
68
69 class EXTDisjointTimerQuery;
70 class EXTDisjointTimerQueryWebGL2;
71 class EXTsRGB;
72 class ExceptionState;
73 class HTMLCanvasElementOrOffscreenCanvas;
74 class HTMLImageElement;
75 class HTMLVideoElement;
76 class ImageBitmap;
77 class ImageBuffer;
78 class ImageData;
79 class IntSize;
80 class OESEglImageExternal;
81 class OESTextureFloat;
82 class OESTextureHalfFloat;
83 class OESVertexArrayObject;
84 class WebGLActiveInfo;
85 class WebGLBuffer;
86 class WebGLCompressedTextureASTC;
87 class WebGLCompressedTextureATC;
88 class WebGLCompressedTextureETC;
89 class WebGLCompressedTextureETC1;
90 class WebGLCompressedTexturePVRTC;
91 class WebGLCompressedTextureS3TC;
92 class WebGLCompressedTextureS3TCsRGB;
93 class WebGLContextGroup;
94 class WebGLContextObject;
95 class WebGLDebugShaders;
96 class WebGLDepthTexture;
97 class WebGLDrawBuffers;
98 class WebGLExtension;
99 class WebGLFramebuffer;
100 class WebGLObject;
101 class WebGLProgram;
102 class WebGLRenderbuffer;
103 class WebGLShader;
104 class WebGLShaderPrecisionFormat;
105 class WebGLSharedObject;
106 class WebGLUniformLocation;
107 class WebGLVertexArrayObjectBase;
108
109 class WebGLRenderingContextErrorMessageCallback;
110
111 // This class uses the color mask to prevent drawing to the alpha channel, if
112 // the DrawingBuffer requires RGB emulation.
113 class ScopedRGBEmulationColorMask {
114  public:
115   ScopedRGBEmulationColorMask(gpu::gles2::GLES2Interface*,
116                               GLboolean* colorMask,
117                               DrawingBuffer*);
118   ~ScopedRGBEmulationColorMask();
119
120  private:
121   gpu::gles2::GLES2Interface* m_contextGL;
122   GLboolean m_colorMask[4];
123   const bool m_requiresEmulation;
124 };
125
126 class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
127                                                  public DrawingBuffer::Client {
128   WTF_MAKE_NONCOPYABLE(WebGLRenderingContextBase);
129
130  public:
131   ~WebGLRenderingContextBase() override;
132
133   virtual String contextName() const = 0;
134   virtual void registerContextExtensions() = 0;
135
136   virtual void initializeNewContext();
137
138   static unsigned getWebGLVersion(const CanvasRenderingContext*);
139
140   static std::unique_ptr<WebGraphicsContext3DProvider>
141   createWebGraphicsContext3DProvider(HTMLCanvasElement*,
142                                      const CanvasContextCreationAttributes&,
143                                      unsigned webGLVersion);
144   static std::unique_ptr<WebGraphicsContext3DProvider>
145   createWebGraphicsContext3DProvider(ScriptState*,
146                                      const CanvasContextCreationAttributes&,
147                                      unsigned webGLVersion);
148   static void forceNextWebGLContextCreationToFail();
149
150   unsigned version() const { return m_version; }
151
152   int drawingBufferWidth() const;
153   int drawingBufferHeight() const;
154
155   void activeTexture(GLenum texture);
156   void attachShader(WebGLProgram*, WebGLShader*);
157   void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
158   void bindBuffer(GLenum target, WebGLBuffer*);
159   virtual void bindFramebuffer(GLenum target, WebGLFramebuffer*);
160   void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
161   void bindTexture(GLenum target, WebGLTexture*);
162   void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
163   void blendEquation(GLenum mode);
164   void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
165   void blendFunc(GLenum sfactor, GLenum dfactor);
166   void blendFuncSeparate(GLenum srcRGB,
167                          GLenum dstRGB,
168                          GLenum srcAlpha,
169                          GLenum dstAlpha);
170
171   void bufferData(GLenum target, long long size, GLenum usage);
172   void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
173   void bufferData(GLenum target, DOMArrayBufferView* data, GLenum usage);
174   void bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data);
175   void bufferSubData(GLenum target,
176                      long long offset,
177                      const FlexibleArrayBufferView& data);
178
179   GLenum checkFramebufferStatus(GLenum target);
180   void clear(GLbitfield mask);
181   void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
182   void clearDepth(GLfloat);
183   void clearStencil(GLint);
184   void colorMask(GLboolean red,
185                  GLboolean green,
186                  GLboolean blue,
187                  GLboolean alpha);
188   void compileShader(WebGLShader*);
189
190   void compressedTexImage2D(GLenum target,
191                             GLint level,
192                             GLenum internalformat,
193                             GLsizei width,
194                             GLsizei height,
195                             GLint border,
196                             DOMArrayBufferView* data);
197   void compressedTexSubImage2D(GLenum target,
198                                GLint level,
199                                GLint xoffset,
200                                GLint yoffset,
201                                GLsizei width,
202                                GLsizei height,
203                                GLenum format,
204                                DOMArrayBufferView* data);
205
206   void copyTexImage2D(GLenum target,
207                       GLint level,
208                       GLenum internalformat,
209                       GLint x,
210                       GLint y,
211                       GLsizei width,
212                       GLsizei height,
213                       GLint border);
214   void copyTexSubImage2D(GLenum target,
215                          GLint level,
216                          GLint xoffset,
217                          GLint yoffset,
218                          GLint x,
219                          GLint y,
220                          GLsizei width,
221                          GLsizei height);
222
223   WebGLBuffer* createBuffer();
224   WebGLFramebuffer* createFramebuffer();
225   WebGLProgram* createProgram();
226   WebGLRenderbuffer* createRenderbuffer();
227   WebGLShader* createShader(GLenum type);
228   WebGLTexture* createTexture();
229
230   void cullFace(GLenum mode);
231
232   void deleteBuffer(WebGLBuffer*);
233   virtual void deleteFramebuffer(WebGLFramebuffer*);
234   void deleteProgram(WebGLProgram*);
235   void deleteRenderbuffer(WebGLRenderbuffer*);
236   void deleteShader(WebGLShader*);
237   void deleteTexture(WebGLTexture*);
238
239   void depthFunc(GLenum);
240   void depthMask(GLboolean);
241   void depthRange(GLfloat zNear, GLfloat zFar);
242   void detachShader(WebGLProgram*, WebGLShader*);
243   void disable(GLenum cap);
244   void disableVertexAttribArray(GLuint index);
245   void drawArrays(GLenum mode, GLint first, GLsizei count);
246   void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
247
248   void drawArraysInstancedANGLE(GLenum mode,
249                                 GLint first,
250                                 GLsizei count,
251                                 GLsizei primcount);
252   void drawElementsInstancedANGLE(GLenum mode,
253                                   GLsizei count,
254                                   GLenum type,
255                                   long long offset,
256                                   GLsizei primcount);
257
258   void enable(GLenum cap);
259   void enableVertexAttribArray(GLuint index);
260   void finish();
261   void flush();
262   void framebufferRenderbuffer(GLenum target,
263                                GLenum attachment,
264                                GLenum renderbuffertarget,
265                                WebGLRenderbuffer*);
266   void framebufferTexture2D(GLenum target,
267                             GLenum attachment,
268                             GLenum textarget,
269                             WebGLTexture*,
270                             GLint level);
271   void frontFace(GLenum mode);
272   void generateMipmap(GLenum target);
273
274   WebGLActiveInfo* getActiveAttrib(WebGLProgram*, GLuint index);
275   WebGLActiveInfo* getActiveUniform(WebGLProgram*, GLuint index);
276   bool getAttachedShaders(WebGLProgram*, HeapVector<Member<WebGLShader>>&);
277   Nullable<HeapVector<Member<WebGLShader>>> getAttachedShaders(WebGLProgram*);
278   GLint getAttribLocation(WebGLProgram*, const String& name);
279   ScriptValue getBufferParameter(ScriptState*, GLenum target, GLenum pname);
280   void getContextAttributes(Nullable<WebGLContextAttributes>&);
281   GLenum getError();
282   ScriptValue getExtension(ScriptState*, const String& name);
283   virtual ScriptValue getFramebufferAttachmentParameter(ScriptState*,
284                                                         GLenum target,
285                                                         GLenum attachment,
286                                                         GLenum pname);
287   virtual ScriptValue getParameter(ScriptState*, GLenum pname);
288   ScriptValue getProgramParameter(ScriptState*, WebGLProgram*, GLenum pname);
289   String getProgramInfoLog(WebGLProgram*);
290   ScriptValue getRenderbufferParameter(ScriptState*,
291                                        GLenum target,
292                                        GLenum pname);
293   ScriptValue getShaderParameter(ScriptState*, WebGLShader*, GLenum pname);
294   String getShaderInfoLog(WebGLShader*);
295   WebGLShaderPrecisionFormat* getShaderPrecisionFormat(GLenum shaderType,
296                                                        GLenum precisionType);
297   String getShaderSource(WebGLShader*);
298   Nullable<Vector<String>> getSupportedExtensions();
299   virtual ScriptValue getTexParameter(ScriptState*,
300                                       GLenum target,
301                                       GLenum pname);
302   ScriptValue getUniform(ScriptState*,
303                          WebGLProgram*,
304                          const WebGLUniformLocation*);
305   WebGLUniformLocation* getUniformLocation(WebGLProgram*, const String&);
306   ScriptValue getVertexAttrib(ScriptState*, GLuint index, GLenum pname);
307   long long getVertexAttribOffset(GLuint index, GLenum pname);
308
309   void hint(GLenum target, GLenum mode);
310   GLboolean isBuffer(WebGLBuffer*);
311   bool isContextLost() const override;
312   GLboolean isEnabled(GLenum cap);
313   GLboolean isFramebuffer(WebGLFramebuffer*);
314   GLboolean isProgram(WebGLProgram*);
315   GLboolean isRenderbuffer(WebGLRenderbuffer*);
316   GLboolean isShader(WebGLShader*);
317   GLboolean isTexture(WebGLTexture*);
318
319   void lineWidth(GLfloat);
320   void linkProgram(WebGLProgram*);
321   virtual void pixelStorei(GLenum pname, GLint param);
322   void polygonOffset(GLfloat factor, GLfloat units);
323   virtual void readPixels(GLint x,
324                           GLint y,
325                           GLsizei width,
326                           GLsizei height,
327                           GLenum format,
328                           GLenum type,
329                           DOMArrayBufferView* pixels);
330   void renderbufferStorage(GLenum target,
331                            GLenum internalformat,
332                            GLsizei width,
333                            GLsizei height);
334   void sampleCoverage(GLfloat value, GLboolean invert);
335   void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
336   void shaderSource(WebGLShader*, const String&);
337   void stencilFunc(GLenum func, GLint ref, GLuint mask);
338   void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
339   void stencilMask(GLuint);
340   void stencilMaskSeparate(GLenum face, GLuint mask);
341   void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
342   void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
343
344   void texImage2D(GLenum target,
345                   GLint level,
346                   GLint internalformat,
347                   GLsizei width,
348                   GLsizei height,
349                   GLint border,
350                   GLenum format,
351                   GLenum type,
352                   DOMArrayBufferView*);
353   void texImage2D(GLenum target,
354                   GLint level,
355                   GLint internalformat,
356                   GLenum format,
357                   GLenum type,
358                   ImageData*);
359   void texImage2D(GLenum target,
360                   GLint level,
361                   GLint internalformat,
362                   GLenum format,
363                   GLenum type,
364                   HTMLImageElement*,
365                   ExceptionState&);
366   void texImage2D(GLenum target,
367                   GLint level,
368                   GLint internalformat,
369                   GLenum format,
370                   GLenum type,
371                   HTMLCanvasElement*,
372                   ExceptionState&);
373   void texImage2D(GLenum target,
374                   GLint level,
375                   GLint internalformat,
376                   GLenum format,
377                   GLenum type,
378                   HTMLVideoElement*,
379                   ExceptionState&);
380   void texImage2D(GLenum target,
381                   GLint level,
382                   GLint internalformat,
383                   GLenum format,
384                   GLenum type,
385                   ImageBitmap*,
386                   ExceptionState&);
387
388   void texParameterf(GLenum target, GLenum pname, GLfloat param);
389   void texParameteri(GLenum target, GLenum pname, GLint param);
390
391   void texSubImage2D(GLenum target,
392                      GLint level,
393                      GLint xoffset,
394                      GLint yoffset,
395                      GLsizei width,
396                      GLsizei height,
397                      GLenum format,
398                      GLenum type,
399                      DOMArrayBufferView*);
400   void texSubImage2D(GLenum target,
401                      GLint level,
402                      GLint xoffset,
403                      GLint yoffset,
404                      GLenum format,
405                      GLenum type,
406                      ImageData*);
407   void texSubImage2D(GLenum target,
408                      GLint level,
409                      GLint xoffset,
410                      GLint yoffset,
411                      GLenum format,
412                      GLenum type,
413                      HTMLImageElement*,
414                      ExceptionState&);
415   void texSubImage2D(GLenum target,
416                      GLint level,
417                      GLint xoffset,
418                      GLint yoffset,
419                      GLenum format,
420                      GLenum type,
421                      HTMLCanvasElement*,
422                      ExceptionState&);
423   void texSubImage2D(GLenum target,
424                      GLint level,
425                      GLint xoffset,
426                      GLint yoffset,
427                      GLenum format,
428                      GLenum type,
429                      HTMLVideoElement*,
430                      ExceptionState&);
431   void texSubImage2D(GLenum target,
432                      GLint level,
433                      GLint xoffset,
434                      GLint yoffset,
435                      GLenum format,
436                      GLenum type,
437                      ImageBitmap*,
438                      ExceptionState&);
439
440   void uniform1f(const WebGLUniformLocation*, GLfloat x);
441   void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
442   void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&);
443   void uniform1i(const WebGLUniformLocation*, GLint x);
444   void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
445   void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&);
446   void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
447   void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
448   void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&);
449   void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
450   void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
451   void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&);
452   void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
453   void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
454   void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&);
455   void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
456   void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
457   void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&);
458   void uniform4f(const WebGLUniformLocation*,
459                  GLfloat x,
460                  GLfloat y,
461                  GLfloat z,
462                  GLfloat w);
463   void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
464   void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&);
465   void uniform4i(const WebGLUniformLocation*,
466                  GLint x,
467                  GLint y,
468                  GLint z,
469                  GLint w);
470   void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
471   void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
472   void uniformMatrix2fv(const WebGLUniformLocation*,
473                         GLboolean transpose,
474                         DOMFloat32Array* value);
475   void uniformMatrix2fv(const WebGLUniformLocation*,
476                         GLboolean transpose,
477                         Vector<GLfloat>& value);
478   void uniformMatrix3fv(const WebGLUniformLocation*,
479                         GLboolean transpose,
480                         DOMFloat32Array* value);
481   void uniformMatrix3fv(const WebGLUniformLocation*,
482                         GLboolean transpose,
483                         Vector<GLfloat>& value);
484   void uniformMatrix4fv(const WebGLUniformLocation*,
485                         GLboolean transpose,
486                         DOMFloat32Array* value);
487   void uniformMatrix4fv(const WebGLUniformLocation*,
488                         GLboolean transpose,
489                         Vector<GLfloat>& value);
490
491   void useProgram(WebGLProgram*);
492   void validateProgram(WebGLProgram*);
493
494   void vertexAttrib1f(GLuint index, GLfloat x);
495   void vertexAttrib1fv(GLuint index, const DOMFloat32Array* values);
496   void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values);
497   void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
498   void vertexAttrib2fv(GLuint index, const DOMFloat32Array* values);
499   void vertexAttrib2fv(GLuint index, const Vector<GLfloat>& values);
500   void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
501   void vertexAttrib3fv(GLuint index, const DOMFloat32Array* values);
502   void vertexAttrib3fv(GLuint index, const Vector<GLfloat>& values);
503   void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
504   void vertexAttrib4fv(GLuint index, const DOMFloat32Array* values);
505   void vertexAttrib4fv(GLuint index, const Vector<GLfloat>& values);
506   void vertexAttribPointer(GLuint index,
507                            GLint size,
508                            GLenum type,
509                            GLboolean normalized,
510                            GLsizei stride,
511                            long long offset);
512
513   void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
514
515   void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
516
517   // WEBGL_lose_context support
518   enum AutoRecoveryMethod {
519     // Don't restore automatically.
520     Manual,
521
522     // Restore when resources are available.
523     WhenAvailable,
524
525     // Restore as soon as possible, but only when
526     // the canvas is visible.
527     Auto
528   };
529   void loseContext(LostContextMode) override;
530   void forceLostContext(LostContextMode, AutoRecoveryMethod);
531   void forceRestoreContext();
532   void loseContextImpl(LostContextMode, AutoRecoveryMethod);
533
534   // Utilities to restore GL state to match the rendering context's
535   // saved state. Use these after contextGL()-based state changes that
536   // bypass the rendering context.
537   void restoreScissorEnabled();
538   void restoreScissorBox();
539   void restoreClearColor();
540   void restoreColorMask();
541
542   gpu::gles2::GLES2Interface* contextGL() const {
543     DrawingBuffer* d = drawingBuffer();
544     if (!d)
545       return nullptr;
546     return d->contextGL();
547   }
548   WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
549   Extensions3DUtil* extensionsUtil();
550
551   void reshape(int width, int height) override;
552
553   void markLayerComposited() override;
554   ImageData* paintRenderingResultsToImageData(SourceDrawingBuffer) override;
555
556   void removeSharedObject(WebGLSharedObject*);
557   void removeContextObject(WebGLContextObject*);
558
559   unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
560
561   // Eagerly finalize WebGLRenderingContextBase in order for it
562   // to (first) be able to detach its WebGLContextObjects, before
563   // they're later swept and finalized.
564   EAGERLY_FINALIZE();
565   DECLARE_EAGER_FINALIZATION_OPERATOR_NEW();
566   DECLARE_VIRTUAL_TRACE();
567
568   DECLARE_VIRTUAL_TRACE_WRAPPERS();
569
570   // Returns approximate gpu memory allocated per pixel.
571   int externallyAllocatedBytesPerPixel() override;
572
573   class TextureUnitState {
574     DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
575
576    public:
577     TraceWrapperMember<WebGLTexture> m_texture2DBinding;
578     TraceWrapperMember<WebGLTexture> m_textureCubeMapBinding;
579     TraceWrapperMember<WebGLTexture> m_texture3DBinding;
580     TraceWrapperMember<WebGLTexture> m_texture2DArrayBinding;
581
582     DECLARE_TRACE();
583     // Wrappers are traced by parent since TextureUnitState is not a heap
584     // object.
585   };
586
587   PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const override;
588   ImageData* toImageData(SnapshotReason) const override;
589   void setFilterQuality(SkFilterQuality) override;
590   bool isWebGL2OrHigher() { return version() >= 2; }
591
592   void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const;
593
594   void commit(ScriptState*, ExceptionState&);
595
596 #if defined(TIZEN_TBM_SUPPORT) && defined(OS_TIZEN_TV_PRODUCT)
597   bool isCurrentVideoTexture();
598   bool doPrepareOESTextureProgram();
599   void doDeleteVideoFrame();
600   void setEnableOESEglImageExternal(bool enable) {
601     m_isEnabledOESEglImageExternal = enable;
602   }
603 #endif
604
605  protected:
606   friend class EXTDisjointTimerQuery;
607   friend class EXTDisjointTimerQueryWebGL2;
608   friend class WebGLDrawBuffers;
609   friend class WebGLFramebuffer;
610   friend class WebGLObject;
611   friend class WebGLContextObject;
612   friend class OESVertexArrayObject;
613   friend class WebGLDebugShaders;
614   friend class WebGLCompressedTextureASTC;
615   friend class WebGLCompressedTextureATC;
616   friend class WebGLCompressedTextureETC;
617   friend class WebGLCompressedTextureETC1;
618   friend class WebGLCompressedTexturePVRTC;
619   friend class WebGLCompressedTextureS3TC;
620   friend class WebGLCompressedTextureS3TCsRGB;
621   friend class WebGLRenderingContextErrorMessageCallback;
622   friend class WebGLVertexArrayObjectBase;
623   friend class ScopedDrawingBufferBinder;
624   friend class ScopedTexture2DRestorer;
625   friend class ScopedFramebufferRestorer;
626   // To allow V8WebGL[2]RenderingContext to call visitChildDOMWrappers.
627   friend class V8WebGLRenderingContext;
628
629   WebGLRenderingContextBase(HTMLCanvasElement*,
630                             std::unique_ptr<WebGraphicsContext3DProvider>,
631                             const CanvasContextCreationAttributes&,
632                             unsigned);
633   WebGLRenderingContextBase(OffscreenCanvas*,
634                             std::unique_ptr<WebGraphicsContext3DProvider>,
635                             const CanvasContextCreationAttributes&,
636                             unsigned);
637   PassRefPtr<DrawingBuffer> createDrawingBuffer(
638       std::unique_ptr<WebGraphicsContext3DProvider>,
639       DrawingBuffer::ChromiumImageUsage);
640   void setupFlags();
641
642   // CanvasRenderingContext implementation.
643   bool is3d() const override { return true; }
644   bool isAccelerated() const override { return true; }
645   void setIsHidden(bool) override;
646   bool paintRenderingResultsToCanvas(SourceDrawingBuffer) override;
647   WebLayer* platformLayer() const override;
648   void stop() override;
649
650   // DrawingBuffer::Client implementation.
651   bool DrawingBufferClientIsBoundForDraw() override;
652   void DrawingBufferClientRestoreScissorTest() override;
653   void DrawingBufferClientRestoreMaskAndClearValues() override;
654   void DrawingBufferClientRestorePixelPackAlignment() override;
655   void DrawingBufferClientRestoreTexture2DBinding() override;
656   void DrawingBufferClientRestoreRenderbufferBinding() override;
657   void DrawingBufferClientRestoreFramebufferBinding() override;
658   void DrawingBufferClientRestorePixelUnpackBufferBinding() override;
659
660   void addSharedObject(WebGLSharedObject*);
661   void addContextObject(WebGLContextObject*);
662   void detachAndRemoveAllObjects();
663
664   virtual void destroyContext();
665   void markContextChanged(ContentChangeType);
666
667   void onErrorMessage(const char*, int32_t id);
668
669   void notifyCanvasContextChanged();
670
671 #if defined(TIZEN_TBM_SUPPORT) && defined(OS_TIZEN_TV_PRODUCT)
672   void prepareOESTextureProgram(WebGLProgram*, bool);
673   bool isEnabledOESEglImageExternal() {
674     return m_isEnabledOESEglImageExternal;
675   }
676 #endif
677
678   // Query if depth_stencil buffer is supported.
679   bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
680
681   // Helper to return the size in bytes of OpenGL data types
682   // like GL_FLOAT, GL_INT, etc.
683   unsigned sizeInBytes(GLenum type) const;
684
685   // Check if each enabled vertex attribute is bound to a buffer.
686   bool validateRenderingState(const char*);
687
688   bool validateWebGLObject(const char*, WebGLObject*);
689
690   // Adds a compressed texture format.
691   void addCompressedTextureFormat(GLenum);
692   void removeAllCompressedTextureFormats();
693
694   // Set UNPACK_ALIGNMENT to 1, all other parameters to 0.
695   virtual void resetUnpackParameters();
696   // Restore the client unpack parameters.
697   virtual void restoreUnpackParameters();
698
699   virtual void visitChildDOMWrappers(v8::Isolate*,
700                                      const v8::Persistent<v8::Object>&);
701
702   PassRefPtr<Image> drawImageIntoBuffer(PassRefPtr<Image>,
703                                         int width,
704                                         int height,
705                                         const char* functionName);
706
707   PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);
708
709   // Structure for rendering to a DrawingBuffer, instead of directly
710   // to the back-buffer of m_context.
711   RefPtr<DrawingBuffer> m_drawingBuffer;
712   DrawingBuffer* drawingBuffer() const;
713
714   RefPtr<WebGLContextGroup> m_contextGroup;
715
716   bool m_isHidden;
717   LostContextMode m_contextLostMode;
718   AutoRecoveryMethod m_autoRecoveryMethod;
719   // Dispatches a context lost event once it is determined that one is needed.
720   // This is used for synthetic, WEBGL_lose_context and real context losses. For
721   // real ones, it's likely that there's no JavaScript on the stack, but that
722   // might be dependent on how exactly the platform discovers that the context
723   // was lost. For better portability we always defer the dispatch of the event.
724   Timer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
725   bool m_restoreAllowed;
726   Timer<WebGLRenderingContextBase> m_restoreTimer;
727
728   bool m_markedCanvasDirty;
729   HeapHashSet<WeakMember<WebGLContextObject>> m_contextObjects;
730
731   // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and
732   // stored values for ELEMENT_ARRAY_BUFFER
733   TraceWrapperMember<WebGLBuffer> m_boundArrayBuffer;
734
735   Member<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
736   TraceWrapperMember<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;
737   void setBoundVertexArrayObject(WebGLVertexArrayObjectBase*);
738
739   enum VertexAttribValueType {
740     Float32ArrayType,
741     Int32ArrayType,
742     Uint32ArrayType,
743   };
744
745   Vector<VertexAttribValueType> m_vertexAttribType;
746   unsigned m_maxVertexAttribs;
747   void setVertexAttribType(GLuint index, VertexAttribValueType);
748
749   TraceWrapperMember<WebGLProgram> m_currentProgram;
750   TraceWrapperMember<WebGLFramebuffer> m_framebufferBinding;
751   TraceWrapperMember<WebGLRenderbuffer> m_renderbufferBinding;
752
753   HeapVector<TextureUnitState> m_textureUnits;
754   unsigned long m_activeTextureUnit;
755
756   Vector<GLenum> m_compressedTextureFormats;
757
758   // Fixed-size cache of reusable image buffers for video texImage2D calls.
759   class LRUImageBufferCache {
760    public:
761     LRUImageBufferCache(int capacity);
762     // The pointer returned is owned by the image buffer map.
763     ImageBuffer* imageBuffer(const IntSize&);
764
765    private:
766     void bubbleToFront(int idx);
767     std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
768     int m_capacity;
769   };
770   LRUImageBufferCache m_generatedImageCache;
771
772   GLint m_maxTextureSize;
773   GLint m_maxCubeMapTextureSize;
774   GLint m_max3DTextureSize;
775   GLint m_maxArrayTextureLayers;
776   GLint m_maxRenderbufferSize;
777   GLint m_maxViewportDims[2];
778   GLint m_maxTextureLevel;
779   GLint m_maxCubeMapTextureLevel;
780   GLint m_max3DTextureLevel;
781
782   GLint m_maxDrawBuffers;
783   GLint m_maxColorAttachments;
784   GLenum m_backDrawBuffer;
785   bool m_drawBuffersWebGLRequirementsChecked;
786   bool m_drawBuffersSupported;
787
788   GLenum m_readBufferOfDefaultFramebuffer;
789
790   GLint m_packAlignment;
791   GLint m_unpackAlignment;
792   bool m_unpackFlipY;
793   bool m_unpackPremultiplyAlpha;
794   GLenum m_unpackColorspaceConversion;
795
796   GLfloat m_clearColor[4];
797   bool m_scissorEnabled;
798   GLint m_scissorBox[4];
799   GLfloat m_clearDepth;
800   GLint m_clearStencil;
801   GLboolean m_colorMask[4];
802   GLboolean m_depthMask;
803
804   bool m_stencilEnabled;
805   GLuint m_stencilMask, m_stencilMaskBack;
806   GLint m_stencilFuncRef,
807       m_stencilFuncRefBack;  // Note that these are the user specified values,
808                              // not the internal clamped value.
809   GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
810
811   bool m_isDepthStencilSupported;
812
813   bool m_synthesizedErrorsToConsole;
814   int m_numGLErrorsToConsoleAllowed;
815
816   unsigned long m_onePlusMaxNonDefaultTextureUnit;
817
818   std::unique_ptr<Extensions3DUtil> m_extensionsUtil;
819
820   enum ExtensionFlags {
821     ApprovedExtension = 0x00,
822     // Extension that is behind the draft extensions runtime flag:
823     DraftExtension = 0x01,
824   };
825
826   class ExtensionTracker : public GarbageCollected<ExtensionTracker> {
827    public:
828     ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
829         : m_draft(flags & DraftExtension), m_prefixes(prefixes) {}
830
831     bool draft() const { return m_draft; }
832
833     const char* const* prefixes() const;
834     bool matchesNameWithPrefixes(const String&) const;
835
836     virtual WebGLExtension* getExtension(WebGLRenderingContextBase*) = 0;
837     virtual bool supported(WebGLRenderingContextBase*) const = 0;
838     virtual const char* extensionName() const = 0;
839     virtual void loseExtension(bool) = 0;
840
841     // This is only used for keeping the JS wrappers of extensions alive.
842     virtual WebGLExtension* getExtensionObjectIfAlreadyEnabled() = 0;
843
844     DEFINE_INLINE_VIRTUAL_TRACE() {}
845
846    private:
847     bool m_draft;
848     const char* const* m_prefixes;
849   };
850
851   template <typename T>
852   class TypedExtensionTracker final : public ExtensionTracker {
853    public:
854     static TypedExtensionTracker<T>* create(Member<T>& extensionField,
855                                             ExtensionFlags flags,
856                                             const char* const* prefixes) {
857       return new TypedExtensionTracker<T>(extensionField, flags, prefixes);
858     }
859
860     WebGLExtension* getExtension(WebGLRenderingContextBase* context) override {
861       if (!m_extension) {
862         m_extension = T::create(context);
863         m_extensionField = m_extension;
864       }
865
866       return m_extension;
867     }
868
869     bool supported(WebGLRenderingContextBase* context) const override {
870       return T::supported(context);
871     }
872
873     const char* extensionName() const override { return T::extensionName(); }
874
875     void loseExtension(bool force) override {
876       if (m_extension) {
877         m_extension->lose(force);
878         if (m_extension->isLost())
879           m_extension = nullptr;
880       }
881     }
882
883     WebGLExtension* getExtensionObjectIfAlreadyEnabled() override {
884       return m_extension;
885     }
886
887     DEFINE_INLINE_VIRTUAL_TRACE() {
888       visitor->trace(m_extension);
889       ExtensionTracker::trace(visitor);
890     }
891
892    private:
893     TypedExtensionTracker(Member<T>& extensionField,
894                           ExtensionFlags flags,
895                           const char* const* prefixes)
896         : ExtensionTracker(flags, prefixes), m_extensionField(extensionField) {}
897
898     GC_PLUGIN_IGNORE("http://crbug.com/519953")
899     Member<T>& m_extensionField;
900     // ExtensionTracker holds it's own reference to the extension to ensure
901     // that it is not deleted before this object's destructor is called
902     Member<T> m_extension;
903   };
904
905   bool m_extensionEnabled[WebGLExtensionNameCount];
906   HeapVector<TraceWrapperMember<ExtensionTracker>> m_extensions;
907
908   template <typename T>
909   void registerExtension(Member<T>& extensionPtr,
910                          ExtensionFlags flags = ApprovedExtension,
911                          const char* const* prefixes = nullptr) {
912     m_extensions.append(TraceWrapperMember<ExtensionTracker>(
913         this, TypedExtensionTracker<T>::create(extensionPtr, flags, prefixes)));
914   }
915
916   bool extensionSupportedAndAllowed(const ExtensionTracker*);
917
918   inline bool extensionEnabled(WebGLExtensionName name) {
919     return m_extensionEnabled[name];
920   }
921
922   // ScopedDrawingBufferBinder is used for
923   // ReadPixels/CopyTexImage2D/CopySubImage2D to read from a multisampled
924   // DrawingBuffer. In this situation, we need to blit to a single sampled
925   // buffer for reading, during which the bindings could be changed and need to
926   // be recovered.
927   class ScopedDrawingBufferBinder {
928     STACK_ALLOCATED();
929
930    public:
931     ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer,
932                               WebGLFramebuffer* framebufferBinding)
933         : m_drawingBuffer(drawingBuffer),
934           m_readFramebufferBinding(framebufferBinding) {
935       // Commit DrawingBuffer if needed (e.g., for multisampling)
936       if (!m_readFramebufferBinding && m_drawingBuffer)
937         m_drawingBuffer->resolveAndBindForReadAndDraw();
938     }
939
940     ~ScopedDrawingBufferBinder() {
941       // Restore DrawingBuffer if needed
942       if (!m_readFramebufferBinding && m_drawingBuffer)
943         m_drawingBuffer->restoreFramebufferBindings();
944     }
945
946    private:
947     DrawingBuffer* m_drawingBuffer;
948     Member<WebGLFramebuffer> m_readFramebufferBinding;
949   };
950
951   // Errors raised by synthesizeGLError() while the context is lost.
952   Vector<GLenum> m_lostContextErrors;
953   // Other errors raised by synthesizeGLError().
954   Vector<GLenum> m_syntheticErrors;
955
956   bool m_isWebGL2FormatsTypesAdded;
957   bool m_isWebGL2TexImageSourceFormatsTypesAdded;
958   bool m_isWebGL2InternalFormatsCopyTexImageAdded;
959   bool m_isOESTextureFloatFormatsTypesAdded;
960   bool m_isOESTextureHalfFloatFormatsTypesAdded;
961   bool m_isWebGLDepthTextureFormatsTypesAdded;
962   bool m_isEXTsRGBFormatsTypesAdded;
963
964 #if defined(TIZEN_TBM_SUPPORT) && defined(OS_TIZEN_TV_PRODUCT)
965   bool m_isOESTextureVideo;
966   bool m_isFirstFrameOES;
967   bool m_isEnabledOESEglImageExternal;
968   WebGLTexture* m_videoTexture;
969   WebGLTexture* m_videoTextureOES;
970   WebGLShader* m_videoFragmentShader;
971   WebGLShader* m_videoVertexShader;
972   WebGLProgram* m_videoProgram;
973   HTMLVideoElement* m_video;
974   unsigned m_videoImageId;
975 #endif
976
977   std::set<GLenum> m_supportedInternalFormats;
978   std::set<GLenum> m_supportedTexImageSourceInternalFormats;
979   std::set<GLenum> m_supportedInternalFormatsCopyTexImage;
980   std::set<GLenum> m_supportedFormats;
981   std::set<GLenum> m_supportedTexImageSourceFormats;
982   std::set<GLenum> m_supportedTypes;
983   std::set<GLenum> m_supportedTexImageSourceTypes;
984
985   // Helpers for getParameter and others
986   ScriptValue getBooleanParameter(ScriptState*, GLenum);
987   ScriptValue getBooleanArrayParameter(ScriptState*, GLenum);
988   ScriptValue getFloatParameter(ScriptState*, GLenum);
989   ScriptValue getIntParameter(ScriptState*, GLenum);
990   ScriptValue getInt64Parameter(ScriptState*, GLenum);
991   ScriptValue getUnsignedIntParameter(ScriptState*, GLenum);
992   ScriptValue getWebGLFloatArrayParameter(ScriptState*, GLenum);
993   ScriptValue getWebGLIntArrayParameter(ScriptState*, GLenum);
994
995   // Clear the backbuffer if it was composited since the last operation.
996   // clearMask is set to the bitfield of any clear that would happen anyway at
997   // this time and the function returns |CombinedClear| if that clear is now
998   // unnecessary.
999   enum HowToClear {
1000     // Skip clearing the backbuffer.
1001     Skipped,
1002     // Clear the backbuffer.
1003     JustClear,
1004     // Combine webgl.clear() API with the backbuffer clear, so webgl.clear()
1005     // doesn't have to call glClear() again.
1006     CombinedClear
1007   };
1008   HowToClear clearIfComposited(GLbitfield clearMask = 0);
1009
1010   // Convert texture internal format.
1011   GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
1012
1013   enum TexImageFunctionType {
1014     TexImage,
1015     TexSubImage,
1016     CopyTexImage,
1017     CompressedTexImage
1018   };
1019   enum TexImageFunctionID {
1020     TexImage2D,
1021     TexSubImage2D,
1022     TexImage3D,
1023     TexSubImage3D
1024   };
1025   enum TexImageByGPUType {
1026     TexImage2DByGPU,
1027     TexSubImage2DByGPU,
1028     TexSubImage3DByGPU
1029   };
1030   enum TexImageDimension { Tex2D, Tex3D };
1031   void texImage2DBase(GLenum target,
1032                       GLint level,
1033                       GLint internalformat,
1034                       GLsizei width,
1035                       GLsizei height,
1036                       GLint border,
1037                       GLenum format,
1038                       GLenum type,
1039                       const void* pixels);
1040   void texImageImpl(TexImageFunctionID,
1041                     GLenum target,
1042                     GLint level,
1043                     GLint internalformat,
1044                     GLint xoffset,
1045                     GLint yoffset,
1046                     GLint zoffset,
1047                     GLenum format,
1048                     GLenum type,
1049                     Image*,
1050                     WebGLImageConversion::ImageHtmlDomSource,
1051                     bool flipY,
1052                     bool premultiplyAlpha,
1053                     const IntRect&,
1054                     GLsizei depth,
1055                     GLint unpackImageHeight);
1056
1057   template <typename T>
1058   IntRect getTextureSourceSize(T* textureSource) {
1059     return IntRect(0, 0, textureSource->width(), textureSource->height());
1060   }
1061
1062   template <typename T>
1063   bool validateTexImageSubRectangle(const char* functionName,
1064                                     TexImageFunctionID functionID,
1065                                     T* image,
1066                                     const IntRect& subRect,
1067                                     GLsizei depth,
1068                                     GLint unpackImageHeight,
1069                                     bool* selectingSubRectangle) {
1070     DCHECK(functionName);
1071     DCHECK(selectingSubRectangle);
1072     DCHECK(image);
1073     *selectingSubRectangle = image &&
1074                              !(subRect.x() == 0 && subRect.y() == 0 &&
1075                                subRect.width() == image->width() &&
1076                                subRect.height() == image->height());
1077     // If the source image rect selects anything except the entire
1078     // contents of the image, assert that we're running WebGL 2.0 or
1079     // higher, since this should never happen for WebGL 1.0 (even though
1080     // the code could support it). If the image is null, that will be
1081     // signaled as an error later.
1082     DCHECK(!*selectingSubRectangle || isWebGL2OrHigher())
1083         << "subRect = (" << subRect.width() << " x " << subRect.height()
1084         << ") @ (" << subRect.x() << ", " << subRect.y() << "), image = ("
1085         << (image ? image->width() : -1) << " x "
1086         << (image ? image->height() : -1) << ")";
1087
1088     if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() ||
1089         subRect.maxY() > image->height() || subRect.width() < 0 ||
1090         subRect.height() < 0) {
1091       synthesizeGLError(GL_INVALID_OPERATION, functionName,
1092                         "source sub-rectangle specified via pixel unpack "
1093                         "parameters is invalid");
1094       return false;
1095     }
1096
1097     if (functionID == TexImage3D || functionID == TexSubImage3D) {
1098       DCHECK_GE(unpackImageHeight, 0);
1099
1100       // Verify that the image data can cover the required depth.
1101       WTF::CheckedNumeric<GLint> maxDepthSupported = 1;
1102       if (unpackImageHeight) {
1103         maxDepthSupported = subRect.height();
1104         maxDepthSupported /= unpackImageHeight;
1105       }
1106
1107       if (!maxDepthSupported.IsValid() ||
1108           maxDepthSupported.ValueOrDie() < depth) {
1109         synthesizeGLError(GL_INVALID_OPERATION, functionName,
1110                           "Not enough data supplied to upload to a 3D texture "
1111                           "with depth > 1");
1112         return false;
1113       }
1114     } else {
1115       DCHECK_EQ(depth, 1);
1116       DCHECK_EQ(unpackImageHeight, 0);
1117     }
1118     return true;
1119   }
1120
1121   // Copy from the source directly to the texture via the gpu, without a
1122   // read-back to system memory.  Source could be canvas or imageBitmap.
1123   void texImageByGPU(TexImageByGPUType,
1124                      WebGLTexture*,
1125                      GLenum target,
1126                      GLint level,
1127                      GLint internalformat,
1128                      GLenum type,
1129                      GLint xoffset,
1130                      GLint yoffset,
1131                      GLint zoffset,
1132                      CanvasImageSource*,
1133                      const IntRect& sourceSubRectangle);
1134   virtual bool canUseTexImageByGPU(TexImageFunctionID,
1135                                    GLint internalformat,
1136                                    GLenum type);
1137
1138   virtual WebGLImageConversion::PixelStoreParams getPackPixelStoreParams();
1139   virtual WebGLImageConversion::PixelStoreParams getUnpackPixelStoreParams(
1140       TexImageDimension);
1141
1142   // Helper function for copyTex{Sub}Image, check whether the internalformat
1143   // and the color buffer format of the current bound framebuffer combination
1144   // is valid.
1145   bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat,
1146                                                       GLenum colorBufferFormat);
1147
1148   // Helper function to verify limits on the length of uniform and attribute
1149   // locations.
1150   virtual unsigned getMaxWebGLLocationLength() const { return 256; }
1151   bool validateLocationLength(const char* functionName, const String&);
1152
1153   // Helper function to check if size is non-negative.
1154   // Generate GL error and return false for negative inputs; otherwise, return
1155   // true.
1156   bool validateSize(const char* functionName, GLint x, GLint y, GLint z = 0);
1157
1158   // Helper function to check if all characters in the string belong to the
1159   // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
1160   bool validateString(const char* functionName, const String&);
1161
1162   // Helper function to check if all characters in the shader source belong to
1163   // the ASCII subset as defined in GLSL ES 1.0 spec section 3.1 Character Set
1164   // for WebGL 1.0 and in GLSL ES 3.00 spec section 3.1 Character Set for WebGL
1165   // 2.0.
1166   bool validateShaderSource(const String&);
1167
1168   // Helper function to check texture binding target and texture bound to the
1169   // target.  Generate GL errors and return 0 if target is invalid or texture
1170   // bound is null.  Otherwise, return the texture bound to the target.
1171   WebGLTexture* validateTextureBinding(const char* functionName, GLenum target);
1172
1173   // Wrapper function for validateTexture2D(3D)Binding, used in texImageHelper
1174   // functions.
1175   virtual WebGLTexture* validateTexImageBinding(const char*,
1176                                                 TexImageFunctionID,
1177                                                 GLenum);
1178
1179   // Helper function to check texture 2D target and texture bound to the target.
1180   // Generate GL errors and return 0 if target is invalid or texture bound is
1181   // null.  Otherwise, return the texture bound to the target.
1182   WebGLTexture* validateTexture2DBinding(const char* functionName,
1183                                          GLenum target);
1184
1185   void addExtensionSupportedFormatsTypes();
1186
1187   // Helper function to check input internalformat/format/type for functions
1188   // Tex{Sub}Image taking TexImageSource source data.  Generates GL error and
1189   // returns false if parameters are invalid.
1190   bool validateTexImageSourceFormatAndType(const char* functionName,
1191                                            TexImageFunctionType,
1192                                            GLenum internalformat,
1193                                            GLenum format,
1194                                            GLenum type);
1195
1196   // Helper function to check input internalformat/format/type for functions
1197   // Tex{Sub}Image.  Generates GL error and returns false if parameters are
1198   // invalid.
1199   bool validateTexFuncFormatAndType(const char* functionName,
1200                                     TexImageFunctionType,
1201                                     GLenum internalformat,
1202                                     GLenum format,
1203                                     GLenum type,
1204                                     GLint level);
1205
1206   // Helper function to check readbuffer validity for copyTex{Sub}Image.
1207   // If yes, obtains the bound read framebuffer, returns true.
1208   // If not, generates a GL error, returns false.
1209   bool validateReadBufferAndGetInfo(const char* functionName,
1210                                     WebGLFramebuffer*& readFramebufferBinding);
1211
1212   // Helper function to check format/type and ArrayBuffer view type for
1213   // readPixels.
1214   // Generates INVALID_ENUM and returns false if parameters are invalid.
1215   // Generates INVALID_OPERATION if ArrayBuffer view type is incompatible with
1216   // type.
1217   virtual bool validateReadPixelsFormatAndType(GLenum format,
1218                                                GLenum type,
1219                                                DOMArrayBufferView*);
1220
1221   // Helper function to check parameters of readPixels. Returns true if all
1222   // parameters are valid. Otherwise, generates appropriate error and returns
1223   // false.
1224   bool validateReadPixelsFuncParameters(GLsizei width,
1225                                         GLsizei height,
1226                                         GLenum format,
1227                                         GLenum type,
1228                                         DOMArrayBufferView*,
1229                                         long long bufferSize);
1230
1231   virtual GLint getMaxTextureLevelForTarget(GLenum target);
1232
1233   // Helper function to check input level for functions {copy}Tex{Sub}Image.
1234   // Generates GL error and returns false if level is invalid.
1235   bool validateTexFuncLevel(const char* functionName,
1236                             GLenum target,
1237                             GLint level);
1238
1239   // Helper function to check if a 64-bit value is non-negative and can fit into
1240   // a 32-bit integer.  Generates GL error and returns false if not.
1241   bool validateValueFitNonNegInt32(const char* functionName,
1242                                    const char* paramName,
1243                                    long long value);
1244
1245   enum TexFuncValidationSourceType {
1246     SourceArrayBufferView,
1247     SourceImageData,
1248     SourceHTMLImageElement,
1249     SourceHTMLCanvasElement,
1250     SourceHTMLVideoElement,
1251     SourceImageBitmap,
1252     SourceUnpackBuffer,
1253   };
1254
1255   // Helper function for tex{Sub}Image{2|3}D to check if the input
1256   // format/type/level/target/width/height/depth/border/xoffset/yoffset/zoffset
1257   // are valid.  Otherwise, it would return quickly without doing other work.
1258   bool validateTexFunc(const char* functionName,
1259                        TexImageFunctionType,
1260                        TexFuncValidationSourceType,
1261                        GLenum target,
1262                        GLint level,
1263                        GLenum internalformat,
1264                        GLsizei width,
1265                        GLsizei height,
1266                        GLsizei depth,
1267                        GLint border,
1268                        GLenum format,
1269                        GLenum type,
1270                        GLint xoffset,
1271                        GLint yoffset,
1272                        GLint zoffset);
1273
1274   // Helper function to check input width and height for functions {copy,
1275   // compressed}Tex{Sub}Image.  Generates GL error and returns false if width or
1276   // height is invalid.
1277   bool validateTexFuncDimensions(const char* functionName,
1278                                  TexImageFunctionType,
1279                                  GLenum target,
1280                                  GLint level,
1281                                  GLsizei width,
1282                                  GLsizei height,
1283                                  GLsizei depth);
1284
1285   // Helper function to check input parameters for functions
1286   // {copy}Tex{Sub}Image.  Generates GL error and returns false if parameters
1287   // are invalid.
1288   bool validateTexFuncParameters(const char* functionName,
1289                                  TexImageFunctionType,
1290                                  TexFuncValidationSourceType,
1291                                  GLenum target,
1292                                  GLint level,
1293                                  GLenum internalformat,
1294                                  GLsizei width,
1295                                  GLsizei height,
1296                                  GLsizei depth,
1297                                  GLint border,
1298                                  GLenum format,
1299                                  GLenum type);
1300
1301   enum NullDisposition { NullAllowed, NullNotAllowed, NullNotReachable };
1302
1303   // Helper function to validate that the given ArrayBufferView
1304   // is of the correct type and contains enough data for the texImage call.
1305   // Generates GL error and returns false if parameters are invalid.
1306   bool validateTexFuncData(const char* functionName,
1307                            TexImageDimension,
1308                            GLint level,
1309                            GLsizei width,
1310                            GLsizei height,
1311                            GLsizei depth,
1312                            GLenum format,
1313                            GLenum type,
1314                            DOMArrayBufferView* pixels,
1315                            NullDisposition,
1316                            GLuint srcOffset);
1317
1318   // Helper function to validate a given texture format is settable as in
1319   // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
1320   // copyTexSubImage2D.
1321   // Generates GL error and returns false if the format is not settable.
1322   bool validateSettableTexFormat(const char* functionName, GLenum format);
1323
1324   // Helper function to validate format for CopyTexImage.
1325   bool validateCopyTexFormat(const char* functionName, GLenum format);
1326
1327   // Helper function for validating compressed texture formats.
1328   bool validateCompressedTexFormat(const char* functionName, GLenum format);
1329
1330   // Helper function to validate if front/back stencilMask and stencilFunc
1331   // settings are the same.
1332   bool validateStencilSettings(const char* functionName);
1333
1334   // Helper function to validate stencil or depth func.
1335   bool validateStencilOrDepthFunc(const char* functionName, GLenum);
1336
1337   // Helper function for texParameterf and texParameteri.
1338   void texParameter(GLenum target,
1339                     GLenum pname,
1340                     GLfloat paramf,
1341                     GLint parami,
1342                     bool isFloat);
1343
1344   // Helper function to print GL errors to console.
1345   void printGLErrorToConsole(const String&);
1346
1347   // Helper function to print warnings to console. Currently
1348   // used only to warn about use of obsolete functions.
1349   void printWarningToConsole(const String&);
1350
1351   // Helper function to validate the target for checkFramebufferStatus and
1352   // validateFramebufferFuncParameters.
1353   virtual bool validateFramebufferTarget(GLenum target);
1354
1355   // Get the framebuffer bound to given target
1356   virtual WebGLFramebuffer* getFramebufferBinding(GLenum target);
1357
1358   virtual WebGLFramebuffer* getReadFramebufferBinding();
1359
1360   // Helper function to validate input parameters for framebuffer functions.
1361   // Generate GL error if parameters are illegal.
1362   bool validateFramebufferFuncParameters(const char* functionName,
1363                                          GLenum target,
1364                                          GLenum attachment);
1365
1366   // Helper function to validate blend equation mode.
1367   bool validateBlendEquation(const char* functionName, GLenum);
1368
1369   // Helper function to validate blend func factors.
1370   bool validateBlendFuncFactors(const char* functionName,
1371                                 GLenum src,
1372                                 GLenum dst);
1373
1374   // Helper function to validate a GL capability.
1375   virtual bool validateCapability(const char* functionName, GLenum);
1376
1377   // Helper function to validate input parameters for uniform functions.
1378   bool validateUniformParameters(const char* functionName,
1379                                  const WebGLUniformLocation*,
1380                                  DOMFloat32Array*,
1381                                  GLsizei mod);
1382   bool validateUniformParameters(const char* functionName,
1383                                  const WebGLUniformLocation*,
1384                                  DOMInt32Array*,
1385                                  GLsizei mod);
1386   bool validateUniformParameters(const char* functionName,
1387                                  const WebGLUniformLocation*,
1388                                  void*,
1389                                  GLsizei,
1390                                  GLsizei mod);
1391   bool validateUniformMatrixParameters(const char* functionName,
1392                                        const WebGLUniformLocation*,
1393                                        GLboolean transpose,
1394                                        DOMFloat32Array*,
1395                                        GLsizei mod);
1396   bool validateUniformMatrixParameters(const char* functionName,
1397                                        const WebGLUniformLocation*,
1398                                        GLboolean transpose,
1399                                        void*,
1400                                        GLsizei,
1401                                        GLsizei mod);
1402
1403   template <typename WTFTypedArray>
1404   bool validateUniformParameters(
1405       const char* functionName,
1406       const WebGLUniformLocation* location,
1407       const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
1408       GLsizei requiredMinSize) {
1409     if (!v.dataMaybeOnStack()) {
1410       synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
1411       return false;
1412     }
1413     return validateUniformMatrixParameters(functionName, location, false,
1414                                            v.dataMaybeOnStack(), v.length(),
1415                                            requiredMinSize);
1416   }
1417
1418   // Helper function to validate the target for bufferData and
1419   // getBufferParameter.
1420   virtual bool validateBufferTarget(const char* functionName, GLenum target);
1421
1422   // Helper function to validate the target for bufferData.
1423   // Return the current bound buffer to target, or 0 if the target is invalid.
1424   virtual WebGLBuffer* validateBufferDataTarget(const char* functionName,
1425                                                 GLenum target);
1426   // Helper function to validate the usage for bufferData.
1427   virtual bool validateBufferDataUsage(const char* functionName, GLenum usage);
1428
1429   virtual bool validateAndUpdateBufferBindTarget(const char* functionName,
1430                                                  GLenum target,
1431                                                  WebGLBuffer*);
1432
1433   virtual void removeBoundBuffer(WebGLBuffer*);
1434
1435   // Helper function for tex{Sub}Image2D to make sure image is ready and
1436   // wouldn't taint Origin.
1437   bool validateHTMLImageElement(const char* functionName,
1438                                 HTMLImageElement*,
1439                                 ExceptionState&);
1440
1441   // Helper function for tex{Sub}Image2D to make sure canvas is ready and
1442   // wouldn't taint Origin.
1443   bool validateHTMLCanvasElement(const char* functionName,
1444                                  HTMLCanvasElement*,
1445                                  ExceptionState&);
1446
1447   // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't
1448   // taint Origin.
1449   bool validateHTMLVideoElement(const char* functionName,
1450                                 HTMLVideoElement*,
1451                                 ExceptionState&);
1452
1453   // Helper function for tex{Sub}Image2D to make sure imagebitmap is ready and
1454   // wouldn't taint Origin.
1455   bool validateImageBitmap(const char* functionName,
1456                            ImageBitmap*,
1457                            ExceptionState&);
1458
1459   // Helper function to validate drawArrays(Instanced) calls
1460   bool validateDrawArrays(const char* functionName);
1461
1462   // Helper function to validate drawElements(Instanced) calls
1463   bool validateDrawElements(const char* functionName,
1464                             GLenum type,
1465                             long long offset);
1466
1467   // Helper functions to bufferData() and bufferSubData().
1468   void bufferDataImpl(GLenum target,
1469                       long long size,
1470                       const void* data,
1471                       GLenum usage);
1472   void bufferSubDataImpl(GLenum target,
1473                          long long offset,
1474                          GLsizeiptr,
1475                          const void* data);
1476
1477   // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
1478   // Return false if caller should return without further processing.
1479   bool deleteObject(WebGLObject*);
1480
1481   // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
1482   // If the object has already been deleted, set deleted to true upon return.
1483   // Return false if caller should return without further processing.
1484   bool checkObjectToBeBound(const char* functionName,
1485                             WebGLObject*,
1486                             bool& deleted);
1487
1488   void dispatchContextLostEvent(TimerBase*);
1489   // Helper for restoration after context lost.
1490   void maybeRestoreContext(TimerBase*);
1491
1492   enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };
1493
1494   // Reports an error to glGetError, sends a message to the JavaScript
1495   // console.
1496   void synthesizeGLError(GLenum,
1497                          const char* functionName,
1498                          const char* description,
1499                          ConsoleDisplayPreference = DisplayInConsole);
1500   void emitGLWarning(const char* function, const char* reason);
1501
1502   String ensureNotNull(const String&) const;
1503
1504   // Enable or disable stencil test based on user setting and
1505   // whether the current FBO has a stencil buffer.
1506   void applyStencilTest();
1507
1508   // Helper for enabling or disabling a capability.
1509   void enableOrDisable(GLenum capability, bool enable);
1510
1511   // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
1512   IntSize clampedCanvasSize() const;
1513
1514   // First time called, if EXT_draw_buffers is supported, query the value;
1515   // otherwise return 0.  Later, return the cached value.
1516   GLint maxDrawBuffers();
1517   GLint maxColorAttachments();
1518
1519   void setBackDrawBuffer(GLenum);
1520   void setFramebuffer(GLenum, WebGLFramebuffer*);
1521
1522   virtual void restoreCurrentFramebuffer();
1523   void restoreCurrentTexture2D();
1524
1525   void findNewMaxNonDefaultTextureUnit();
1526
1527   virtual void renderbufferStorageImpl(GLenum target,
1528                                        GLsizei samples,
1529                                        GLenum internalformat,
1530                                        GLsizei width,
1531                                        GLsizei height,
1532                                        const char* functionName);
1533
1534   friend class WebGLStateRestorer;
1535   friend class WebGLRenderingContextEvictionManager;
1536
1537   static void activateContext(WebGLRenderingContextBase*);
1538   static void deactivateContext(WebGLRenderingContextBase*);
1539   static void addToEvictedList(WebGLRenderingContextBase*);
1540   static void removeFromEvictedList(WebGLRenderingContextBase*);
1541   static void willDestroyContext(WebGLRenderingContextBase*);
1542   static void forciblyLoseOldestContext(const String& reason);
1543   // Return the least recently used context's position in the active context
1544   // vector.  If the vector is empty, return the maximum allowed active context
1545   // number.
1546   static WebGLRenderingContextBase* oldestContext();
1547   static WebGLRenderingContextBase* oldestEvictedContext();
1548
1549   ImageBitmap* transferToImageBitmapBase(ScriptState*);
1550
1551   // Helper functions for tex(Sub)Image2D && texSubImage3D
1552   void texImageHelperDOMArrayBufferView(TexImageFunctionID,
1553                                         GLenum,
1554                                         GLint,
1555                                         GLint,
1556                                         GLsizei,
1557                                         GLsizei,
1558                                         GLsizei,
1559                                         GLint,
1560                                         GLenum,
1561                                         GLenum,
1562                                         GLint,
1563                                         GLint,
1564                                         GLint,
1565                                         DOMArrayBufferView*,
1566                                         NullDisposition,
1567                                         GLuint srcOffset);
1568   void texImageHelperImageData(TexImageFunctionID,
1569                                GLenum,
1570                                GLint,
1571                                GLint,
1572                                GLint,
1573                                GLenum,
1574                                GLenum,
1575                                GLsizei,
1576                                GLint,
1577                                GLint,
1578                                GLint,
1579                                ImageData*,
1580                                const IntRect&,
1581                                GLint);
1582   void texImageHelperHTMLImageElement(TexImageFunctionID,
1583                                       GLenum,
1584                                       GLint,
1585                                       GLint,
1586                                       GLenum,
1587                                       GLenum,
1588                                       GLint,
1589                                       GLint,
1590                                       GLint,
1591                                       HTMLImageElement*,
1592                                       const IntRect&,
1593                                       GLsizei,
1594                                       GLint,
1595                                       ExceptionState&);
1596   void texImageHelperHTMLCanvasElement(TexImageFunctionID,
1597                                        GLenum,
1598                                        GLint,
1599                                        GLint,
1600                                        GLenum,
1601                                        GLenum,
1602                                        GLint,
1603                                        GLint,
1604                                        GLint,
1605                                        HTMLCanvasElement*,
1606                                        const IntRect&,
1607                                        GLsizei,
1608                                        GLint,
1609                                        ExceptionState&);
1610   void texImageHelperHTMLVideoElement(TexImageFunctionID,
1611                                       GLenum,
1612                                       GLint,
1613                                       GLint,
1614                                       GLenum,
1615                                       GLenum,
1616                                       GLint,
1617                                       GLint,
1618                                       GLint,
1619                                       HTMLVideoElement*,
1620                                       const IntRect&,
1621                                       GLsizei,
1622                                       GLint,
1623                                       ExceptionState&);
1624   void texImageHelperImageBitmap(TexImageFunctionID,
1625                                  GLenum,
1626                                  GLint,
1627                                  GLint,
1628                                  GLenum,
1629                                  GLenum,
1630                                  GLint,
1631                                  GLint,
1632                                  GLint,
1633                                  ImageBitmap*,
1634                                  ExceptionState&);
1635   static const char* getTexImageFunctionName(TexImageFunctionID);
1636   IntRect sentinelEmptyRect();
1637   IntRect safeGetImageSize(Image*);
1638   IntRect getImageDataSize(ImageData*);
1639
1640   // Helper implementing readPixels for WebGL 1.0 and 2.0.
1641   void readPixelsHelper(GLint x,
1642                         GLint y,
1643                         GLsizei width,
1644                         GLsizei height,
1645                         GLenum format,
1646                         GLenum type,
1647                         DOMArrayBufferView* pixels,
1648                         GLuint offset);
1649
1650  private:
1651   WebGLRenderingContextBase(HTMLCanvasElement*,
1652                             OffscreenCanvas*,
1653                             std::unique_ptr<WebGraphicsContext3DProvider>,
1654                             const CanvasContextCreationAttributes&,
1655                             unsigned);
1656   static std::unique_ptr<WebGraphicsContext3DProvider>
1657   createContextProviderInternal(HTMLCanvasElement*,
1658                                 ScriptState*,
1659                                 const CanvasContextCreationAttributes&,
1660                                 unsigned);
1661   void texImageCanvasByGPU(HTMLCanvasElement*,
1662                            GLuint,
1663                            GLenum,
1664                            GLenum,
1665                            GLint,
1666                            GLint,
1667                            GLint,
1668                            const IntRect& sourceSubRectangle);
1669   void texImageBitmapByGPU(ImageBitmap*, GLuint, GLenum, GLenum, GLint, bool);
1670
1671   const unsigned m_version;
1672
1673   bool isPaintable() const final { return drawingBuffer(); }
1674 };
1675
1676 DEFINE_TYPE_CASTS(WebGLRenderingContextBase,
1677                   CanvasRenderingContext,
1678                   context,
1679                   context->is3d(),
1680                   context.is3d());
1681
1682 }  // namespace blink
1683
1684 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
1685     blink::WebGLRenderingContextBase::TextureUnitState);
1686
1687 #endif  // WebGLRenderingContextBase_h