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