Add 'webglcontextchanged' WebGLContextEvent
[WebKit-https.git] / Source / WebCore / html / canvas / WebGLRenderingContextBase.h
1 /*
2  * Copyright (C) 2015-2017 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 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 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 #pragma once
27
28 #if ENABLE(WEBGL)
29
30 #include "ActiveDOMObject.h"
31 #include "ActivityStateChangeObserver.h"
32 #include "CanvasRenderingContext.h"
33 #include "GraphicsContext3D.h"
34 #include "ImageBuffer.h"
35 #include "Timer.h"
36 #include "WebGLAny.h"
37 #include "WebGLBuffer.h"
38 #include "WebGLContextAttributes.h"
39 #include "WebGLFramebuffer.h"
40 #include "WebGLProgram.h"
41 #include "WebGLRenderbuffer.h"
42 #include "WebGLStateTracker.h"
43 #include "WebGLTexture.h"
44 #include "WebGLVertexArrayObjectOES.h"
45 #include <memory>
46
47 #if ENABLE(WEBGL2)
48 #include "WebGLVertexArrayObject.h"
49 #endif
50
51 namespace WebCore {
52
53 class ANGLEInstancedArrays;
54 class EXTBlendMinMax;
55 class EXTTextureFilterAnisotropic;
56 class EXTShaderTextureLOD;
57 class EXTsRGB;
58 class EXTFragDepth;
59 class HTMLImageElement;
60 class HTMLVideoElement;
61 class ImageData;
62 class IntSize;
63 class OESStandardDerivatives;
64 class OESTextureFloat;
65 class OESTextureFloatLinear;
66 class OESTextureHalfFloat;
67 class OESTextureHalfFloatLinear;
68 class OESVertexArrayObject;
69 class OESElementIndexUint;
70 class WebGLActiveInfo;
71 class WebGLContextGroup;
72 class WebGLContextObject;
73 class WebGLCompressedTextureATC;
74 class WebGLCompressedTexturePVRTC;
75 class WebGLCompressedTextureS3TC;
76 class WebGLDebugRendererInfo;
77 class WebGLDebugShaders;
78 class WebGLDepthTexture;
79 class WebGLDrawBuffers;
80 class WebGLExtension;
81 class WebGLLoseContext;
82 class WebGLObject;
83 class WebGLShader;
84 class WebGLSharedObject;
85 class WebGLShaderPrecisionFormat;
86 class WebGLUniformLocation;
87
88 inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
89 {
90     ASSERT(clippedStart && clippedRange);
91     if (start < 0) {
92         range += start;
93         start = 0;
94     }
95     GC3Dint end = start + range;
96     if (end > sourceRange)
97         range -= end - sourceRange;
98     *clippedStart = start;
99     *clippedRange = range;
100 }
101
102 // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
103 inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
104     GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
105     GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
106 {
107     ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
108     clip1D(x, width, sourceWidth, clippedX, clippedWidth);
109     clip1D(y, height, sourceHeight, clippedY, clippedHeight);
110     return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
111 }
112
113 class WebGLRenderingContextBase : public CanvasRenderingContext, private ActivityStateChangeObserver, public ActiveDOMObject {
114 public:
115     static std::unique_ptr<WebGLRenderingContextBase> create(HTMLCanvasElement&, WebGLContextAttributes&, const String&);
116     virtual ~WebGLRenderingContextBase();
117
118 #if PLATFORM(WIN)
119     // FIXME: Implement accelerated 3d canvas on Windows.
120     bool isAccelerated() const override { return false; }
121 #else
122     bool isAccelerated() const override { return true; }
123 #endif
124
125     int drawingBufferWidth() const;
126     int drawingBufferHeight() const;
127
128     void activeTexture(GC3Denum texture);
129     void attachShader(WebGLProgram*, WebGLShader*);
130     void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name);
131     void bindBuffer(GC3Denum target, WebGLBuffer*);
132     void bindFramebuffer(GC3Denum target, WebGLFramebuffer*);
133     void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*);
134     void bindTexture(GC3Denum target, WebGLTexture*);
135     void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
136     void blendEquation(GC3Denum mode);
137     void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
138     void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
139     void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
140
141     using BufferDataSource = WTF::Variant<RefPtr<ArrayBuffer>, RefPtr<ArrayBufferView>>;
142     void bufferData(GC3Denum target, long long size, GC3Denum usage);
143     void bufferData(GC3Denum target, std::optional<BufferDataSource>&&, GC3Denum usage);
144     void bufferSubData(GC3Denum target, long long offset, std::optional<BufferDataSource>&&);
145
146     GC3Denum checkFramebufferStatus(GC3Denum target);
147     virtual void clear(GC3Dbitfield mask) = 0;
148     void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
149     void clearDepth(GC3Dfloat);
150     void clearStencil(GC3Dint);
151     void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
152     void compileShader(WebGLShader*);
153
154     void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, ArrayBufferView& data);
155     void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& data);
156
157     void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
158     void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
159
160     RefPtr<WebGLBuffer> createBuffer();
161     RefPtr<WebGLFramebuffer> createFramebuffer();
162     RefPtr<WebGLProgram> createProgram();
163     RefPtr<WebGLRenderbuffer> createRenderbuffer();
164     RefPtr<WebGLShader> createShader(GC3Denum type);
165     RefPtr<WebGLTexture> createTexture();
166
167     void cullFace(GC3Denum mode);
168
169     void deleteBuffer(WebGLBuffer*);
170     void deleteFramebuffer(WebGLFramebuffer*);
171     void deleteProgram(WebGLProgram*);
172     void deleteRenderbuffer(WebGLRenderbuffer*);
173     void deleteShader(WebGLShader*);
174     void deleteTexture(WebGLTexture*);
175
176     void depthFunc(GC3Denum);
177     void depthMask(GC3Dboolean);
178     void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
179     void detachShader(WebGLProgram*, WebGLShader*);
180     void disable(GC3Denum cap);
181     void disableVertexAttribArray(GC3Duint index);
182     void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
183     void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
184
185     void enable(GC3Denum cap);
186     void enableVertexAttribArray(GC3Duint index);
187     void finish();
188     void flush();
189     void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*);
190     void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level);
191     void frontFace(GC3Denum mode);
192     void generateMipmap(GC3Denum target);
193
194     RefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index);
195     RefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index);
196     std::optional<Vector<RefPtr<WebGLShader>>> getAttachedShaders(WebGLProgram*);
197     GC3Dint getAttribLocation(WebGLProgram*, const String& name);
198     WebGLAny getBufferParameter(GC3Denum target, GC3Denum pname);
199     std::optional<WebGLContextAttributes> getContextAttributes();
200     GC3Denum getError();
201     virtual WebGLExtension* getExtension(const String& name) = 0;
202     virtual WebGLAny getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname) = 0;
203     virtual WebGLAny getParameter(GC3Denum pname) = 0;
204     WebGLAny getProgramParameter(WebGLProgram*, GC3Denum pname);
205     String getProgramInfoLog(WebGLProgram*);
206     WebGLAny getRenderbufferParameter(GC3Denum target, GC3Denum pname);
207     WebGLAny getShaderParameter(WebGLShader*, GC3Denum pname);
208     String getShaderInfoLog(WebGLShader*);
209     RefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType);
210     String getShaderSource(WebGLShader*);
211     virtual std::optional<Vector<String>> getSupportedExtensions() = 0;
212     WebGLAny getTexParameter(GC3Denum target, GC3Denum pname);
213     WebGLAny getUniform(WebGLProgram*, const WebGLUniformLocation*);
214     RefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
215     WebGLAny getVertexAttrib(GC3Duint index, GC3Denum pname);
216     long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
217
218     virtual void hint(GC3Denum target, GC3Denum mode) = 0;
219     GC3Dboolean isBuffer(WebGLBuffer*);
220     bool isContextLost() const;
221     GC3Dboolean isEnabled(GC3Denum cap);
222     GC3Dboolean isFramebuffer(WebGLFramebuffer*);
223     GC3Dboolean isProgram(WebGLProgram*);
224     GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
225     GC3Dboolean isShader(WebGLShader*);
226     GC3Dboolean isTexture(WebGLTexture*);
227
228     void lineWidth(GC3Dfloat);
229     void linkProgram(WebGLProgram*);
230     void pixelStorei(GC3Denum pname, GC3Dint param);
231     void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
232     void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView& pixels);
233     void releaseShaderCompiler();
234     virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) = 0;
235     void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
236     void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
237     void shaderSource(WebGLShader*, const String&);
238     void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
239     void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
240     void stencilMask(GC3Duint);
241     void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
242     void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
243     void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
244
245     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&);
246
247     using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
248     ExceptionOr<void> texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, std::optional<TexImageSource>);
249
250     void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
251     void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
252
253     void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&);
254     ExceptionOr<void> texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, std::optional<TexImageSource>&&);
255
256     template <class TypedArray, class DataType>
257     class TypedList {
258     public:
259         using VariantType = Variant<RefPtr<TypedArray>, Vector<DataType>>;
260
261         TypedList(VariantType&& variant)
262             : m_variant(WTFMove(variant))
263         {
264         }
265
266         DataType* data() const
267         {
268             return WTF::switchOn(m_variant,
269                 [] (const RefPtr<TypedArray>& typedArray) -> DataType* { return typedArray->data(); },
270                 [] (const Vector<DataType>& vector) -> DataType* { return const_cast<Vector<DataType>&>(vector).data(); }
271             );
272         }
273
274         GC3Dsizei length() const
275         {
276             return WTF::switchOn(m_variant,
277                 [] (const RefPtr<TypedArray>& typedArray) -> GC3Dsizei { return typedArray->length(); },
278                 [] (const Vector<DataType>& vector) -> GC3Dsizei { return vector.size(); }
279             );
280         }
281
282     private:
283         VariantType m_variant;
284     };
285
286     using Float32List = TypedList<Float32Array, float>;
287     using Int32List = TypedList<Int32Array, int>;
288
289     void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
290     void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y);
291     void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
292     void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
293
294     void uniform1i(const WebGLUniformLocation*, GC3Dint x);
295     void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y);
296     void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z);
297     void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
298
299     void uniform1fv(const WebGLUniformLocation*, Float32List&&);
300     void uniform2fv(const WebGLUniformLocation*, Float32List&&);
301     void uniform3fv(const WebGLUniformLocation*, Float32List&&);
302     void uniform4fv(const WebGLUniformLocation*, Float32List&&);
303
304     void uniform1iv(const WebGLUniformLocation*, Int32List&&);
305     void uniform2iv(const WebGLUniformLocation*, Int32List&&);
306     void uniform3iv(const WebGLUniformLocation*, Int32List&&);
307     void uniform4iv(const WebGLUniformLocation*, Int32List&&);
308
309     void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
310     void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
311     void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
312
313     void useProgram(WebGLProgram*);
314     void validateProgram(WebGLProgram*);
315
316     void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
317     void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
318     void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
319     void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
320
321     void vertexAttrib1fv(GC3Duint index, Float32List&&);
322     void vertexAttrib2fv(GC3Duint index, Float32List&&);
323     void vertexAttrib3fv(GC3Duint index, Float32List&&);
324     void vertexAttrib4fv(GC3Duint index, Float32List&&);
325
326     void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
327         GC3Dsizei stride, long long offset);
328
329     void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
330
331     // WEBKIT_lose_context support
332     enum LostContextMode {
333         // Lost context occurred at the graphics system level.
334         RealLostContext,
335
336         // Lost context provoked by WEBKIT_lose_context.
337         SyntheticLostContext
338     };
339     void forceLostContext(LostContextMode);
340     void recycleContext();
341     void forceRestoreContext();
342     void loseContextImpl(LostContextMode);
343     void dispatchContextChangedEvent();
344     WEBCORE_EXPORT void simulateContextChanged();
345
346     GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
347     WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
348     PlatformLayer* platformLayer() const override;
349
350     void reshape(int width, int height);
351
352     void markLayerComposited();
353     void paintRenderingResultsToCanvas() override;
354     RefPtr<ImageData> paintRenderingResultsToImageData();
355
356     void removeSharedObject(WebGLSharedObject&);
357     void removeContextObject(WebGLContextObject&);
358     
359     unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
360
361     // Instanced Array helper functions.
362     void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
363     void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
364     void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
365
366 protected:
367     WebGLRenderingContextBase(HTMLCanvasElement&, WebGLContextAttributes);
368     WebGLRenderingContextBase(HTMLCanvasElement&, Ref<GraphicsContext3D>&&, WebGLContextAttributes);
369
370     friend class WebGLDrawBuffers;
371     friend class WebGLFramebuffer;
372     friend class WebGLObject;
373     friend class OESVertexArrayObject;
374     friend class WebGLDebugShaders;
375     friend class WebGLCompressedTextureATC;
376     friend class WebGLCompressedTexturePVRTC;
377     friend class WebGLCompressedTextureS3TC;
378     friend class WebGLRenderingContextErrorMessageCallback;
379     friend class WebGLVertexArrayObjectOES;
380     friend class WebGLVertexArrayObject;
381     friend class WebGLVertexArrayObjectBase;
382
383     virtual void initializeNewContext();
384     virtual void initializeVertexArrayObjects() = 0;
385     void setupFlags();
386
387     // ActiveDOMObject
388     bool hasPendingActivity() const override;
389     void stop() override;
390     const char* activeDOMObjectName() const override;
391     bool canSuspendForDocumentSuspension() const override;
392
393     void addSharedObject(WebGLSharedObject&);
394     void addContextObject(WebGLContextObject&);
395     void detachAndRemoveAllObjects();
396
397     void destroyGraphicsContext3D();
398     void markContextChanged();
399
400     void addActivityStateChangeObserverIfNecessary();
401     void removeActivityStateChangeObserver();
402
403     // Query whether it is built on top of compliant GLES2 implementation.
404     bool isGLES2Compliant() { return m_isGLES2Compliant; }
405     // Query if the GL implementation is NPOT strict.
406     bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
407     // Query if depth_stencil buffer is supported.
408     bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
409
410     // Helper to return the size in bytes of OpenGL data types
411     // like GL_FLOAT, GL_INT, etc.
412     unsigned int sizeInBytes(GC3Denum type);
413
414     // Basic validation of count and offset against number of elements in element array buffer
415     bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
416
417     // Conservative but quick index validation
418     virtual bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) = 0;
419
420     // Precise but slow index validation -- only done if conservative checks fail
421     bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired);
422     bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);
423
424     bool validateWebGLObject(const char*, WebGLObject*);
425
426     bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
427     bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primcount);
428     bool validateNPOTTextureLevel(GC3Dsizei width, GC3Dsizei height, GC3Dint level, const char* functionName);
429
430     // Adds a compressed texture format.
431     void addCompressedTextureFormat(GC3Denum);
432
433     RefPtr<Image> drawImageIntoBuffer(Image&, int width, int height, int deviceScaleFactor);
434
435 #if ENABLE(VIDEO)
436     RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
437 #endif
438
439     WebGLTexture::TextureExtensionFlag textureExtensionFlags() const;
440
441     bool enableSupportedExtension(const char* extensionNameLiteral);
442
443     RefPtr<GraphicsContext3D> m_context;
444     RefPtr<WebGLContextGroup> m_contextGroup;
445
446     // Dispatches a context lost event once it is determined that one is needed.
447     // This is used both for synthetic and real context losses. For real ones, it's
448     // likely that there's no JavaScript on the stack, but that might be dependent
449     // on how exactly the platform discovers that the context was lost. For better
450     // portability we always defer the dispatch of the event.
451     Timer m_dispatchContextLostEventTimer;
452     bool m_restoreAllowed { false };
453     Timer m_restoreTimer;
454
455     bool m_needsUpdate;
456     bool m_markedCanvasDirty;
457     HashSet<WebGLContextObject*> m_contextObjects;
458
459     // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
460     RefPtr<WebGLBuffer> m_boundArrayBuffer;
461     RefPtr<WebGLBuffer> m_boundCopyReadBuffer;
462     RefPtr<WebGLBuffer> m_boundCopyWriteBuffer;
463     RefPtr<WebGLBuffer> m_boundPixelPackBuffer;
464     RefPtr<WebGLBuffer> m_boundPixelUnpackBuffer;
465     RefPtr<WebGLBuffer> m_boundTransformFeedbackBuffer;
466     RefPtr<WebGLBuffer> m_boundUniformBuffer;
467
468     RefPtr<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
469     RefPtr<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;
470
471     void setBoundVertexArrayObject(WebGLVertexArrayObjectBase* arrayObject)
472     {
473         m_boundVertexArrayObject = arrayObject ? arrayObject : m_defaultVertexArrayObject;
474     }
475     
476     class VertexAttribValue {
477     public:
478         VertexAttribValue()
479         {
480             initValue();
481         }
482         
483         void initValue()
484         {
485             value[0] = 0.0f;
486             value[1] = 0.0f;
487             value[2] = 0.0f;
488             value[3] = 1.0f;
489         }
490         
491         GC3Dfloat value[4];
492     };
493     Vector<VertexAttribValue> m_vertexAttribValue;
494     unsigned m_maxVertexAttribs;
495     RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
496     long m_vertexAttrib0BufferSize;
497     GC3Dfloat m_vertexAttrib0BufferValue[4];
498     bool m_forceAttrib0BufferRefill;
499     bool m_vertexAttrib0UsedBefore;
500
501     RefPtr<WebGLProgram> m_currentProgram;
502     RefPtr<WebGLFramebuffer> m_framebufferBinding;
503     RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
504     struct TextureUnitState {
505         RefPtr<WebGLTexture> texture2DBinding;
506         RefPtr<WebGLTexture> textureCubeMapBinding;
507     };
508     Vector<TextureUnitState> m_textureUnits;
509     HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_unrenderableTextureUnits;
510
511     unsigned long m_activeTextureUnit;
512
513     RefPtr<WebGLTexture> m_blackTexture2D;
514     RefPtr<WebGLTexture> m_blackTextureCubeMap;
515
516     Vector<GC3Denum> m_compressedTextureFormats;
517
518     // Fixed-size cache of reusable image buffers for video texImage2D calls.
519     class LRUImageBufferCache {
520     public:
521         LRUImageBufferCache(int capacity);
522         // The pointer returned is owned by the image buffer map.
523         ImageBuffer* imageBuffer(const IntSize& size);
524     private:
525         void bubbleToFront(int idx);
526         std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
527         int m_capacity;
528     };
529     LRUImageBufferCache m_generatedImageCache { 0 };
530
531     GC3Dint m_maxTextureSize;
532     GC3Dint m_maxCubeMapTextureSize;
533     GC3Dint m_maxRenderbufferSize;
534     GC3Dint m_maxViewportDims[2] { 0, 0 };
535     GC3Dint m_maxTextureLevel;
536     GC3Dint m_maxCubeMapTextureLevel;
537
538     GC3Dint m_maxDrawBuffers;
539     GC3Dint m_maxColorAttachments;
540     GC3Denum m_backDrawBuffer;
541     bool m_drawBuffersWebGLRequirementsChecked;
542     bool m_drawBuffersSupported;
543
544     GC3Dint m_packAlignment;
545     GC3Dint m_unpackAlignment;
546     bool m_unpackFlipY;
547     bool m_unpackPremultiplyAlpha;
548     GC3Denum m_unpackColorspaceConversion;
549     bool m_contextLost { false };
550     LostContextMode m_contextLostMode { SyntheticLostContext };
551     WebGLContextAttributes m_attributes;
552
553     bool m_layerCleared;
554     GC3Dfloat m_clearColor[4];
555     bool m_scissorEnabled;
556     GC3Dfloat m_clearDepth;
557     GC3Dint m_clearStencil;
558     GC3Dboolean m_colorMask[4];
559     GC3Dboolean m_depthMask;
560
561     bool m_stencilEnabled;
562     GC3Duint m_stencilMask, m_stencilMaskBack;
563     GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
564     GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
565
566     bool m_isGLES2Compliant;
567     bool m_isGLES2NPOTStrict;
568     bool m_isDepthStencilSupported;
569     bool m_isRobustnessEXTSupported;
570
571     bool m_synthesizedErrorsToConsole { true };
572     int m_numGLErrorsToConsoleAllowed;
573
574     // A WebGLRenderingContext can be created in a state where it appears as
575     // a valid and active context, but will not execute any important operations
576     // until its load policy is completely resolved.
577     bool m_isPendingPolicyResolution { false };
578     bool m_hasRequestedPolicyResolution { false };
579     bool isContextLostOrPending();
580
581     // Enabled extension objects.
582     // FIXME: Move some of these to WebGLRenderingContext, the ones not needed for WebGL2
583     std::unique_ptr<EXTFragDepth> m_extFragDepth;
584     std::unique_ptr<EXTBlendMinMax> m_extBlendMinMax;
585     std::unique_ptr<EXTsRGB> m_extsRGB;
586     std::unique_ptr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
587     std::unique_ptr<EXTShaderTextureLOD> m_extShaderTextureLOD;
588     std::unique_ptr<OESTextureFloat> m_oesTextureFloat;
589     std::unique_ptr<OESTextureFloatLinear> m_oesTextureFloatLinear;
590     std::unique_ptr<OESTextureHalfFloat> m_oesTextureHalfFloat;
591     std::unique_ptr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
592     std::unique_ptr<OESStandardDerivatives> m_oesStandardDerivatives;
593     std::unique_ptr<OESVertexArrayObject> m_oesVertexArrayObject;
594     std::unique_ptr<OESElementIndexUint> m_oesElementIndexUint;
595     std::unique_ptr<WebGLLoseContext> m_webglLoseContext;
596     std::unique_ptr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
597     std::unique_ptr<WebGLDebugShaders> m_webglDebugShaders;
598     std::unique_ptr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
599     std::unique_ptr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
600     std::unique_ptr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
601     std::unique_ptr<WebGLDepthTexture> m_webglDepthTexture;
602     std::unique_ptr<WebGLDrawBuffers> m_webglDrawBuffers;
603     std::unique_ptr<ANGLEInstancedArrays> m_angleInstancedArrays;
604
605     // Helpers for getParameter and other similar functions.
606     bool getBooleanParameter(GC3Denum);
607     Vector<bool> getBooleanArrayParameter(GC3Denum);
608     float getFloatParameter(GC3Denum);
609     int getIntParameter(GC3Denum);
610     unsigned getUnsignedIntParameter(GC3Denum);
611     long long getInt64Parameter(GC3Denum);
612     RefPtr<Float32Array> getWebGLFloatArrayParameter(GC3Denum);
613     RefPtr<Int32Array> getWebGLIntArrayParameter(GC3Denum);
614
615     // Clear the backbuffer if it was composited since the last operation.
616     // clearMask is set to the bitfield of any clear that would happen anyway at this time
617     // and the function returns true if that clear is now unnecessary.
618     bool clearIfComposited(GC3Dbitfield clearMask = 0);
619
620     // Helper to restore state that clearing the framebuffer may destroy.
621     void restoreStateAfterClear();
622
623     void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
624     void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
625     void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels);
626     void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
627
628     bool checkTextureCompleteness(const char*, bool);
629
630     void createFallbackBlackTextures1x1();
631
632     // Helper function for copyTex{Sub}Image, check whether the internalformat
633     // and the color buffer format of the current bound framebuffer combination
634     // is valid.
635     bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
636                                                         GC3Denum colorBufferFormat);
637
638     // Helper function to get the bound framebuffer's color buffer format.
639     GC3Denum getBoundFramebufferColorFormat();
640
641     // Helper function to get the bound framebuffer's width.
642     int getBoundFramebufferWidth();
643
644     // Helper function to get the bound framebuffer's height.
645     int getBoundFramebufferHeight();
646
647     // Helper function to verify limits on the length of uniform and attribute locations.
648     bool validateLocationLength(const char* functionName, const String&);
649
650     // Helper function to check if size is non-negative.
651     // Generate GL error and return false for negative inputs; otherwise, return true.
652     bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
653
654     // Helper function to check if all characters in the string belong to the
655     // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
656     bool validateString(const char* functionName, const String&);
657
658     // Helper function to check target and texture bound to the target.
659     // Generate GL errors and return 0 if target is invalid or texture bound is
660     // null.  Otherwise, return the texture bound to the target.
661     WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
662
663     // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
664     // Generates GL error and returns false if parameters are invalid.
665     bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level);
666
667     // Helper function to check input level for functions {copy}Tex{Sub}Image.
668     // Generates GL error and returns false if level is invalid.
669     bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
670
671     enum TexFuncValidationFunctionType {
672         TexImage,
673         TexSubImage,
674         CopyTexImage
675     };
676
677     enum TexFuncValidationSourceType {
678         SourceArrayBufferView,
679         SourceImageData,
680         SourceHTMLImageElement,
681         SourceHTMLCanvasElement,
682         SourceHTMLVideoElement,
683     };
684
685     // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
686     // Otherwise, it would return quickly without doing other work.
687     bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
688         GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
689
690     // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
691     // Generates GL error and returns false if parameters are invalid.
692     bool validateTexFuncParameters(const char* functionName,
693         TexFuncValidationFunctionType,
694         GC3Denum target, GC3Dint level,
695         GC3Denum internalformat,
696         GC3Dsizei width, GC3Dsizei height, GC3Dint border,
697         GC3Denum format, GC3Denum type);
698
699     enum NullDisposition {
700         NullAllowed,
701         NullNotAllowed
702     };
703
704     // Helper function to validate that the given ArrayBufferView
705     // is of the correct type and contains enough data for the texImage call.
706     // Generates GL error and returns false if parameters are invalid.
707     bool validateTexFuncData(const char* functionName, GC3Dint level,
708         GC3Dsizei width, GC3Dsizei height,
709         GC3Denum internalformat, GC3Denum format, GC3Denum type,
710         ArrayBufferView* pixels,
711         NullDisposition);
712
713     // Helper function to validate a given texture format is settable as in
714     // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
715     // copyTexSubImage2D.
716     // Generates GL error and returns false if the format is not settable.
717     bool validateSettableTexInternalFormat(const char* functionName, GC3Denum format);
718
719     // Helper function to validate compressed texture data is correct size
720     // for the given format and dimensions.
721     bool validateCompressedTexFuncData(const char* functionName, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& pixels);
722
723     // Helper function for validating compressed texture formats.
724     bool validateCompressedTexFormat(GC3Denum format);
725
726     // Helper function to validate compressed texture dimensions are valid for
727     // the given format.
728     bool validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
729
730     // Helper function to validate compressed texture dimensions are valid for
731     // the given format.
732     bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
733                                             GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
734
735     // Helper function to validate mode for draw{Arrays/Elements}.
736     bool validateDrawMode(const char* functionName, GC3Denum);
737
738     // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
739     bool validateStencilSettings(const char* functionName);
740
741     // Helper function to validate stencil func.
742     bool validateStencilFunc(const char* functionName, GC3Denum);
743
744     // Helper function for texParameterf and texParameteri.
745     void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
746
747     // Helper function to print GL errors to console.
748     void printGLErrorToConsole(const String&);
749     void printGLWarningToConsole(const char* function, const char* reason);
750
751     // Helper function to print warnings to console. Currently
752     // used only to warn about use of obsolete functions.
753     void printWarningToConsole(const String&);
754
755     // Helper function to validate input parameters for framebuffer functions.
756     // Generate GL error if parameters are illegal.
757     virtual bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) = 0;
758
759     // Helper function to validate blend equation mode.
760     virtual bool validateBlendEquation(const char* functionName, GC3Denum) = 0;
761
762     // Helper function to validate blend func factors.
763     bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
764
765     // Helper function to validate a GL capability.
766     virtual bool validateCapability(const char* functionName, GC3Denum) = 0;
767
768     // Helper function to validate input parameters for uniform functions.
769     bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, const Float32List&, GC3Dsizei mod);
770     bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, const Int32List&, GC3Dsizei mod);
771     bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
772     bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, const Float32List&, GC3Dsizei mod);
773     bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
774
775     // Helper function to validate parameters for bufferData.
776     // Return the current bound buffer to target, or 0 if parameters are invalid.
777     WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
778
779     // Helper function for tex{Sub}Image2D to make sure image is ready.
780     bool validateHTMLImageElement(const char* functionName, HTMLImageElement*);
781     bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*);
782 #if ENABLE(VIDEO)
783     bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*);
784 #endif
785
786     // Helper functions for vertexAttribNf{v}.
787     void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
788     void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32List&&, GC3Dsizei expectedSize);
789
790     // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
791     // Return false if caller should return without further processing.
792     bool deleteObject(WebGLObject*);
793
794     // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
795     // If the object has already been deleted, set deleted to true upon return.
796     // Return false if caller should return without further processing.
797     bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
798
799     // Helpers for simulating vertexAttrib0.
800     void initVertexAttrib0();
801     bool simulateVertexAttrib0(GC3Dsizei numVertex);
802     bool validateSimulatedVertexAttrib0(GC3Dsizei numVertex);
803     void restoreStatesAfterVertexAttrib0Simulation();
804
805     void dispatchContextLostEvent();
806     // Helper for restoration after context lost.
807     void maybeRestoreContext();
808
809     // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message to the JavaScript console.
810     enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };
811     void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
812
813     String ensureNotNull(const String&) const;
814
815     // Enable or disable stencil test based on user setting and whether the current FBO has a stencil buffer.
816     void applyStencilTest();
817
818     // Helper for enabling or disabling a capability.
819     void enableOrDisable(GC3Denum capability, bool enable);
820
821     // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
822     IntSize clampedCanvasSize();
823
824     virtual GC3Dint getMaxDrawBuffers() = 0;
825     virtual GC3Dint getMaxColorAttachments() = 0;
826
827     void setBackDrawBuffer(GC3Denum);
828
829     void restoreCurrentFramebuffer();
830     void restoreCurrentTexture2D();
831
832     // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
833     bool supportsDrawBuffers();
834
835 private:
836     bool validateArrayBufferType(const char* functionName, GC3Denum type, std::optional<JSC::TypedArrayType>);
837     void registerWithWebGLStateTracker();
838     void checkForContextLossHandling();
839
840     void activityStateDidChange(ActivityState::Flags oldActivityState, ActivityState::Flags newActivityState) override;
841
842     WebGLStateTracker::Token m_trackerToken;
843     Timer m_checkForContextLossHandlingTimer;
844 };
845
846 } // namespace WebCore
847
848 SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::WebGLRenderingContextBase, is3d())
849
850 #endif