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