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