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 WebGLRenderingContextBase_h
27#define WebGLRenderingContextBase_h
28
29#include "bindings/core/v8/Nullable.h"
30#include "core/dom/ActiveDOMObject.h"
31#include "core/html/canvas/CanvasRenderingContext.h"
32#include "core/html/canvas/WebGLExtensionName.h"
33#include "core/html/canvas/WebGLGetInfo.h"
34#include "core/page/Page.h"
35#include "core/rendering/RenderBoxModelObject.h"
36#include "platform/Timer.h"
37#include "platform/graphics/GraphicsTypes3D.h"
38#include "platform/graphics/ImageBuffer.h"
39#include "platform/graphics/gpu/DrawingBuffer.h"
40#include "platform/graphics/gpu/Extensions3DUtil.h"
41#include "platform/graphics/gpu/WebGLImageConversion.h"
42#include "public/platform/WebGraphicsContext3D.h"
43#include "wtf/Float32Array.h"
44#include "wtf/Int32Array.h"
45#include "wtf/OwnPtr.h"
46#include "wtf/text/WTFString.h"
47
48namespace blink {
49class WebLayer;
50}
51
52namespace blink {
53
54class ANGLEInstancedArrays;
55class EXTBlendMinMax;
56class EXTFragDepth;
57class EXTShaderTextureLOD;
58class EXTTextureFilterAnisotropic;
59class ExceptionState;
60class HTMLImageElement;
61class HTMLVideoElement;
62class ImageBuffer;
63class ImageData;
64class IntSize;
65class OESElementIndexUint;
66class OESStandardDerivatives;
67class OESTextureFloat;
68class OESTextureFloatLinear;
69class OESTextureHalfFloat;
70class OESTextureHalfFloatLinear;
71class OESVertexArrayObject;
72class WebGLActiveInfo;
73class WebGLBuffer;
74class WebGLCompressedTextureATC;
75class WebGLCompressedTextureETC1;
76class WebGLCompressedTexturePVRTC;
77class WebGLCompressedTextureS3TC;
78class WebGLContextAttributes;
79class WebGLContextGroup;
80class WebGLContextObject;
81class WebGLDebugRendererInfo;
82class WebGLDebugShaders;
83class WebGLDepthTexture;
84class WebGLDrawBuffers;
85class WebGLExtension;
86class WebGLFramebuffer;
87class WebGLLoseContext;
88class WebGLObject;
89class WebGLProgram;
90class WebGLRenderbuffer;
91class WebGLShader;
92class WebGLShaderPrecisionFormat;
93class WebGLSharedObject;
94class WebGLSharedWebGraphicsContext3D;
95class WebGLTexture;
96class WebGLUniformLocation;
97class WebGLVertexArrayObjectOES;
98
99class WebGLRenderingContextLostCallback;
100class WebGLRenderingContextErrorMessageCallback;
101
102class WebGLRenderingContextBase: public CanvasRenderingContext, public ActiveDOMObject, public Page::MultisamplingChangedObserver {
103    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WebGLRenderingContextBase);
104public:
105    virtual ~WebGLRenderingContextBase();
106
107    virtual unsigned version() const = 0;
108    virtual String contextName() const = 0;
109    virtual void registerContextExtensions() = 0;
110
111    static unsigned getWebGLVersion(const CanvasRenderingContext*);
112
113    int drawingBufferWidth() const;
114    int drawingBufferHeight() const;
115
116    void activeTexture(GLenum texture);
117    void attachShader(WebGLProgram*, WebGLShader*);
118    void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
119    void bindBuffer(GLenum target, WebGLBuffer*);
120    void bindFramebuffer(GLenum target, WebGLFramebuffer*);
121    void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
122    void bindTexture(GLenum target, WebGLTexture*);
123    void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
124    void blendEquation(GLenum mode);
125    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
126    void blendFunc(GLenum sfactor, GLenum dfactor);
127    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
128
129    void bufferData(GLenum target, long long size, GLenum usage);
130    void bufferData(GLenum target, ArrayBuffer* data, GLenum usage);
131    void bufferData(GLenum target, ArrayBufferView* data, GLenum usage);
132    void bufferSubData(GLenum target, long long offset, ArrayBuffer* data);
133    void bufferSubData(GLenum target, long long offset, ArrayBufferView* data);
134
135    GLenum checkFramebufferStatus(GLenum target);
136    void clear(GLbitfield mask);
137    void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
138    void clearDepth(GLfloat);
139    void clearStencil(GLint);
140    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
141    void compileShader(WebGLShader*);
142
143    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data);
144    void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data);
145
146    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
147    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
148
149    PassRefPtrWillBeRawPtr<WebGLBuffer> createBuffer();
150    PassRefPtrWillBeRawPtr<WebGLFramebuffer> createFramebuffer();
151    PassRefPtrWillBeRawPtr<WebGLProgram> createProgram();
152    PassRefPtrWillBeRawPtr<WebGLRenderbuffer> createRenderbuffer();
153    PassRefPtrWillBeRawPtr<WebGLShader> createShader(GLenum type);
154    PassRefPtrWillBeRawPtr<WebGLTexture> createTexture();
155
156    void cullFace(GLenum mode);
157
158    void deleteBuffer(WebGLBuffer*);
159    void deleteFramebuffer(WebGLFramebuffer*);
160    void deleteProgram(WebGLProgram*);
161    void deleteRenderbuffer(WebGLRenderbuffer*);
162    void deleteShader(WebGLShader*);
163    void deleteTexture(WebGLTexture*);
164
165    void depthFunc(GLenum);
166    void depthMask(GLboolean);
167    void depthRange(GLfloat zNear, GLfloat zFar);
168    void detachShader(WebGLProgram*, WebGLShader*);
169    void disable(GLenum cap);
170    void disableVertexAttribArray(GLuint index);
171    void drawArrays(GLenum mode, GLint first, GLsizei count);
172    void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
173
174    void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
175    void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount);
176
177    void enable(GLenum cap);
178    void enableVertexAttribArray(GLuint index);
179    void finish();
180    void flush();
181    void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer*);
182    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture*, GLint level);
183    void frontFace(GLenum mode);
184    void generateMipmap(GLenum target);
185
186    PassRefPtrWillBeRawPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GLuint index);
187    PassRefPtrWillBeRawPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GLuint index);
188    bool getAttachedShaders(WebGLProgram*, WillBeHeapVector<RefPtrWillBeMember<WebGLShader> >&);
189    Nullable<WillBeHeapVector<RefPtrWillBeMember<WebGLShader> > > getAttachedShaders(WebGLProgram*);
190    GLint getAttribLocation(WebGLProgram*, const String& name);
191    WebGLGetInfo getBufferParameter(GLenum target, GLenum pname);
192    PassRefPtrWillBeRawPtr<WebGLContextAttributes> getContextAttributes();
193    GLenum getError();
194    PassRefPtrWillBeRawPtr<WebGLExtension> getExtension(const String& name);
195    WebGLGetInfo getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
196    WebGLGetInfo getParameter(GLenum pname);
197    WebGLGetInfo getProgramParameter(WebGLProgram*, GLenum pname);
198    String getProgramInfoLog(WebGLProgram*);
199    WebGLGetInfo getRenderbufferParameter(GLenum target, GLenum pname);
200    WebGLGetInfo getShaderParameter(WebGLShader*, GLenum pname);
201    String getShaderInfoLog(WebGLShader*);
202    PassRefPtrWillBeRawPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType);
203    String getShaderSource(WebGLShader*);
204    Nullable<Vector<String> > getSupportedExtensions();
205    WebGLGetInfo getTexParameter(GLenum target, GLenum pname);
206    WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
207    PassRefPtrWillBeRawPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
208    WebGLGetInfo getVertexAttrib(GLuint index, GLenum pname);
209    long long getVertexAttribOffset(GLuint index, GLenum pname);
210
211    void hint(GLenum target, GLenum mode);
212    GLboolean isBuffer(WebGLBuffer*);
213    bool isContextLost() const;
214    GLboolean isEnabled(GLenum cap);
215    GLboolean isFramebuffer(WebGLFramebuffer*);
216    GLboolean isProgram(WebGLProgram*);
217    GLboolean isRenderbuffer(WebGLRenderbuffer*);
218    GLboolean isShader(WebGLShader*);
219    GLboolean isTexture(WebGLTexture*);
220
221    void lineWidth(GLfloat);
222    void linkProgram(WebGLProgram*);
223    void pixelStorei(GLenum pname, GLint param);
224    void polygonOffset(GLfloat factor, GLfloat units);
225    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels);
226    void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
227    void sampleCoverage(GLfloat value, GLboolean invert);
228    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
229    void shaderSource(WebGLShader*, const String&);
230    void stencilFunc(GLenum func, GLint ref, GLuint mask);
231    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
232    void stencilMask(GLuint);
233    void stencilMaskSeparate(GLenum face, GLuint mask);
234    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
235    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
236
237    void texImage2D(GLenum target, GLint level, GLenum internalformat,
238        GLsizei width, GLsizei height, GLint border,
239        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
240    void texImage2D(GLenum target, GLint level, GLenum internalformat,
241        GLenum format, GLenum type, ImageData*, ExceptionState&);
242    void texImage2D(GLenum target, GLint level, GLenum internalformat,
243        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
244    void texImage2D(GLenum target, GLint level, GLenum internalformat,
245        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
246    void texImage2D(GLenum target, GLint level, GLenum internalformat,
247        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
248
249    void texParameterf(GLenum target, GLenum pname, GLfloat param);
250    void texParameteri(GLenum target, GLenum pname, GLint param);
251
252    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
253        GLsizei width, GLsizei height,
254        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
255    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
256        GLenum format, GLenum type, ImageData*, ExceptionState&);
257    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
258        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
259    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
260        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
261    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
262        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
263
264    void uniform1f(const WebGLUniformLocation*, GLfloat x);
265    void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
266    void uniform1fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
267    void uniform1i(const WebGLUniformLocation*, GLint x);
268    void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
269    void uniform1iv(const WebGLUniformLocation*, GLint* v, GLsizei);
270    void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
271    void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
272    void uniform2fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
273    void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
274    void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
275    void uniform2iv(const WebGLUniformLocation*, GLint* v, GLsizei);
276    void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
277    void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
278    void uniform3fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
279    void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
280    void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
281    void uniform3iv(const WebGLUniformLocation*, GLint* v, GLsizei);
282    void uniform4f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
283    void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
284    void uniform4fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
285    void uniform4i(const WebGLUniformLocation*, GLint x, GLint y, GLint z, GLint w);
286    void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
287    void uniform4iv(const WebGLUniformLocation*, GLint* v, GLsizei);
288    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
289    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
290    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
291    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
292    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
293    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
294
295    void useProgram(WebGLProgram*);
296    void validateProgram(WebGLProgram*);
297
298    void vertexAttrib1f(GLuint index, GLfloat x);
299    void vertexAttrib1fv(GLuint index, Float32Array* values);
300    void vertexAttrib1fv(GLuint index, GLfloat* values, GLsizei);
301    void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
302    void vertexAttrib2fv(GLuint index, Float32Array* values);
303    void vertexAttrib2fv(GLuint index, GLfloat* values, GLsizei);
304    void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
305    void vertexAttrib3fv(GLuint index, Float32Array* values);
306    void vertexAttrib3fv(GLuint index, GLfloat* values, GLsizei);
307    void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
308    void vertexAttrib4fv(GLuint index, Float32Array* values);
309    void vertexAttrib4fv(GLuint index, GLfloat* values, GLsizei);
310    void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
311        GLsizei stride, long long offset);
312
313    void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
314
315    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
316
317    // WEBGL_lose_context support
318    enum LostContextMode {
319        NotLostContext,
320
321        // Lost context occurred at the graphics system level.
322        RealLostContext,
323
324        // Lost context provoked by WEBGL_lose_context.
325        WebGLLoseContextLostContext,
326
327        // Lost context occurred due to internal implementation reasons.
328        SyntheticLostContext,
329    };
330    enum AutoRecoveryMethod {
331        // Don't restore automatically.
332        Manual,
333
334        // Restore when resources are available.
335        WhenAvailable,
336
337        // Restore as soon as possible.
338        Auto
339    };
340    void forceLostContext(LostContextMode, AutoRecoveryMethod);
341    void forceRestoreContext();
342    void loseContextImpl(LostContextMode, AutoRecoveryMethod);
343
344    blink::WebGraphicsContext3D* webContext() const { return drawingBuffer()->context(); }
345    WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
346    Extensions3DUtil* extensionsUtil();
347
348    void reshape(int width, int height);
349
350    void markLayerComposited();
351    PassRefPtrWillBeRawPtr<ImageData> paintRenderingResultsToImageData();
352
353    void removeSharedObject(WebGLSharedObject*);
354    void removeContextObject(WebGLContextObject*);
355
356    unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
357
358    // ActiveDOMObject notifications
359    virtual bool hasPendingActivity() const OVERRIDE;
360    virtual void stop() OVERRIDE;
361
362    void setSavingImage(bool isSaving) { m_savingImage = isSaving; }
363
364    virtual void trace(Visitor*) OVERRIDE;
365
366    class TextureUnitState {
367        ALLOW_ONLY_INLINE_ALLOCATION();
368    public:
369        RefPtrWillBeMember<WebGLTexture> m_texture2DBinding;
370        RefPtrWillBeMember<WebGLTexture> m_textureCubeMapBinding;
371
372        void trace(Visitor*);
373    };
374
375protected:
376    friend class WebGLDrawBuffers;
377    friend class WebGLFramebuffer;
378    friend class WebGLObject;
379    friend class WebGLContextObject;
380    friend class OESVertexArrayObject;
381    friend class WebGLDebugShaders;
382    friend class WebGLCompressedTextureATC;
383    friend class WebGLCompressedTextureETC1;
384    friend class WebGLCompressedTexturePVRTC;
385    friend class WebGLCompressedTextureS3TC;
386    friend class WebGLRenderingContextErrorMessageCallback;
387    friend class WebGLVertexArrayObjectOES;
388    friend class ScopedTexture2DRestorer;
389
390    WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
391    PassRefPtr<DrawingBuffer> createDrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D>);
392    void initializeNewContext();
393    void setupFlags();
394
395#if ENABLE(OILPAN)
396    PassRefPtr<WebGLSharedWebGraphicsContext3D> sharedWebGraphicsContext3D() const;
397#endif
398
399    // CanvasRenderingContext implementation.
400    virtual bool is3d() const OVERRIDE { return true; }
401    virtual bool isAccelerated() const OVERRIDE { return true; }
402    virtual void setIsHidden(bool) OVERRIDE;
403    virtual void paintRenderingResultsToCanvas() OVERRIDE;
404    virtual blink::WebLayer* platformLayer() const OVERRIDE;
405
406    void addSharedObject(WebGLSharedObject*);
407    void addContextObject(WebGLContextObject*);
408    void detachAndRemoveAllObjects();
409
410    void destroyContext();
411    void markContextChanged(ContentChangeType);
412
413    // Query if the GL implementation is NPOT strict.
414    bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
415    // Query if depth_stencil buffer is supported.
416    bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
417
418    // Helper to return the size in bytes of OpenGL data types
419    // like GL_FLOAT, GL_INT, etc.
420    unsigned sizeInBytes(GLenum type);
421
422    // Check if each enabled vertex attribute is bound to a buffer.
423    bool validateRenderingState(const char*);
424
425    bool validateWebGLObject(const char*, WebGLObject*);
426
427    // Adds a compressed texture format.
428    void addCompressedTextureFormat(GLenum);
429    void removeAllCompressedTextureFormats();
430
431    PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, const char* functionName);
432
433    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
434
435    WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
436
437    // Structure for rendering to a DrawingBuffer, instead of directly
438    // to the back-buffer of m_context.
439#if ENABLE(OILPAN)
440    RefPtr<WebGLSharedWebGraphicsContext3D> m_sharedWebGraphicsContext3D;
441#else
442    RefPtr<DrawingBuffer> m_drawingBuffer;
443#endif
444    DrawingBuffer* drawingBuffer() const;
445
446    RefPtr<WebGLContextGroup> m_contextGroup;
447
448    LostContextMode m_contextLostMode;
449    AutoRecoveryMethod m_autoRecoveryMethod;
450    // Dispatches a context lost event once it is determined that one is needed.
451    // This is used for synthetic, WEBGL_lose_context and real context losses. For real ones, it's
452    // likely that there's no JavaScript on the stack, but that might be dependent
453    // on how exactly the platform discovers that the context was lost. For better
454    // portability we always defer the dispatch of the event.
455    Timer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
456    bool m_restoreAllowed;
457    Timer<WebGLRenderingContextBase> m_restoreTimer;
458
459    bool m_needsUpdate;
460    bool m_markedCanvasDirty;
461    WillBeHeapHashSet<RawPtrWillBeWeakMember<WebGLContextObject> > m_contextObjects;
462
463    OwnPtrWillBeMember<WebGLRenderingContextLostCallback> m_contextLostCallbackAdapter;
464    OwnPtrWillBeMember<WebGLRenderingContextErrorMessageCallback> m_errorMessageCallbackAdapter;
465
466    // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
467    RefPtrWillBeMember<WebGLBuffer> m_boundArrayBuffer;
468
469    RefPtrWillBeMember<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
470    RefPtrWillBeMember<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
471    void setBoundVertexArrayObject(PassRefPtrWillBeRawPtr<WebGLVertexArrayObjectOES> arrayObject)
472    {
473        if (arrayObject)
474            m_boundVertexArrayObject = arrayObject;
475        else
476            m_boundVertexArrayObject = m_defaultVertexArrayObject;
477    }
478
479    class VertexAttribValue {
480    public:
481        VertexAttribValue()
482        {
483            initValue();
484        }
485
486        void initValue()
487        {
488            value[0] = 0.0f;
489            value[1] = 0.0f;
490            value[2] = 0.0f;
491            value[3] = 1.0f;
492        }
493
494        GLfloat value[4];
495    };
496    Vector<VertexAttribValue> m_vertexAttribValue;
497    unsigned m_maxVertexAttribs;
498    RefPtrWillBeMember<WebGLBuffer> m_vertexAttrib0Buffer;
499    long m_vertexAttrib0BufferSize;
500    GLfloat m_vertexAttrib0BufferValue[4];
501    bool m_forceAttrib0BufferRefill;
502    bool m_vertexAttrib0UsedBefore;
503
504    RefPtrWillBeMember<WebGLProgram> m_currentProgram;
505    RefPtrWillBeMember<WebGLFramebuffer> m_framebufferBinding;
506    RefPtrWillBeMember<WebGLRenderbuffer> m_renderbufferBinding;
507
508    WillBeHeapVector<TextureUnitState> m_textureUnits;
509    unsigned long m_activeTextureUnit;
510
511    RefPtrWillBeMember<WebGLTexture> m_blackTexture2D;
512    RefPtrWillBeMember<WebGLTexture> m_blackTextureCubeMap;
513
514    Vector<GLenum> m_compressedTextureFormats;
515
516    // Fixed-size cache of reusable image buffers for video texImage2D calls.
517    class LRUImageBufferCache {
518    public:
519        LRUImageBufferCache(int capacity);
520        // The pointer returned is owned by the image buffer map.
521        ImageBuffer* imageBuffer(const IntSize& size);
522    private:
523        void bubbleToFront(int idx);
524        OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
525        int m_capacity;
526    };
527    LRUImageBufferCache m_generatedImageCache;
528
529    GLint m_maxTextureSize;
530    GLint m_maxCubeMapTextureSize;
531    GLint m_maxRenderbufferSize;
532    GLint m_maxViewportDims[2];
533    GLint m_maxTextureLevel;
534    GLint m_maxCubeMapTextureLevel;
535
536    GLint m_maxDrawBuffers;
537    GLint m_maxColorAttachments;
538    GLenum m_backDrawBuffer;
539    bool m_drawBuffersWebGLRequirementsChecked;
540    bool m_drawBuffersSupported;
541
542    GLint m_packAlignment;
543    GLint m_unpackAlignment;
544    bool m_unpackFlipY;
545    bool m_unpackPremultiplyAlpha;
546    GLenum m_unpackColorspaceConversion;
547    RefPtrWillBeMember<WebGLContextAttributes> m_requestedAttributes;
548
549    bool m_layerCleared;
550    GLfloat m_clearColor[4];
551    bool m_scissorEnabled;
552    GLfloat m_clearDepth;
553    GLint m_clearStencil;
554    GLboolean m_colorMask[4];
555    GLboolean m_depthMask;
556
557    bool m_stencilEnabled;
558    GLuint m_stencilMask, m_stencilMaskBack;
559    GLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
560    GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
561
562    bool m_isGLES2NPOTStrict;
563    bool m_isDepthStencilSupported;
564
565    bool m_synthesizedErrorsToConsole;
566    int m_numGLErrorsToConsoleAllowed;
567
568    bool m_multisamplingAllowed;
569    bool m_multisamplingObserverRegistered;
570
571    unsigned long m_onePlusMaxNonDefaultTextureUnit;
572
573    OwnPtr<Extensions3DUtil> m_extensionsUtil;
574
575    bool m_savingImage;
576
577    enum ExtensionFlags {
578        ApprovedExtension               = 0x00,
579        // Extension that is behind the draft extensions runtime flag:
580        DraftExtension                  = 0x01,
581    };
582
583    class ExtensionTracker : public NoBaseWillBeGarbageCollected<ExtensionTracker> {
584    public:
585        ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
586            : m_draft(flags & DraftExtension)
587            , m_prefixes(prefixes)
588        {
589        }
590
591#if !ENABLE(OILPAN)
592        virtual ~ExtensionTracker()
593        {
594        }
595#endif
596
597        bool draft() const
598        {
599            return m_draft;
600        }
601
602        const char* const* prefixes() const;
603        bool matchesNameWithPrefixes(const String&) const;
604
605        virtual PassRefPtrWillBeRawPtr<WebGLExtension> getExtension(WebGLRenderingContextBase*) = 0;
606        virtual bool supported(WebGLRenderingContextBase*) const = 0;
607        virtual const char* extensionName() const = 0;
608        virtual void loseExtension() = 0;
609
610        virtual void trace(Visitor*) { }
611
612    private:
613        bool m_draft;
614        const char* const* m_prefixes;
615    };
616
617    template <typename T>
618    class TypedExtensionTracker FINAL : public ExtensionTracker {
619    public:
620        static PassOwnPtrWillBeRawPtr<TypedExtensionTracker<T> > create(RefPtrWillBeMember<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
621        {
622            return adoptPtrWillBeNoop(new TypedExtensionTracker<T>(extensionField, flags, prefixes));
623        }
624
625#if !ENABLE(OILPAN)
626        virtual ~TypedExtensionTracker()
627        {
628            if (m_extension) {
629                m_extension->lose(true);
630                m_extension = nullptr;
631            }
632        }
633#endif
634
635        virtual PassRefPtrWillBeRawPtr<WebGLExtension> getExtension(WebGLRenderingContextBase* context) OVERRIDE
636        {
637            if (!m_extension) {
638                m_extension = T::create(context);
639                m_extensionField = m_extension;
640            }
641
642            return m_extension;
643        }
644
645        virtual bool supported(WebGLRenderingContextBase* context) const OVERRIDE
646        {
647            return T::supported(context);
648        }
649
650        virtual const char* extensionName() const OVERRIDE
651        {
652            return T::extensionName();
653        }
654
655        virtual void loseExtension() OVERRIDE
656        {
657            if (m_extension) {
658                m_extension->lose(false);
659                if (m_extension->isLost())
660                    m_extension = nullptr;
661            }
662        }
663
664        virtual void trace(Visitor* visitor) OVERRIDE
665        {
666            visitor->trace(m_extension);
667            ExtensionTracker::trace(visitor);
668        }
669
670    private:
671        TypedExtensionTracker(RefPtrWillBeMember<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
672            : ExtensionTracker(flags, prefixes)
673            , m_extensionField(extensionField)
674        {
675        }
676
677        RefPtrWillBeMember<T>& m_extensionField;
678        // ExtensionTracker holds it's own reference to the extension to ensure
679        // that it is not deleted before this object's destructor is called
680        RefPtrWillBeMember<T> m_extension;
681    };
682
683    bool m_extensionEnabled[WebGLExtensionNameCount];
684    WillBeHeapVector<OwnPtrWillBeMember<ExtensionTracker> > m_extensions;
685
686    template <typename T>
687    void registerExtension(RefPtrWillBeMember<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
688    {
689        m_extensions.append(TypedExtensionTracker<T>::create(extensionPtr, flags, prefixes));
690    }
691
692    bool extensionSupportedAndAllowed(const ExtensionTracker*);
693
694    inline bool extensionEnabled(WebGLExtensionName name)
695    {
696        return m_extensionEnabled[name];
697    }
698
699    // Errors raised by synthesizeGLError() while the context is lost.
700    Vector<GLenum> m_lostContextErrors;
701
702    // Helpers for getParameter and others
703    WebGLGetInfo getBooleanParameter(GLenum);
704    WebGLGetInfo getBooleanArrayParameter(GLenum);
705    WebGLGetInfo getFloatParameter(GLenum);
706    WebGLGetInfo getIntParameter(GLenum);
707    WebGLGetInfo getUnsignedIntParameter(GLenum);
708    WebGLGetInfo getWebGLFloatArrayParameter(GLenum);
709    WebGLGetInfo getWebGLIntArrayParameter(GLenum);
710
711    // Clear the backbuffer if it was composited since the last operation.
712    // clearMask is set to the bitfield of any clear that would happen anyway at this time
713    // and the function returns true if that clear is now unnecessary.
714    bool clearIfComposited(GLbitfield clearMask = 0);
715
716    // Helper to restore state that clearing the framebuffer may destroy.
717    void restoreStateAfterClear();
718
719    // Convert texture internal format.
720    GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
721
722    void texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState&);
723    void texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
724    void texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState&);
725    void texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
726
727    void handleTextureCompleteness(const char*, bool);
728    void createFallbackBlackTextures1x1();
729
730    // Helper function for copyTex{Sub}Image, check whether the internalformat
731    // and the color buffer format of the current bound framebuffer combination
732    // is valid.
733    bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
734
735    // Helper function to get the bound framebuffer's color buffer format.
736    GLenum boundFramebufferColorFormat();
737
738    // Helper function to verify limits on the length of uniform and attribute locations.
739    bool validateLocationLength(const char* functionName, const String&);
740
741    // Helper function to check if size is non-negative.
742    // Generate GL error and return false for negative inputs; otherwise, return true.
743    bool validateSize(const char* functionName, GLint x, GLint y);
744
745    // Helper function to check if all characters in the string belong to the
746    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
747    bool validateString(const char* functionName, const String&);
748
749    // Helper function to check target and texture bound to the target.
750    // Generate GL errors and return 0 if target is invalid or texture bound is
751    // null.  Otherwise, return the texture bound to the target.
752    WebGLTexture* validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap);
753
754    // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
755    // Generates GL error and returns false if parameters are invalid.
756    bool validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level);
757
758    // Helper function to check input level for functions {copy}Tex{Sub}Image.
759    // Generates GL error and returns false if level is invalid.
760    bool validateTexFuncLevel(const char* functionName, GLenum target, GLint level);
761
762    // Helper function to check if a 64-bit value is non-negative and can fit into a 32-bit integer.
763    // Generates GL error and returns false if not.
764    bool validateValueFitNonNegInt32(const char* functionName, const char* paramName, long long value);
765
766    enum TexFuncValidationFunctionType {
767        NotTexSubImage2D,
768        TexSubImage2D,
769    };
770
771    enum TexFuncValidationSourceType {
772        SourceArrayBufferView,
773        SourceImageData,
774        SourceHTMLImageElement,
775        SourceHTMLCanvasElement,
776        SourceHTMLVideoElement,
777    };
778
779    // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
780    // Otherwise, it would return quickly without doing other work.
781    bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width,
782        GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset);
783
784    // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
785    // Generates GL error and returns false if width or height is invalid.
786    bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height);
787
788    // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
789    // Generates GL error and returns false if parameters are invalid.
790    bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
791
792    enum NullDisposition {
793        NullAllowed,
794        NullNotAllowed
795    };
796
797    // Helper function to validate that the given ArrayBufferView
798    // is of the correct type and contains enough data for the texImage call.
799    // Generates GL error and returns false if parameters are invalid.
800    bool validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition);
801
802    // Helper function to validate a given texture format is settable as in
803    // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
804    // copyTexSubImage2D.
805    // Generates GL error and returns false if the format is not settable.
806    bool validateSettableTexFormat(const char* functionName, GLenum format);
807
808    // Helper function to validate compressed texture data is correct size
809    // for the given format and dimensions.
810    bool validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels);
811
812    // Helper function for validating compressed texture formats.
813    bool validateCompressedTexFormat(GLenum format);
814
815    // Helper function to validate compressed texture dimensions are valid for
816    // the given format.
817    bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
818
819    // Helper function to validate compressed texture dimensions are valid for
820    // the given format.
821    bool validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture*);
822
823    // Helper function to validate mode for draw{Arrays/Elements}.
824    bool validateDrawMode(const char* functionName, GLenum);
825
826    // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
827    bool validateStencilSettings(const char* functionName);
828
829    // Helper function to validate stencil or depth func.
830    bool validateStencilOrDepthFunc(const char* functionName, GLenum);
831
832    // Helper function for texParameterf and texParameteri.
833    void texParameter(GLenum target, GLenum pname, GLfloat parami, GLint paramf, bool isFloat);
834
835    // Helper function to print GL errors to console.
836    void printGLErrorToConsole(const String&);
837
838    // Helper function to print warnings to console. Currently
839    // used only to warn about use of obsolete functions.
840    void printWarningToConsole(const String&);
841
842    // Helper function to validate input parameters for framebuffer functions.
843    // Generate GL error if parameters are illegal.
844    bool validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment);
845
846    // Helper function to validate blend equation mode.
847    bool validateBlendEquation(const char* functionName, GLenum);
848
849    // Helper function to validate blend func factors.
850    bool validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst);
851
852    // Helper function to validate a GL capability.
853    bool validateCapability(const char* functionName, GLenum);
854
855    // Helper function to validate input parameters for uniform functions.
856    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GLsizei mod);
857    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GLsizei mod);
858    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GLsizei, GLsizei mod);
859    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, Float32Array*, GLsizei mod);
860    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, void*, GLsizei, GLsizei mod);
861
862    // Helper function to validate the target for bufferData.
863    // Return the current bound buffer to target, or 0 if the target is invalid.
864    WebGLBuffer* validateBufferDataTarget(const char* functionName, GLenum target);
865
866    // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
867    bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
868
869    // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
870    bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
871
872    // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
873    bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
874
875    // Helper function to validate drawArrays(Instanced) calls
876    bool validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count);
877
878    // Helper function to validate drawElements(Instanced) calls
879    bool validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset);
880
881    // Helper function to validate draw*Instanced calls
882    bool validateDrawInstanced(const char* functionName, GLsizei primcount);
883
884    // Helper functions for vertexAttribNf{v}.
885    void vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat, GLfloat, GLfloat, GLfloat);
886    void vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array*, GLsizei expectedSize);
887    void vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat*, GLsizei, GLsizei expectedSize);
888
889    // Helper functions to bufferData() and bufferSubData().
890    void bufferDataImpl(GLenum target, long long size, const void* data, GLenum usage);
891    void bufferSubDataImpl(GLenum target, long long offset, GLsizeiptr size, const void* data);
892
893    // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
894    // Return false if caller should return without further processing.
895    bool deleteObject(WebGLObject*);
896
897    // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
898    // If the object has already been deleted, set deleted to true upon return.
899    // Return false if caller should return without further processing.
900    bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
901
902    void dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*);
903    // Helper for restoration after context lost.
904    void maybeRestoreContext(Timer<WebGLRenderingContextBase>*);
905
906    enum ConsoleDisplayPreference {
907        DisplayInConsole,
908        DontDisplayInConsole
909    };
910
911    // Wrapper for WebGraphicsContext3D::synthesizeGLError that sends a message
912    // to the JavaScript console.
913    void synthesizeGLError(GLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
914    void emitGLWarning(const char* function, const char* reason);
915
916    String ensureNotNull(const String&) const;
917
918    // Enable or disable stencil test based on user setting and
919    // whether the current FBO has a stencil buffer.
920    void applyStencilTest();
921
922    // Helper for enabling or disabling a capability.
923    void enableOrDisable(GLenum capability, bool enable);
924
925    // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
926    IntSize clampedCanvasSize();
927
928    // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
929    // Later, return the cached value.
930    GLint maxDrawBuffers();
931    GLint maxColorAttachments();
932
933    void setBackDrawBuffer(GLenum);
934
935    void restoreCurrentFramebuffer();
936    void restoreCurrentTexture2D();
937
938    virtual void multisamplingChanged(bool) OVERRIDE;
939
940    void findNewMaxNonDefaultTextureUnit();
941
942    friend class WebGLStateRestorer;
943    friend class WebGLRenderingContextEvictionManager;
944
945    static Vector<WebGLRenderingContextBase*>& activeContexts();
946    static Vector<WebGLRenderingContextBase*>& forciblyEvictedContexts();
947
948    static void activateContext(WebGLRenderingContextBase*);
949    static void deactivateContext(WebGLRenderingContextBase*);
950    static void addToEvictedList(WebGLRenderingContextBase*);
951    static void removeFromEvictedList(WebGLRenderingContextBase*);
952    static void willDestroyContext(WebGLRenderingContextBase*);
953    static void forciblyLoseOldestContext(const String& reason);
954    // Return the least recently used context's position in the active context vector.
955    // If the vector is empty, return the maximum allowed active context number.
956    static size_t oldestContextIndex();
957    static IntSize oldestContextSize();
958};
959
960DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context, context->is3d(), context.is3d());
961
962} // namespace blink
963
964WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::WebGLRenderingContextBase::TextureUnitState);
965
966#endif // WebGLRenderingContextBase_h
967