1/*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WebGLRenderingContext_h
27#define WebGLRenderingContext_h
28
29#include "core/dom/ActiveDOMObject.h"
30#include "core/html/canvas/CanvasRenderingContext.h"
31#include "core/html/canvas/WebGLGetInfo.h"
32#include "core/page/Page.h"
33#include "core/platform/Timer.h"
34#include "core/platform/graphics/GraphicsContext3D.h"
35#include "core/platform/graphics/ImageBuffer.h"
36
37#include "wtf/Float32Array.h"
38#include "wtf/Int32Array.h"
39#include "wtf/OwnArrayPtr.h"
40#include "wtf/text/WTFString.h"
41
42namespace WebKit { class WebLayer; }
43
44namespace WebCore {
45
46class ANGLEInstancedArrays;
47class DrawingBuffer;
48class EXTFragDepth;
49class EXTTextureFilterAnisotropic;
50class ExceptionState;
51class HTMLImageElement;
52class HTMLVideoElement;
53class ImageBuffer;
54class ImageData;
55class IntSize;
56class OESElementIndexUint;
57class OESStandardDerivatives;
58class OESTextureFloat;
59class OESTextureFloatLinear;
60class OESTextureHalfFloat;
61class OESTextureHalfFloatLinear;
62class OESVertexArrayObject;
63class WebGLActiveInfo;
64class WebGLBuffer;
65class WebGLCompressedTextureATC;
66class WebGLCompressedTexturePVRTC;
67class WebGLCompressedTextureS3TC;
68class WebGLContextAttributes;
69class WebGLContextGroup;
70class WebGLContextObject;
71class WebGLDebugRendererInfo;
72class WebGLDebugShaders;
73class WebGLDepthTexture;
74class WebGLDrawBuffers;
75class WebGLExtension;
76class WebGLFramebuffer;
77class WebGLLoseContext;
78class WebGLObject;
79class WebGLProgram;
80class WebGLRenderbuffer;
81class WebGLShader;
82class WebGLShaderPrecisionFormat;
83class WebGLSharedObject;
84class WebGLTexture;
85class WebGLUniformLocation;
86class WebGLVertexArrayObjectOES;
87
88class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver {
89public:
90    static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
91    virtual ~WebGLRenderingContext();
92
93    virtual bool is3d() const { return true; }
94    virtual bool isAccelerated() const { return true; }
95
96    int drawingBufferWidth() const;
97    int drawingBufferHeight() const;
98
99    void activeTexture(GC3Denum texture);
100    void attachShader(WebGLProgram*, WebGLShader*);
101    void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name);
102    void bindBuffer(GC3Denum target, WebGLBuffer*);
103    void bindFramebuffer(GC3Denum target, WebGLFramebuffer*);
104    void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*);
105    void bindTexture(GC3Denum target, WebGLTexture*);
106    void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
107    void blendEquation(GC3Denum mode);
108    void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
109    void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
110    void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
111
112    void bufferData(GC3Denum target, long long size, GC3Denum usage);
113    void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage);
114    void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage);
115    void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data);
116    void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data);
117
118    GC3Denum checkFramebufferStatus(GC3Denum target);
119    void clear(GC3Dbitfield mask);
120    void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
121    void clearDepth(GC3Dfloat);
122    void clearStencil(GC3Dint);
123    void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
124    void compileShader(WebGLShader*);
125
126    void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
127                              GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
128    void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
129                                 GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
130
131    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
132    void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
133
134    PassRefPtr<WebGLBuffer> createBuffer();
135    PassRefPtr<WebGLFramebuffer> createFramebuffer();
136    PassRefPtr<WebGLProgram> createProgram();
137    PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
138    PassRefPtr<WebGLShader> createShader(GC3Denum type);
139    PassRefPtr<WebGLTexture> createTexture();
140
141    void cullFace(GC3Denum mode);
142
143    void deleteBuffer(WebGLBuffer*);
144    void deleteFramebuffer(WebGLFramebuffer*);
145    void deleteProgram(WebGLProgram*);
146    void deleteRenderbuffer(WebGLRenderbuffer*);
147    void deleteShader(WebGLShader*);
148    void deleteTexture(WebGLTexture*);
149
150    void depthFunc(GC3Denum);
151    void depthMask(GC3Dboolean);
152    void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
153    void detachShader(WebGLProgram*, WebGLShader*);
154    void disable(GC3Denum cap);
155    void disableVertexAttribArray(GC3Duint index);
156    void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
157    void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
158
159    void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
160    void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount);
161
162    void enable(GC3Denum cap);
163    void enableVertexAttribArray(GC3Duint index);
164    void finish();
165    void flush();
166    void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*);
167    void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level);
168    void frontFace(GC3Denum mode);
169    void generateMipmap(GC3Denum target);
170
171    PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index);
172    PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index);
173    bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
174    GC3Dint getAttribLocation(WebGLProgram*, const String& name);
175    WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname);
176    PassRefPtr<WebGLContextAttributes> getContextAttributes();
177    GC3Denum getError();
178    PassRefPtr<WebGLExtension> getExtension(const String& name);
179    WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname);
180    WebGLGetInfo getParameter(GC3Denum pname);
181    WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname);
182    String getProgramInfoLog(WebGLProgram*);
183    WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname);
184    WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname);
185    String getShaderInfoLog(WebGLShader*);
186    PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType);
187    String getShaderSource(WebGLShader*);
188    Vector<String> getSupportedExtensions();
189    WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname);
190    WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
191    PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
192    WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname);
193    long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
194
195    void hint(GC3Denum target, GC3Denum mode);
196    GC3Dboolean isBuffer(WebGLBuffer*);
197    bool isContextLost();
198    GC3Dboolean isEnabled(GC3Denum cap);
199    GC3Dboolean isFramebuffer(WebGLFramebuffer*);
200    GC3Dboolean isProgram(WebGLProgram*);
201    GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
202    GC3Dboolean isShader(WebGLShader*);
203    GC3Dboolean isTexture(WebGLTexture*);
204
205    void lineWidth(GC3Dfloat);
206    void linkProgram(WebGLProgram*);
207    void pixelStorei(GC3Denum pname, GC3Dint param);
208    void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
209    void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels);
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&);
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*, ExceptionState&);
224    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
225        GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
226    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
227        GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
228    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
229        GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
230    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
231        GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
232
233    void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
234    void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
235
236    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
237        GC3Dsizei width, GC3Dsizei height,
238        GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&);
239    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
240        GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
241    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
242        GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
243    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
244        GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
245    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
246        GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
247
248    void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
249    void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
250    void uniform1fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
251    void uniform1i(const WebGLUniformLocation*, GC3Dint x);
252    void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
253    void uniform1iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
254    void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y);
255    void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
256    void uniform2fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
257    void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y);
258    void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
259    void uniform2iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
260    void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
261    void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
262    void uniform3fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
263    void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z);
264    void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
265    void uniform3iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
266    void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
267    void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
268    void uniform4fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
269    void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
270    void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
271    void uniform4iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
272    void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
273    void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
274    void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
275    void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
276    void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
277    void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
278
279    void useProgram(WebGLProgram*);
280    void validateProgram(WebGLProgram*);
281
282    void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
283    void vertexAttrib1fv(GC3Duint index, Float32Array* values);
284    void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
285    void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
286    void vertexAttrib2fv(GC3Duint index, Float32Array* values);
287    void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
288    void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
289    void vertexAttrib3fv(GC3Duint index, Float32Array* values);
290    void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
291    void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
292    void vertexAttrib4fv(GC3Duint index, Float32Array* values);
293    void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
294    void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
295        GC3Dsizei stride, long long offset);
296
297    void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
298
299    void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
300
301    // WEBKIT_lose_context support
302    enum LostContextMode {
303        // Lost context occurred at the graphics system level.
304        RealLostContext,
305
306        // Lost context provoked by WEBKIT_lose_context.
307        SyntheticLostContext,
308
309        // A synthetic lost context that should attempt to recover automatically
310        AutoRecoverSyntheticLostContext
311    };
312    void forceLostContext(LostContextMode);
313    void forceRestoreContext();
314    void loseContextImpl(LostContextMode);
315
316    GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
317    WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
318    virtual WebKit::WebLayer* platformLayer() const;
319
320    void reshape(int width, int height);
321
322    void markLayerComposited();
323    virtual void paintRenderingResultsToCanvas();
324    virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
325
326    void removeSharedObject(WebGLSharedObject*);
327    void removeContextObject(WebGLContextObject*);
328
329    unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
330
331    // ActiveDOMObject notifications
332    virtual bool hasPendingActivity() const;
333    virtual void stop();
334
335  private:
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*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes, GraphicsContext3D::Attributes);
348    void initializeNewContext();
349    void setupFlags();
350
351    void addSharedObject(WebGLSharedObject*);
352    void addContextObject(WebGLContextObject*);
353    void detachAndRemoveAllObjects();
354
355    void destroyGraphicsContext3D();
356    void markContextChanged();
357
358    // Query if the GL implementation is NPOT strict.
359    bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
360    // Query if depth_stencil buffer is supported.
361    bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
362
363    // Helper to return the size in bytes of OpenGL data types
364    // like GL_FLOAT, GL_INT, etc.
365    unsigned int sizeInBytes(GC3Denum type);
366
367    // Check if each enabled vertex attribute is bound to a buffer.
368    bool validateRenderingState();
369
370    bool validateWebGLObject(const char*, WebGLObject*);
371
372    // Adds a compressed texture format.
373    void addCompressedTextureFormat(GC3Denum);
374    void removeAllCompressedTextureFormats();
375
376    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
377
378    WebGLRenderbuffer* ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer*);
379
380    RefPtr<GraphicsContext3D> m_context;
381    RefPtr<WebGLContextGroup> m_contextGroup;
382
383    // Structure for rendering to a DrawingBuffer, instead of directly
384    // to the back-buffer of m_context.
385    RefPtr<DrawingBuffer> m_drawingBuffer;
386
387    // Dispatches a context lost event once it is determined that one is needed.
388    // This is used both for synthetic and real context losses. For real ones, it's
389    // likely that there's no JavaScript on the stack, but that might be dependent
390    // on how exactly the platform discovers that the context was lost. For better
391    // portability we always defer the dispatch of the event.
392    Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
393    bool m_restoreAllowed;
394    Timer<WebGLRenderingContext> m_restoreTimer;
395
396    bool m_needsUpdate;
397    bool m_markedCanvasDirty;
398    HashSet<WebGLContextObject*> m_contextObjects;
399
400    // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
401    RefPtr<WebGLBuffer> m_boundArrayBuffer;
402
403    RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
404    RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
405    void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
406    {
407        if (arrayObject)
408            m_boundVertexArrayObject = arrayObject;
409        else
410            m_boundVertexArrayObject = m_defaultVertexArrayObject;
411    }
412
413    class VertexAttribValue {
414    public:
415        VertexAttribValue()
416        {
417            initValue();
418        }
419
420        void initValue()
421        {
422            value[0] = 0.0f;
423            value[1] = 0.0f;
424            value[2] = 0.0f;
425            value[3] = 1.0f;
426        }
427
428        GC3Dfloat value[4];
429    };
430    Vector<VertexAttribValue> m_vertexAttribValue;
431    unsigned m_maxVertexAttribs;
432    RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
433    long m_vertexAttrib0BufferSize;
434    GC3Dfloat m_vertexAttrib0BufferValue[4];
435    bool m_forceAttrib0BufferRefill;
436    bool m_vertexAttrib0UsedBefore;
437
438    RefPtr<WebGLProgram> m_currentProgram;
439    RefPtr<WebGLFramebuffer> m_framebufferBinding;
440    RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
441    class TextureUnitState {
442    public:
443        RefPtr<WebGLTexture> m_texture2DBinding;
444        RefPtr<WebGLTexture> m_textureCubeMapBinding;
445    };
446    Vector<TextureUnitState> m_textureUnits;
447    unsigned long m_activeTextureUnit;
448
449    RefPtr<WebGLTexture> m_blackTexture2D;
450    RefPtr<WebGLTexture> m_blackTextureCubeMap;
451
452    Vector<GC3Denum> m_compressedTextureFormats;
453
454    // Fixed-size cache of reusable image buffers for video texImage2D calls.
455    class LRUImageBufferCache {
456    public:
457        LRUImageBufferCache(int capacity);
458        // The pointer returned is owned by the image buffer map.
459        ImageBuffer* imageBuffer(const IntSize& size);
460    private:
461        void bubbleToFront(int idx);
462        OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers;
463        int m_capacity;
464    };
465    LRUImageBufferCache m_videoCache;
466
467    GC3Dint m_maxTextureSize;
468    GC3Dint m_maxCubeMapTextureSize;
469    GC3Dint m_maxRenderbufferSize;
470    GC3Dint m_maxViewportDims[2];
471    GC3Dint m_maxTextureLevel;
472    GC3Dint m_maxCubeMapTextureLevel;
473
474    GC3Dint m_maxDrawBuffers;
475    GC3Dint m_maxColorAttachments;
476    GC3Denum m_backDrawBuffer;
477    bool m_drawBuffersWebGLRequirementsChecked;
478    bool m_drawBuffersSupported;
479
480    GC3Dint m_packAlignment;
481    GC3Dint m_unpackAlignment;
482    bool m_unpackFlipY;
483    bool m_unpackPremultiplyAlpha;
484    GC3Denum m_unpackColorspaceConversion;
485    bool m_contextLost;
486    LostContextMode m_contextLostMode;
487    GraphicsContext3D::Attributes m_attributes;
488    GraphicsContext3D::Attributes m_requestedAttributes;
489
490    bool m_layerCleared;
491    GC3Dfloat m_clearColor[4];
492    bool m_scissorEnabled;
493    GC3Dfloat m_clearDepth;
494    GC3Dint m_clearStencil;
495    GC3Dboolean m_colorMask[4];
496    GC3Dboolean m_depthMask;
497
498    bool m_stencilEnabled;
499    GC3Duint m_stencilMask, m_stencilMaskBack;
500    GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
501    GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
502
503    bool m_isGLES2NPOTStrict;
504    bool m_isDepthStencilSupported;
505
506    bool m_synthesizedErrorsToConsole;
507    int m_numGLErrorsToConsoleAllowed;
508
509    // Enabled extension objects.
510    RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
511    RefPtr<EXTFragDepth> m_extFragDepth;
512    RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
513    RefPtr<OESTextureFloat> m_oesTextureFloat;
514    RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
515    RefPtr<OESTextureHalfFloat> m_oesTextureHalfFloat;
516    RefPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
517    RefPtr<OESStandardDerivatives> m_oesStandardDerivatives;
518    RefPtr<OESVertexArrayObject> m_oesVertexArrayObject;
519    RefPtr<OESElementIndexUint> m_oesElementIndexUint;
520    RefPtr<WebGLLoseContext> m_webglLoseContext;
521    RefPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
522    RefPtr<WebGLDebugShaders> m_webglDebugShaders;
523    RefPtr<WebGLDrawBuffers> m_webglDrawBuffers;
524    RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
525    RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
526    RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
527    RefPtr<WebGLDepthTexture> m_webglDepthTexture;
528
529    class ExtensionTracker {
530    public:
531        ExtensionTracker(bool privileged, bool draft, bool prefixed, const char** prefixes)
532            : m_privileged(privileged)
533            , m_draft(draft)
534            , m_prefixed(prefixed)
535            , m_prefixes(prefixes)
536        {
537        }
538
539        virtual ~ExtensionTracker()
540        {
541        }
542
543        bool getPrefixed() const
544        {
545            return m_prefixed;
546        }
547
548        bool getPrivileged() const
549        {
550            return m_privileged;
551        }
552
553        bool getDraft() const
554        {
555            return m_draft;
556        }
557
558        bool matchesNameWithPrefixes(const String&) const;
559
560        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0;
561        virtual bool supported(WebGLRenderingContext*) const = 0;
562        virtual const char* getExtensionName() const = 0;
563        virtual void loseExtension() = 0;
564
565    private:
566        bool m_privileged;
567        bool m_draft;
568        bool m_prefixed;
569        const char** m_prefixes;
570    };
571
572    template <typename T>
573    class TypedExtensionTracker : public ExtensionTracker {
574    public:
575        TypedExtensionTracker(RefPtr<T>& extensionField, bool privileged, bool draft, bool prefixed, const char** prefixes)
576            : ExtensionTracker(privileged, draft, prefixed, prefixes)
577            , m_extensionField(extensionField)
578        {
579        }
580
581        ~TypedExtensionTracker()
582        {
583            if (m_extensionField) {
584                m_extensionField->lose(true);
585                m_extensionField = 0;
586            }
587        }
588
589        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const
590        {
591            if (!m_extensionField)
592                m_extensionField = T::create(context);
593
594            return m_extensionField;
595        }
596
597        virtual bool supported(WebGLRenderingContext* context) const
598        {
599            return T::supported(context);
600        }
601
602        virtual const char* getExtensionName() const
603        {
604            return T::getExtensionName();
605        }
606
607        virtual void loseExtension()
608        {
609            if (m_extensionField) {
610                m_extensionField->lose(false);
611                if (m_extensionField->isLost())
612                    m_extensionField = 0;
613            }
614        }
615
616    private:
617        RefPtr<T>& m_extensionField;
618    };
619
620    Vector<ExtensionTracker*> m_extensions;
621
622    template <typename T>
623    void registerExtension(RefPtr<T>& extensionPtr, bool privileged, bool draft, bool prefixed, const char** prefixes)
624    {
625        m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, privileged, draft, prefixed, prefixes));
626    }
627
628    // Errors raised by synthesizeGLError() while the context is lost.
629    Vector<GC3Denum> lost_context_errors_;
630
631    // Helpers for getParameter and others
632    WebGLGetInfo getBooleanParameter(GC3Denum);
633    WebGLGetInfo getBooleanArrayParameter(GC3Denum);
634    WebGLGetInfo getFloatParameter(GC3Denum);
635    WebGLGetInfo getIntParameter(GC3Denum);
636    WebGLGetInfo getUnsignedIntParameter(GC3Denum);
637    WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
638    WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
639
640    // Clear the backbuffer if it was composited since the last operation.
641    // clearMask is set to the bitfield of any clear that would happen anyway at this time
642    // and the function returns true if that clear is now unnecessary.
643    bool clearIfComposited(GC3Dbitfield clearMask = 0);
644
645    // Helper to restore state that clearing the framebuffer may destroy.
646    void restoreStateAfterClear();
647
648    void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
649    void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
650    void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
651    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
652
653    void handleTextureCompleteness(const char*, bool);
654    void createFallbackBlackTextures1x1();
655
656    // Helper function for copyTex{Sub}Image, check whether the internalformat
657    // and the color buffer format of the current bound framebuffer combination
658    // is valid.
659    bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
660                                                        GC3Denum colorBufferFormat);
661
662    // Helper function to get the bound framebuffer's color buffer format.
663    GC3Denum getBoundFramebufferColorFormat();
664
665    // Helper function to get the bound framebuffer's width.
666    int getBoundFramebufferWidth();
667
668    // Helper function to get the bound framebuffer's height.
669    int getBoundFramebufferHeight();
670
671    // Helper function to verify limits on the length of uniform and attribute locations.
672    bool validateLocationLength(const char* functionName, const String&);
673
674    // Helper function to check if size is non-negative.
675    // Generate GL error and return false for negative inputs; otherwise, return true.
676    bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
677
678    // Helper function to check if all characters in the string belong to the
679    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
680    bool validateString(const char* functionName, const String&);
681
682    // Helper function to check target and texture bound to the target.
683    // Generate GL errors and return 0 if target is invalid or texture bound is
684    // null.  Otherwise, return the texture bound to the target.
685    WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
686
687    // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
688    // Generates GL error and returns false if parameters are invalid.
689    bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
690
691    // Helper function to check input level for functions {copy}Tex{Sub}Image.
692    // Generates GL error and returns false if level is invalid.
693    bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
694
695    enum TexFuncValidationFunctionType {
696        NotTexSubImage2D,
697        TexSubImage2D,
698    };
699
700    enum TexFuncValidationSourceType {
701        SourceArrayBufferView,
702        SourceImageData,
703        SourceHTMLImageElement,
704        SourceHTMLCanvasElement,
705        SourceHTMLVideoElement,
706    };
707
708    // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
709    // Otherwise, it would return quickly without doing other work.
710    bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
711        GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
712
713    // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
714    // Generates GL error and returns false if parameters are invalid.
715    bool validateTexFuncParameters(const char* functionName,
716                                   TexFuncValidationFunctionType,
717                                   GC3Denum target, GC3Dint level,
718                                   GC3Denum internalformat,
719                                   GC3Dsizei width, GC3Dsizei height, GC3Dint border,
720                                   GC3Denum format, GC3Denum type);
721
722    enum NullDisposition {
723        NullAllowed,
724        NullNotAllowed
725    };
726
727    // Helper function to validate that the given ArrayBufferView
728    // is of the correct type and contains enough data for the texImage call.
729    // Generates GL error and returns false if parameters are invalid.
730    bool validateTexFuncData(const char* functionName, GC3Dint level,
731                             GC3Dsizei width, GC3Dsizei height,
732                             GC3Denum format, GC3Denum type,
733                             ArrayBufferView* pixels,
734                             NullDisposition);
735
736    // Helper function to validate a given texture format is settable as in
737    // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
738    // copyTexSubImage2D.
739    // Generates GL error and returns false if the format is not settable.
740    bool validateSettableTexFormat(const char* functionName, GC3Denum format);
741
742    // Helper function to validate compressed texture data is correct size
743    // for the given format and dimensions.
744    bool validateCompressedTexFuncData(const char* functionName,
745                                       GC3Dsizei width, GC3Dsizei height,
746                                       GC3Denum format, ArrayBufferView* pixels);
747
748    // Helper function for validating compressed texture formats.
749    bool validateCompressedTexFormat(GC3Denum format);
750
751    // Helper function to validate compressed texture dimensions are valid for
752    // the given format.
753    bool validateCompressedTexDimensions(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
754
755    // Helper function to validate compressed texture dimensions are valid for
756    // the given format.
757    bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
758                                            GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
759
760    // Helper function to validate mode for draw{Arrays/Elements}.
761    bool validateDrawMode(const char* functionName, GC3Denum);
762
763    // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
764    bool validateStencilSettings(const char* functionName);
765
766    // Helper function to validate stencil or depth func.
767    bool validateStencilOrDepthFunc(const char* functionName, GC3Denum);
768
769    // Helper function for texParameterf and texParameteri.
770    void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
771
772    // Helper function to print GL errors to console.
773    void printGLErrorToConsole(const String&);
774
775    // Helper function to print warnings to console. Currently
776    // used only to warn about use of obsolete functions.
777    void printWarningToConsole(const String&);
778
779    // Helper function to validate input parameters for framebuffer functions.
780    // Generate GL error if parameters are illegal.
781    bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
782
783    // Helper function to validate blend equation mode.
784    bool validateBlendEquation(const char* functionName, GC3Denum);
785
786    // Helper function to validate blend func factors.
787    bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
788
789    // Helper function to validate a GL capability.
790    bool validateCapability(const char* functionName, GC3Denum);
791
792    // Helper function to validate input parameters for uniform functions.
793    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
794    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
795    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
796    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
797    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
798
799    // Helper function to validate parameters for bufferData.
800    // Return the current bound buffer to target, or 0 if parameters are invalid.
801    WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
802
803    // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
804    bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
805
806    // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
807    bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
808
809    // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
810    bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
811
812    // Helper function to validate drawArrays(Instanced) calls
813    bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count);
814
815    // Helper function to validate drawElements(Instanced) calls
816    bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
817
818    // Helper function to validate draw*Instanced calls
819    bool validateDrawInstanced(const char* functionName, GC3Dsizei primcount);
820
821    // Helper functions for vertexAttribNf{v}.
822    void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
823    void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
824    void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
825
826    // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
827    // Return false if caller should return without further processing.
828    bool deleteObject(WebGLObject*);
829
830    // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
831    // If the object has already been deleted, set deleted to true upon return.
832    // Return false if caller should return without further processing.
833    bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
834
835    void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
836    // Helper for restoration after context lost.
837    void maybeRestoreContext(Timer<WebGLRenderingContext>*);
838
839    // Determine if we are running privileged code in the browser, for example,
840    // a Safari or Chrome extension.
841    bool allowPrivilegedExtensions() const;
842
843    enum ConsoleDisplayPreference {
844        DisplayInConsole,
845        DontDisplayInConsole
846    };
847
848    // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
849    // to the JavaScript console.
850    void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
851    void emitGLWarning(const char* function, const char* reason);
852
853    String ensureNotNull(const String&) const;
854
855    // Enable or disable stencil test based on user setting and
856    // whether the current FBO has a stencil buffer.
857    void applyStencilTest();
858
859    // Helper for enabling or disabling a capability.
860    void enableOrDisable(GC3Denum capability, bool enable);
861
862    // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
863    IntSize clampedCanvasSize();
864
865    // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
866    // Later, return the cached value.
867    GC3Dint getMaxDrawBuffers();
868    GC3Dint getMaxColorAttachments();
869
870    void setBackDrawBuffer(GC3Denum);
871
872    void restoreCurrentFramebuffer();
873    void restoreCurrentTexture2D();
874
875    virtual void multisamplingChanged(bool);
876    bool m_multisamplingAllowed;
877    bool m_multisamplingObserverRegistered;
878
879    friend class WebGLStateRestorer;
880    friend class WebGLRenderingContextEvictionManager;
881
882    static Vector<WebGLRenderingContext*>& activeContexts();
883    static Vector<WebGLRenderingContext*>& forciblyEvictedContexts();
884
885    static void activateContext(WebGLRenderingContext*);
886    static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList);
887    static void willDestroyContext(WebGLRenderingContext*);
888    static void forciblyLoseOldestContext(const String& reason);
889    static IntSize oldestContextSize();
890};
891
892} // namespace WebCore
893
894#endif
895