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