| /* |
| * Copyright (C) 2009 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef WebGLRenderingContextBase_h |
| #define WebGLRenderingContextBase_h |
| |
| #include <memory> |
| #include <set> |
| #include "bindings/core/v8/Nullable.h" |
| #include "bindings/core/v8/ScriptValue.h" |
| #include "core/CoreExport.h" |
| #include "core/html/canvas/CanvasContextCreationAttributes.h" |
| #include "core/html/canvas/CanvasRenderingContext.h" |
| #include "core/layout/ContentChangeType.h" |
| #include "core/typed_arrays/ArrayBufferViewHelpers.h" |
| #include "core/typed_arrays/DOMTypedArray.h" |
| #include "core/typed_arrays/TypedFlexibleArrayBufferView.h" |
| #include "modules/webgl/WebGLContextAttributes.h" |
| #include "modules/webgl/WebGLExtensionName.h" |
| #include "modules/webgl/WebGLTexture.h" |
| #include "modules/webgl/WebGLVertexArrayObjectBase.h" |
| #include "platform/Timer.h" |
| #include "platform/bindings/ScriptState.h" |
| #include "platform/bindings/ScriptWrappable.h" |
| #include "platform/bindings/ScriptWrappableVisitor.h" |
| #include "platform/graphics/gpu/DrawingBuffer.h" |
| #include "platform/graphics/gpu/Extensions3DUtil.h" |
| #include "platform/graphics/gpu/WebGLImageConversion.h" |
| #include "platform/wtf/CheckedNumeric.h" |
| #include "platform/wtf/text/WTFString.h" |
| #include "public/platform/Platform.h" |
| #include "public/platform/WebGraphicsContext3DProvider.h" |
| #include "third_party/khronos/GLES2/gl2.h" |
| |
| namespace blink { |
| class WebLayer; |
| } |
| |
| namespace gpu { |
| namespace gles2 { |
| class GLES2Interface; |
| } |
| } |
| |
| namespace blink { |
| |
| class CanvasResourceProvider; |
| class EXTDisjointTimerQuery; |
| class EXTDisjointTimerQueryWebGL2; |
| class ExceptionState; |
| class HTMLCanvasElementOrOffscreenCanvas; |
| class HTMLImageElement; |
| class HTMLVideoElement; |
| class ImageBitmap; |
| class ImageData; |
| class IntSize; |
| class OESVertexArrayObject; |
| class WebGLActiveInfo; |
| class WebGLBuffer; |
| class WebGLCompressedTextureASTC; |
| class WebGLCompressedTextureATC; |
| class WebGLCompressedTextureETC; |
| class WebGLCompressedTextureETC1; |
| class WebGLCompressedTexturePVRTC; |
| class WebGLCompressedTextureS3TC; |
| class WebGLCompressedTextureS3TCsRGB; |
| class WebGLContextGroup; |
| class WebGLContextObject; |
| class WebGLDebugShaders; |
| class WebGLDrawBuffers; |
| class WebGLExtension; |
| class WebGLFramebuffer; |
| class WebGLObject; |
| class WebGLProgram; |
| class WebGLRenderbuffer; |
| class WebGLShader; |
| class WebGLShaderPrecisionFormat; |
| class WebGLUniformLocation; |
| class WebGLVertexArrayObjectBase; |
| |
| class WebGLRenderingContextErrorMessageCallback; |
| |
| // This class uses the color mask to prevent drawing to the alpha channel, if |
| // the DrawingBuffer requires RGB emulation. |
| class ScopedRGBEmulationColorMask { |
| STACK_ALLOCATED(); |
| |
| public: |
| ScopedRGBEmulationColorMask(WebGLRenderingContextBase*, |
| GLboolean* color_mask, |
| DrawingBuffer*); |
| ~ScopedRGBEmulationColorMask(); |
| |
| private: |
| Member<WebGLRenderingContextBase> context_; |
| GLboolean color_mask_[4]; |
| const bool requires_emulation_; |
| }; |
| |
| class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, |
| public DrawingBuffer::Client { |
| WTF_MAKE_NONCOPYABLE(WebGLRenderingContextBase); |
| |
| public: |
| ~WebGLRenderingContextBase() override; |
| |
| HTMLCanvasElement* canvas() const { |
| if (Host()->IsOffscreenCanvas()) |
| return nullptr; |
| return static_cast<HTMLCanvasElement*>(Host()); |
| } |
| |
| virtual String ContextName() const = 0; |
| virtual void RegisterContextExtensions() = 0; |
| |
| virtual void InitializeNewContext(); |
| |
| static unsigned GetWebGLVersion(const CanvasRenderingContext*); |
| |
| static std::unique_ptr<WebGraphicsContext3DProvider> |
| CreateWebGraphicsContext3DProvider(CanvasRenderingContextHost*, |
| const CanvasContextCreationAttributes&, |
| unsigned web_gl_version, |
| bool* using_gpu_compositing); |
| static void ForceNextWebGLContextCreationToFail(); |
| |
| unsigned Version() const { return version_; } |
| |
| int drawingBufferWidth() const; |
| int drawingBufferHeight() const; |
| |
| void activeTexture(GLenum texture); |
| void attachShader(WebGLProgram*, WebGLShader*); |
| void bindAttribLocation(WebGLProgram*, GLuint index, const String& name); |
| void bindBuffer(GLenum target, WebGLBuffer*); |
| virtual void bindFramebuffer(GLenum target, WebGLFramebuffer*); |
| void bindRenderbuffer(GLenum target, WebGLRenderbuffer*); |
| void bindTexture(GLenum target, WebGLTexture*); |
| void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); |
| void blendEquation(GLenum mode); |
| void blendEquationSeparate(GLenum mode_rgb, GLenum mode_alpha); |
| void blendFunc(GLenum sfactor, GLenum dfactor); |
| void blendFuncSeparate(GLenum src_rgb, |
| GLenum dst_rgb, |
| GLenum src_alpha, |
| GLenum dst_alpha); |
| |
| void bufferData(GLenum target, long long size, GLenum usage); |
| void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage); |
| void bufferData(GLenum target, |
| MaybeShared<DOMArrayBufferView> data, |
| GLenum usage); |
| void bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data); |
| void bufferSubData(GLenum target, |
| long long offset, |
| const FlexibleArrayBufferView& data); |
| |
| GLenum checkFramebufferStatus(GLenum target); |
| void clear(GLbitfield mask); |
| void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); |
| void clearDepth(GLfloat); |
| void clearStencil(GLint); |
| void colorMask(GLboolean red, |
| GLboolean green, |
| GLboolean blue, |
| GLboolean alpha); |
| void compileShader(WebGLShader*); |
| |
| void compressedTexImage2D(GLenum target, |
| GLint level, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height, |
| GLint border, |
| MaybeShared<DOMArrayBufferView> data); |
| void compressedTexSubImage2D(GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLsizei width, |
| GLsizei height, |
| GLenum format, |
| MaybeShared<DOMArrayBufferView> data); |
| |
| void copyTexImage2D(GLenum target, |
| GLint level, |
| GLenum internalformat, |
| GLint x, |
| GLint y, |
| GLsizei width, |
| GLsizei height, |
| GLint border); |
| void copyTexSubImage2D(GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLint x, |
| GLint y, |
| GLsizei width, |
| GLsizei height); |
| |
| WebGLBuffer* createBuffer(); |
| WebGLFramebuffer* createFramebuffer(); |
| WebGLProgram* createProgram(); |
| WebGLRenderbuffer* createRenderbuffer(); |
| WebGLShader* createShader(GLenum type); |
| WebGLTexture* createTexture(); |
| |
| void cullFace(GLenum mode); |
| |
| void deleteBuffer(WebGLBuffer*); |
| virtual void deleteFramebuffer(WebGLFramebuffer*); |
| void deleteProgram(WebGLProgram*); |
| void deleteRenderbuffer(WebGLRenderbuffer*); |
| void deleteShader(WebGLShader*); |
| void deleteTexture(WebGLTexture*); |
| |
| void depthFunc(GLenum); |
| void depthMask(GLboolean); |
| void depthRange(GLfloat z_near, GLfloat z_far); |
| void detachShader(WebGLProgram*, WebGLShader*); |
| void disable(GLenum cap); |
| void disableVertexAttribArray(GLuint index); |
| void drawArrays(GLenum mode, GLint first, GLsizei count); |
| void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset); |
| |
| void DrawArraysInstancedANGLE(GLenum mode, |
| GLint first, |
| GLsizei count, |
| GLsizei primcount); |
| void DrawElementsInstancedANGLE(GLenum mode, |
| GLsizei count, |
| GLenum type, |
| long long offset, |
| GLsizei primcount); |
| |
| void enable(GLenum cap); |
| void enableVertexAttribArray(GLuint index); |
| void finish(); |
| void flush(); |
| void framebufferRenderbuffer(GLenum target, |
| GLenum attachment, |
| GLenum renderbuffertarget, |
| WebGLRenderbuffer*); |
| void framebufferTexture2D(GLenum target, |
| GLenum attachment, |
| GLenum textarget, |
| WebGLTexture*, |
| GLint level); |
| void frontFace(GLenum mode); |
| void generateMipmap(GLenum target); |
| |
| WebGLActiveInfo* getActiveAttrib(WebGLProgram*, GLuint index); |
| WebGLActiveInfo* getActiveUniform(WebGLProgram*, GLuint index); |
| bool getAttachedShaders(WebGLProgram*, HeapVector<Member<WebGLShader>>&); |
| Nullable<HeapVector<Member<WebGLShader>>> getAttachedShaders(WebGLProgram*); |
| GLint getAttribLocation(WebGLProgram*, const String& name); |
| ScriptValue getBufferParameter(ScriptState*, GLenum target, GLenum pname); |
| void getContextAttributes(Nullable<WebGLContextAttributes>&); |
| GLenum getError(); |
| ScriptValue getExtension(ScriptState*, const String& name); |
| virtual ScriptValue getFramebufferAttachmentParameter(ScriptState*, |
| GLenum target, |
| GLenum attachment, |
| GLenum pname); |
| virtual ScriptValue getParameter(ScriptState*, GLenum pname); |
| ScriptValue getProgramParameter(ScriptState*, WebGLProgram*, GLenum pname); |
| String getProgramInfoLog(WebGLProgram*); |
| ScriptValue getRenderbufferParameter(ScriptState*, |
| GLenum target, |
| GLenum pname); |
| ScriptValue getShaderParameter(ScriptState*, WebGLShader*, GLenum pname); |
| String getShaderInfoLog(WebGLShader*); |
| WebGLShaderPrecisionFormat* getShaderPrecisionFormat(GLenum shader_type, |
| GLenum precision_type); |
| String getShaderSource(WebGLShader*); |
| Nullable<Vector<String>> getSupportedExtensions(); |
| virtual ScriptValue getTexParameter(ScriptState*, |
| GLenum target, |
| GLenum pname); |
| ScriptValue getUniform(ScriptState*, |
| WebGLProgram*, |
| const WebGLUniformLocation*); |
| WebGLUniformLocation* getUniformLocation(WebGLProgram*, const String&); |
| ScriptValue getVertexAttrib(ScriptState*, GLuint index, GLenum pname); |
| long long getVertexAttribOffset(GLuint index, GLenum pname); |
| |
| void hint(GLenum target, GLenum mode); |
| GLboolean isBuffer(WebGLBuffer*); |
| bool isContextLost() const override; |
| GLboolean isEnabled(GLenum cap); |
| GLboolean isFramebuffer(WebGLFramebuffer*); |
| GLboolean isProgram(WebGLProgram*); |
| GLboolean isRenderbuffer(WebGLRenderbuffer*); |
| GLboolean isShader(WebGLShader*); |
| GLboolean isTexture(WebGLTexture*); |
| |
| void lineWidth(GLfloat); |
| void linkProgram(WebGLProgram*); |
| virtual void pixelStorei(GLenum pname, GLint param); |
| void polygonOffset(GLfloat factor, GLfloat units); |
| virtual void readPixels(GLint x, |
| GLint y, |
| GLsizei width, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| MaybeShared<DOMArrayBufferView> pixels); |
| void renderbufferStorage(GLenum target, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height); |
| void sampleCoverage(GLfloat value, GLboolean invert); |
| void scissor(GLint x, GLint y, GLsizei width, GLsizei height); |
| void shaderSource(WebGLShader*, const String&); |
| void stencilFunc(GLenum func, GLint ref, GLuint mask); |
| void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); |
| void stencilMask(GLuint); |
| void stencilMaskSeparate(GLenum face, GLuint mask); |
| void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); |
| void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); |
| |
| void texImage2D(GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLsizei width, |
| GLsizei height, |
| GLint border, |
| GLenum format, |
| GLenum type, |
| MaybeShared<DOMArrayBufferView>); |
| void texImage2D(GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLenum format, |
| GLenum type, |
| ImageData*); |
| void texImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLenum format, |
| GLenum type, |
| HTMLImageElement*, |
| ExceptionState&); |
| void texImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLenum format, |
| GLenum type, |
| HTMLCanvasElement*, |
| ExceptionState&); |
| void texImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLenum format, |
| GLenum type, |
| HTMLVideoElement*, |
| ExceptionState&); |
| void texImage2D(GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLenum format, |
| GLenum type, |
| ImageBitmap*, |
| ExceptionState&); |
| |
| void texParameterf(GLenum target, GLenum pname, GLfloat param); |
| void texParameteri(GLenum target, GLenum pname, GLint param); |
| |
| void texSubImage2D(GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLsizei width, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| MaybeShared<DOMArrayBufferView>); |
| void texSubImage2D(GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLenum format, |
| GLenum type, |
| ImageData*); |
| void texSubImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLenum format, |
| GLenum type, |
| HTMLImageElement*, |
| ExceptionState&); |
| void texSubImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLenum format, |
| GLenum type, |
| HTMLCanvasElement*, |
| ExceptionState&); |
| void texSubImage2D(ExecutionContext*, |
| GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLenum format, |
| GLenum type, |
| HTMLVideoElement*, |
| ExceptionState&); |
| void texSubImage2D(GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLenum format, |
| GLenum type, |
| ImageBitmap*, |
| ExceptionState&); |
| |
| void uniform1f(const WebGLUniformLocation*, GLfloat x); |
| void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&); |
| void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&); |
| void uniform1i(const WebGLUniformLocation*, GLint x); |
| void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&); |
| void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&); |
| void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y); |
| void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&); |
| void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&); |
| void uniform2i(const WebGLUniformLocation*, GLint x, GLint y); |
| void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&); |
| void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&); |
| void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z); |
| void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&); |
| void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&); |
| void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z); |
| void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&); |
| void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&); |
| void uniform4f(const WebGLUniformLocation*, |
| GLfloat x, |
| GLfloat y, |
| GLfloat z, |
| GLfloat w); |
| void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&); |
| void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&); |
| void uniform4i(const WebGLUniformLocation*, |
| GLint x, |
| GLint y, |
| GLint z, |
| GLint w); |
| void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&); |
| void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&); |
| void uniformMatrix2fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| MaybeShared<DOMFloat32Array> value); |
| void uniformMatrix2fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| Vector<GLfloat>& value); |
| void uniformMatrix3fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| MaybeShared<DOMFloat32Array> value); |
| void uniformMatrix3fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| Vector<GLfloat>& value); |
| void uniformMatrix4fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| MaybeShared<DOMFloat32Array> value); |
| void uniformMatrix4fv(const WebGLUniformLocation*, |
| GLboolean transpose, |
| Vector<GLfloat>& value); |
| |
| void useProgram(WebGLProgram*); |
| void validateProgram(WebGLProgram*); |
| |
| void vertexAttrib1f(GLuint index, GLfloat x); |
| void vertexAttrib1fv(GLuint index, MaybeShared<const DOMFloat32Array> values); |
| void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values); |
| void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y); |
| void vertexAttrib2fv(GLuint index, MaybeShared<const DOMFloat32Array> values); |
| void vertexAttrib2fv(GLuint index, const Vector<GLfloat>& values); |
| void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z); |
| void vertexAttrib3fv(GLuint index, MaybeShared<const DOMFloat32Array> values); |
| void vertexAttrib3fv(GLuint index, const Vector<GLfloat>& values); |
| void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); |
| void vertexAttrib4fv(GLuint index, MaybeShared<const DOMFloat32Array> values); |
| void vertexAttrib4fv(GLuint index, const Vector<GLfloat>& values); |
| void vertexAttribPointer(GLuint index, |
| GLint size, |
| GLenum type, |
| GLboolean normalized, |
| GLsizei stride, |
| long long offset); |
| |
| void VertexAttribDivisorANGLE(GLuint index, GLuint divisor); |
| |
| void viewport(GLint x, GLint y, GLsizei width, GLsizei height); |
| |
| // WEBGL_lose_context support |
| enum AutoRecoveryMethod { |
| // Don't restore automatically. |
| kManual, |
| |
| // Restore when resources are available. |
| kWhenAvailable, |
| |
| // Restore as soon as possible, but only when |
| // the canvas is visible. |
| kAuto |
| }; |
| void LoseContext(LostContextMode) override; |
| void ForceLostContext(LostContextMode, AutoRecoveryMethod); |
| void ForceRestoreContext(); |
| void LoseContextImpl(LostContextMode, AutoRecoveryMethod); |
| uint32_t NumberOfContextLosses() const; |
| |
| // Utilities to restore GL state to match the rendering context's |
| // saved state. Use these after contextGL()-based state changes that |
| // bypass the rendering context. |
| void RestoreScissorEnabled(); |
| void RestoreScissorBox(); |
| void RestoreClearColor(); |
| void RestoreColorMask(); |
| |
| gpu::gles2::GLES2Interface* ContextGL() const { |
| DrawingBuffer* d = GetDrawingBuffer(); |
| if (!d) |
| return nullptr; |
| return d->ContextGL(); |
| } |
| WebGLContextGroup* ContextGroup() const { return context_group_.Get(); } |
| Extensions3DUtil* ExtensionsUtil(); |
| |
| void Reshape(int width, int height) override; |
| |
| void MarkLayerComposited() override; |
| |
| scoped_refptr<Uint8Array> PaintRenderingResultsToDataArray( |
| SourceDrawingBuffer) override; |
| |
| unsigned MaxVertexAttribs() const { return max_vertex_attribs_; } |
| |
| virtual void Trace(blink::Visitor*); |
| |
| virtual void TraceWrappers(const ScriptWrappableVisitor*) const; |
| |
| // Returns approximate gpu memory allocated per pixel. |
| int ExternallyAllocatedBufferCountPerPixel() override; |
| |
| // Returns the drawing buffer size after it is, probably, has scaled down |
| // to the maximum supported canvas size. |
| IntSize DrawingBufferSize() const override; |
| DrawingBuffer* GetDrawingBuffer() const; |
| |
| class TextureUnitState { |
| DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| |
| public: |
| TraceWrapperMember<WebGLTexture> texture2d_binding_; |
| TraceWrapperMember<WebGLTexture> texture_cube_map_binding_; |
| TraceWrapperMember<WebGLTexture> texture3d_binding_; |
| TraceWrapperMember<WebGLTexture> texture2d_array_binding_; |
| |
| void Trace(blink::Visitor*); |
| // Wrappers are traced by parent since TextureUnitState is not a heap |
| // object. |
| }; |
| |
| scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const override; |
| void SetFilterQuality(SkFilterQuality) override; |
| bool IsWebGL2OrHigher() { return Version() >= 2; } |
| |
| void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const; |
| |
| ScriptPromise commit(ScriptState*, ExceptionState&); |
| |
| // For use by WebVR which doesn't use the normal compositing path. |
| // This clears the backbuffer if preserveDrawingBuffer is false. |
| void MarkCompositedAndClearBackbufferIfNeeded(); |
| |
| // For use by WebVR, commits the current canvas content similar |
| // to the "commit" JS API. |
| scoped_refptr<StaticBitmapImage> GetStaticBitmapImage(); |
| |
| protected: |
| friend class EXTDisjointTimerQuery; |
| friend class EXTDisjointTimerQueryWebGL2; |
| friend class WebGLDrawBuffers; |
| friend class WebGLFramebuffer; |
| friend class WebGLObject; |
| friend class WebGLContextObject; |
| friend class OESVertexArrayObject; |
| friend class WebGLDebugShaders; |
| friend class WebGLCompressedTextureASTC; |
| friend class WebGLCompressedTextureATC; |
| friend class WebGLCompressedTextureETC; |
| friend class WebGLCompressedTextureETC1; |
| friend class WebGLCompressedTexturePVRTC; |
| friend class WebGLCompressedTextureS3TC; |
| friend class WebGLCompressedTextureS3TCsRGB; |
| friend class WebGLRenderingContextErrorMessageCallback; |
| friend class WebGLVertexArrayObjectBase; |
| friend class ScopedDrawingBufferBinder; |
| friend class ScopedTexture2DRestorer; |
| friend class ScopedFramebufferRestorer; |
| friend class ScopedUnpackParametersResetRestore; |
| |
| WebGLRenderingContextBase(CanvasRenderingContextHost*, |
| std::unique_ptr<WebGraphicsContext3DProvider>, |
| bool using_gpu_compositing, |
| const CanvasContextCreationAttributes&, |
| unsigned); |
| scoped_refptr<DrawingBuffer> CreateDrawingBuffer( |
| std::unique_ptr<WebGraphicsContext3DProvider>, |
| bool using_gpu_compositing); |
| void SetupFlags(); |
| |
| // CanvasRenderingContext implementation. |
| bool Is3d() const override { return true; } |
| bool IsComposited() const override { return true; } |
| bool IsAccelerated() const override { return true; } |
| void SetIsHidden(bool) override; |
| bool PaintRenderingResultsToCanvas(SourceDrawingBuffer) override; |
| WebLayer* PlatformLayer() const override; |
| void Stop() override; |
| void FinalizeFrame() override; |
| |
| // DrawingBuffer::Client implementation. |
| bool DrawingBufferClientIsBoundForDraw() override; |
| void DrawingBufferClientRestoreScissorTest() override; |
| void DrawingBufferClientRestoreMaskAndClearValues() override; |
| void DrawingBufferClientRestorePixelPackParameters() override; |
| void DrawingBufferClientRestoreTexture2DBinding() override; |
| void DrawingBufferClientRestoreRenderbufferBinding() override; |
| void DrawingBufferClientRestoreFramebufferBinding() override; |
| void DrawingBufferClientRestorePixelUnpackBufferBinding() override; |
| void DrawingBufferClientRestorePixelPackBufferBinding() override; |
| |
| virtual void DestroyContext(); |
| void MarkContextChanged(ContentChangeType); |
| |
| void OnErrorMessage(const char*, int32_t id); |
| |
| // Query if depth_stencil buffer is supported. |
| bool IsDepthStencilSupported() { return is_depth_stencil_supported_; } |
| |
| // Check if each enabled vertex attribute is bound to a buffer. |
| bool ValidateRenderingState(const char*); |
| |
| bool ValidateWebGLObject(const char*, WebGLObject*); |
| |
| // Adds a compressed texture format. |
| void AddCompressedTextureFormat(GLenum); |
| void RemoveAllCompressedTextureFormats(); |
| |
| // Set UNPACK_ALIGNMENT to 1, all other parameters to 0. |
| virtual void ResetUnpackParameters(); |
| // Restore the client unpack parameters. |
| virtual void RestoreUnpackParameters(); |
| |
| scoped_refptr<Image> DrawImageIntoBuffer(scoped_refptr<Image>, |
| int width, |
| int height, |
| const char* function_name); |
| |
| scoped_refptr<Image> VideoFrameToImage( |
| HTMLVideoElement*, |
| int already_uploaded_id, |
| WebMediaPlayer::VideoFrameUploadMetadata* out_metadata); |
| |
| // Structure for rendering to a DrawingBuffer, instead of directly |
| // to the back-buffer of m_context. |
| scoped_refptr<DrawingBuffer> drawing_buffer_; |
| |
| TraceWrapperMember<WebGLContextGroup> context_group_; |
| |
| bool is_hidden_; |
| LostContextMode context_lost_mode_; |
| AutoRecoveryMethod auto_recovery_method_; |
| // Dispatches a context lost event once it is determined that one is needed. |
| // This is used for synthetic, WEBGL_lose_context and real context losses. For |
| // real ones, it's likely that there's no JavaScript on the stack, but that |
| // might be dependent on how exactly the platform discovers that the context |
| // was lost. For better portability we always defer the dispatch of the event. |
| TaskRunnerTimer<WebGLRenderingContextBase> dispatch_context_lost_event_timer_; |
| bool restore_allowed_; |
| TaskRunnerTimer<WebGLRenderingContextBase> restore_timer_; |
| scoped_refptr<WebTaskRunner> task_runner_; |
| |
| bool marked_canvas_dirty_; |
| bool animation_frame_in_progress_; |
| |
| // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and |
| // stored values for ELEMENT_ARRAY_BUFFER |
| TraceWrapperMember<WebGLBuffer> bound_array_buffer_; |
| |
| Member<WebGLVertexArrayObjectBase> default_vertex_array_object_; |
| TraceWrapperMember<WebGLVertexArrayObjectBase> bound_vertex_array_object_; |
| void SetBoundVertexArrayObject(WebGLVertexArrayObjectBase*); |
| |
| enum VertexAttribValueType { |
| kFloat32ArrayType, |
| kInt32ArrayType, |
| kUint32ArrayType, |
| }; |
| |
| Vector<VertexAttribValueType> vertex_attrib_type_; |
| unsigned max_vertex_attribs_; |
| void SetVertexAttribType(GLuint index, VertexAttribValueType); |
| |
| TraceWrapperMember<WebGLProgram> current_program_; |
| TraceWrapperMember<WebGLFramebuffer> framebuffer_binding_; |
| TraceWrapperMember<WebGLRenderbuffer> renderbuffer_binding_; |
| |
| HeapVector<TextureUnitState> texture_units_; |
| unsigned long active_texture_unit_; |
| |
| Vector<GLenum> compressed_texture_formats_; |
| |
| // Fixed-size cache of reusable resource providers for video texImage2D calls. |
| class LRUCanvasResourceProviderCache { |
| public: |
| LRUCanvasResourceProviderCache(int capacity); |
| // The pointer returned is owned by the image buffer map. |
| CanvasResourceProvider* GetCanvasResourceProvider(const IntSize&); |
| |
| private: |
| void BubbleToFront(int idx); |
| std::unique_ptr<std::unique_ptr<CanvasResourceProvider>[]> |
| resource_providers_; |
| int capacity_; |
| }; |
| LRUCanvasResourceProviderCache generated_image_cache_; |
| |
| GLint max_texture_size_; |
| GLint max_cube_map_texture_size_; |
| GLint max3d_texture_size_; |
| GLint max_array_texture_layers_; |
| GLint max_renderbuffer_size_; |
| GLint max_viewport_dims_[2]; |
| GLint max_texture_level_; |
| GLint max_cube_map_texture_level_; |
| GLint max3d_texture_level_; |
| |
| GLint max_draw_buffers_; |
| GLint max_color_attachments_; |
| GLenum back_draw_buffer_; |
| bool draw_buffers_web_gl_requirements_checked_; |
| bool draw_buffers_supported_; |
| |
| GLenum read_buffer_of_default_framebuffer_; |
| |
| GLint pack_alignment_ = 4; |
| GLint unpack_alignment_ = 4; |
| bool unpack_flip_y_ = false; |
| bool unpack_premultiply_alpha_ = false; |
| GLenum unpack_colorspace_conversion_ = GC3D_BROWSER_DEFAULT_WEBGL; |
| // The following three unpack params belong to WebGL2 only. |
| GLint unpack_skip_pixels_ = 0; |
| GLint unpack_skip_rows_ = 0; |
| GLint unpack_row_length_ = 0; |
| |
| GLfloat clear_color_[4]; |
| bool scissor_enabled_; |
| GLint scissor_box_[4]; |
| GLfloat clear_depth_; |
| GLint clear_stencil_; |
| GLboolean color_mask_[4]; |
| GLboolean depth_mask_; |
| |
| bool stencil_enabled_; |
| GLuint stencil_mask_, stencil_mask_back_; |
| GLint stencil_func_ref_, |
| stencil_func_ref_back_; // Note that these are the user specified values, |
| // not the internal clamped value. |
| GLuint stencil_func_mask_, stencil_func_mask_back_; |
| |
| bool is_depth_stencil_supported_; |
| |
| bool synthesized_errors_to_console_; |
| int num_gl_errors_to_console_allowed_; |
| |
| unsigned long one_plus_max_non_default_texture_unit_; |
| |
| std::unique_ptr<Extensions3DUtil> extensions_util_; |
| |
| enum ExtensionFlags { |
| kApprovedExtension = 0x00, |
| // Extension that is behind the draft extensions runtime flag: |
| kDraftExtension = 0x01, |
| }; |
| |
| class ExtensionTracker : public GarbageCollected<ExtensionTracker>, |
| public TraceWrapperBase { |
| public: |
| ExtensionTracker(ExtensionFlags flags, const char* const* prefixes) |
| : draft_(flags & kDraftExtension), prefixes_(prefixes) {} |
| |
| bool Draft() const { return draft_; } |
| |
| const char* const* Prefixes() const; |
| bool MatchesNameWithPrefixes(const String&) const; |
| |
| virtual WebGLExtension* GetExtension(WebGLRenderingContextBase*) = 0; |
| virtual bool Supported(WebGLRenderingContextBase*) const = 0; |
| virtual const char* ExtensionName() const = 0; |
| virtual void LoseExtension(bool) = 0; |
| |
| // This is only used for keeping the JS wrappers of extensions alive. |
| virtual WebGLExtension* GetExtensionObjectIfAlreadyEnabled() = 0; |
| |
| virtual void Trace(blink::Visitor* visitor) {} |
| void TraceWrappers(const ScriptWrappableVisitor*) const override {} |
| |
| private: |
| bool draft_; |
| const char* const* prefixes_; |
| }; |
| |
| template <typename T> |
| class TypedExtensionTracker final : public ExtensionTracker { |
| public: |
| static TypedExtensionTracker<T>* Create(Member<T>& extension_field, |
| ExtensionFlags flags, |
| const char* const* prefixes) { |
| return new TypedExtensionTracker<T>(extension_field, flags, prefixes); |
| } |
| |
| WebGLExtension* GetExtension(WebGLRenderingContextBase* context) override { |
| if (!extension_) { |
| extension_ = T::Create(context); |
| extension_field_ = extension_; |
| } |
| |
| return extension_; |
| } |
| |
| bool Supported(WebGLRenderingContextBase* context) const override { |
| return T::Supported(context); |
| } |
| |
| const char* ExtensionName() const override { return T::ExtensionName(); } |
| |
| void LoseExtension(bool force) override { |
| if (extension_) { |
| extension_->Lose(force); |
| if (extension_->IsLost()) |
| extension_ = nullptr; |
| } |
| } |
| |
| WebGLExtension* GetExtensionObjectIfAlreadyEnabled() override { |
| return extension_; |
| } |
| |
| virtual void Trace(blink::Visitor* visitor) { |
| visitor->Trace(extension_); |
| ExtensionTracker::Trace(visitor); |
| } |
| |
| virtual void TraceWrappers(const ScriptWrappableVisitor* visitor) const { |
| visitor->TraceWrappers(extension_); |
| ExtensionTracker::TraceWrappers(visitor); |
| } |
| |
| private: |
| TypedExtensionTracker(Member<T>& extension_field, |
| ExtensionFlags flags, |
| const char* const* prefixes) |
| : ExtensionTracker(flags, prefixes), |
| extension_field_(extension_field) {} |
| |
| GC_PLUGIN_IGNORE("http://crbug.com/519953") |
| Member<T>& extension_field_; |
| // ExtensionTracker holds it's own reference to the extension to ensure |
| // that it is not deleted before this object's destructor is called |
| TraceWrapperMember<T> extension_; |
| }; |
| |
| bool extension_enabled_[kWebGLExtensionNameCount]; |
| HeapVector<TraceWrapperMember<ExtensionTracker>> extensions_; |
| HashSet<String> disabled_extensions_; |
| |
| template <typename T> |
| void RegisterExtension(Member<T>& extension_ptr, |
| ExtensionFlags flags = kApprovedExtension, |
| const char* const* prefixes = nullptr) { |
| extensions_.push_back( |
| TypedExtensionTracker<T>::Create(extension_ptr, flags, prefixes)); |
| } |
| |
| bool ExtensionSupportedAndAllowed(const ExtensionTracker*); |
| |
| inline bool ExtensionEnabled(WebGLExtensionName name) { |
| return extension_enabled_[name]; |
| } |
| |
| // ScopedDrawingBufferBinder is used for |
| // ReadPixels/CopyTexImage2D/CopySubImage2D to read from a multisampled |
| // DrawingBuffer. In this situation, we need to blit to a single sampled |
| // buffer for reading, during which the bindings could be changed and need to |
| // be recovered. |
| class ScopedDrawingBufferBinder { |
| STACK_ALLOCATED(); |
| |
| public: |
| ScopedDrawingBufferBinder(DrawingBuffer* drawing_buffer, |
| WebGLFramebuffer* framebuffer_binding) |
| : drawing_buffer_(drawing_buffer), |
| read_framebuffer_binding_(framebuffer_binding) { |
| // Commit DrawingBuffer if needed (e.g., for multisampling) |
| if (!read_framebuffer_binding_ && drawing_buffer_) |
| drawing_buffer_->ResolveAndBindForReadAndDraw(); |
| } |
| |
| ~ScopedDrawingBufferBinder() { |
| // Restore DrawingBuffer if needed |
| if (!read_framebuffer_binding_ && drawing_buffer_) |
| drawing_buffer_->RestoreFramebufferBindings(); |
| } |
| |
| private: |
| DrawingBuffer* drawing_buffer_; |
| Member<WebGLFramebuffer> read_framebuffer_binding_; |
| }; |
| |
| // Errors raised by synthesizeGLError() while the context is lost. |
| Vector<GLenum> lost_context_errors_; |
| // Other errors raised by synthesizeGLError(). |
| Vector<GLenum> synthetic_errors_; |
| |
| bool is_web_gl2_formats_types_added_; |
| bool is_web_gl2_tex_image_source_formats_types_added_; |
| bool is_web_gl2_internal_formats_copy_tex_image_added_; |
| bool is_oes_texture_float_formats_types_added_; |
| bool is_oes_texture_half_float_formats_types_added_; |
| bool is_web_gl_depth_texture_formats_types_added_; |
| bool is_ext_srgb_formats_types_added_; |
| bool is_ext_color_buffer_float_formats_added_; |
| |
| std::set<GLenum> supported_internal_formats_; |
| std::set<GLenum> supported_tex_image_source_internal_formats_; |
| std::set<GLenum> supported_internal_formats_copy_tex_image_; |
| std::set<GLenum> supported_formats_; |
| std::set<GLenum> supported_tex_image_source_formats_; |
| std::set<GLenum> supported_types_; |
| std::set<GLenum> supported_tex_image_source_types_; |
| |
| // Helpers for getParameter and others |
| ScriptValue GetBooleanParameter(ScriptState*, GLenum); |
| ScriptValue GetBooleanArrayParameter(ScriptState*, GLenum); |
| ScriptValue GetFloatParameter(ScriptState*, GLenum); |
| ScriptValue GetIntParameter(ScriptState*, GLenum); |
| ScriptValue GetInt64Parameter(ScriptState*, GLenum); |
| ScriptValue GetUnsignedIntParameter(ScriptState*, GLenum); |
| ScriptValue GetWebGLFloatArrayParameter(ScriptState*, GLenum); |
| ScriptValue GetWebGLIntArrayParameter(ScriptState*, GLenum); |
| |
| // Clear the backbuffer if it was composited since the last operation. |
| // clearMask is set to the bitfield of any clear that would happen anyway at |
| // this time and the function returns |CombinedClear| if that clear is now |
| // unnecessary. |
| enum HowToClear { |
| // Skip clearing the backbuffer. |
| kSkipped, |
| // Clear the backbuffer. |
| kJustClear, |
| // Combine webgl.clear() API with the backbuffer clear, so webgl.clear() |
| // doesn't have to call glClear() again. |
| kCombinedClear |
| }; |
| HowToClear ClearIfComposited(GLbitfield clear_mask = 0); |
| |
| // Convert texture internal format. |
| GLenum ConvertTexInternalFormat(GLenum internalformat, GLenum type); |
| |
| enum TexImageFunctionType { |
| kTexImage, |
| kTexSubImage, |
| kCopyTexImage, |
| kCompressedTexImage |
| }; |
| |
| // This must stay in sync with WebMediaPlayer::TexImageFunctionID. |
| enum TexImageFunctionID { |
| kTexImage2D, |
| kTexSubImage2D, |
| kTexImage3D, |
| kTexSubImage3D |
| }; |
| |
| enum TexImageDimension { kTex2D, kTex3D }; |
| void TexImage2DBase(GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLsizei width, |
| GLsizei height, |
| GLint border, |
| GLenum format, |
| GLenum type, |
| const void* pixels); |
| void TexImageImpl(TexImageFunctionID, |
| GLenum target, |
| GLint level, |
| GLint internalformat, |
| GLint xoffset, |
| GLint yoffset, |
| GLint zoffset, |
| GLenum format, |
| GLenum type, |
| Image*, |
| WebGLImageConversion::ImageHtmlDomSource, |
| bool flip_y, |
| bool premultiply_alpha, |
| const IntRect&, |
| GLsizei depth, |
| GLint unpack_image_height); |
| |
| template <typename T> |
| IntRect GetTextureSourceSize(T* texture_source) { |
| return IntRect(0, 0, texture_source->width(), texture_source->height()); |
| } |
| |
| template <typename T> |
| bool ValidateTexImageSubRectangle(const char* function_name, |
| TexImageFunctionID function_id, |
| T* image, |
| const IntRect& sub_rect, |
| GLsizei depth, |
| GLint unpack_image_height, |
| bool* selecting_sub_rectangle) { |
| DCHECK(function_name); |
| DCHECK(selecting_sub_rectangle); |
| DCHECK(image); |
| int image_width = static_cast<int>(image->width()); |
| int image_height = static_cast<int>(image->height()); |
| *selecting_sub_rectangle = |
| !(sub_rect.X() == 0 && sub_rect.Y() == 0 && |
| sub_rect.Width() == image_width && sub_rect.Height() == image_height); |
| // If the source image rect selects anything except the entire |
| // contents of the image, assert that we're running WebGL 2.0 or |
| // higher, since this should never happen for WebGL 1.0 (even though |
| // the code could support it). If the image is null, that will be |
| // signaled as an error later. |
| DCHECK(!*selecting_sub_rectangle || IsWebGL2OrHigher()) |
| << "subRect = (" << sub_rect.Width() << " x " << sub_rect.Height() |
| << ") @ (" << sub_rect.X() << ", " << sub_rect.Y() << "), image = (" |
| << image_width << " x " << image_height << ")"; |
| |
| if (!sub_rect.IsValid() || sub_rect.X() < 0 || sub_rect.Y() < 0 || |
| sub_rect.MaxX() > image_width || sub_rect.MaxY() > image_height || |
| sub_rect.Width() < 0 || sub_rect.Height() < 0) { |
| SynthesizeGLError(GL_INVALID_OPERATION, function_name, |
| "source sub-rectangle specified via pixel unpack " |
| "parameters is invalid"); |
| return false; |
| } |
| |
| if (function_id == kTexImage3D || function_id == kTexSubImage3D) { |
| DCHECK_GE(unpack_image_height, 0); |
| |
| if (depth < 1) { |
| SynthesizeGLError(GL_INVALID_OPERATION, function_name, |
| "Can't define a 3D texture with depth < 1"); |
| return false; |
| } |
| |
| // According to the WebGL 2.0 spec, specifying depth > 1 means |
| // to select multiple rectangles stacked vertically. |
| WTF::CheckedNumeric<GLint> max_y_accessed; |
| if (unpack_image_height) { |
| max_y_accessed = unpack_image_height; |
| } else { |
| max_y_accessed = sub_rect.Height(); |
| } |
| max_y_accessed *= depth - 1; |
| max_y_accessed += sub_rect.Height(); |
| max_y_accessed += sub_rect.Y(); |
| |
| if (!max_y_accessed.IsValid()) { |
| SynthesizeGLError(GL_INVALID_OPERATION, function_name, |
| "Out-of-range parameters passed for 3D texture " |
| "upload"); |
| return false; |
| } |
| |
| if (max_y_accessed.ValueOrDie() > image_height) { |
| SynthesizeGLError(GL_INVALID_OPERATION, function_name, |
| "Not enough data supplied to upload to a 3D texture " |
| "with depth > 1"); |
| return false; |
| } |
| } else { |
| DCHECK_EQ(depth, 1); |
| DCHECK_EQ(unpack_image_height, 0); |
| } |
| return true; |
| } |
| |
| // Copy from the source directly to the texture via the gpu, without a |
| // read-back to system memory. Source could be canvas or imageBitmap. |
| void TexImageByGPU(TexImageFunctionID, |
| WebGLTexture*, |
| GLenum target, |
| GLint level, |
| GLint xoffset, |
| GLint yoffset, |
| GLint zoffset, |
| CanvasImageSource*, |
| const IntRect& source_sub_rectangle); |
| bool CanUseTexImageByGPU(GLenum format, GLenum type); |
| |
| virtual WebGLImageConversion::PixelStoreParams GetPackPixelStoreParams(); |
| virtual WebGLImageConversion::PixelStoreParams GetUnpackPixelStoreParams( |
| TexImageDimension); |
| |
| // Helper function for copyTex{Sub}Image, check whether the internalformat |
| // and the color buffer format of the current bound framebuffer combination |
| // is valid. |
| bool IsTexInternalFormatColorBufferCombinationValid( |
| GLenum tex_internal_format, |
| GLenum color_buffer_format); |
| |
| // Helper function to verify limits on the length of uniform and attribute |
| // locations. |
| virtual unsigned GetMaxWebGLLocationLength() const { return 256; } |
| bool ValidateLocationLength(const char* function_name, const String&); |
| |
| // Helper function to check if size is non-negative. |
| // Generate GL error and return false for negative inputs; otherwise, return |
| // true. |
| bool ValidateSize(const char* function_name, GLint x, GLint y, GLint z = 0); |
| |
| // Helper function to check if all characters in the string belong to the |
| // ASCII subset as defined in GLSL ES 1.0 spec section 3.1. |
| bool ValidateString(const char* function_name, const String&); |
| |
| // Helper function to check if all characters in the shader source belong to |
| // the ASCII subset as defined in GLSL ES 1.0 spec section 3.1 Character Set |
| // for WebGL 1.0 and in GLSL ES 3.00 spec section 3.1 Character Set for WebGL |
| // 2.0. |
| bool ValidateShaderSource(const String&); |
| |
| // Helper function to check texture binding target and texture bound to the |
| // target. Generate GL errors and return 0 if target is invalid or texture |
| // bound is null. Otherwise, return the texture bound to the target. |
| WebGLTexture* ValidateTextureBinding(const char* function_name, |
| GLenum target); |
| |
| // Wrapper function for validateTexture2D(3D)Binding, used in TexImageHelper |
| // functions. |
| virtual WebGLTexture* ValidateTexImageBinding(const char*, |
| TexImageFunctionID, |
| GLenum); |
| |
| // Helper function to check texture 2D target and texture bound to the target. |
| // Generate GL errors and return 0 if target is invalid or texture bound is |
| // null. Otherwise, return the texture bound to the target. |
| WebGLTexture* ValidateTexture2DBinding(const char* function_name, |
| GLenum target); |
| |
| void AddExtensionSupportedFormatsTypes(); |
| |
| // Helper function to check input internalformat/format/type for functions |
| // Tex{Sub}Image taking TexImageSource source data. Generates GL error and |
| // returns false if parameters are invalid. |
| bool ValidateTexImageSourceFormatAndType(const char* function_name, |
| TexImageFunctionType, |
| GLenum internalformat, |
| GLenum format, |
| GLenum type); |
| |
| // Helper function to check input internalformat/format/type for functions |
| // Tex{Sub}Image. Generates GL error and returns false if parameters are |
| // invalid. |
| bool ValidateTexFuncFormatAndType(const char* function_name, |
| TexImageFunctionType, |
| GLenum internalformat, |
| GLenum format, |
| GLenum type, |
| GLint level); |
| |
| // Helper function to check readbuffer validity for copyTex{Sub}Image. |
| // If yes, obtains the bound read framebuffer, returns true. |
| // If not, generates a GL error, returns false. |
| bool ValidateReadBufferAndGetInfo( |
| const char* function_name, |
| WebGLFramebuffer*& read_framebuffer_binding); |
| |
| // Helper function to check format/type and ArrayBuffer view type for |
| // readPixels. |
| // Generates INVALID_ENUM and returns false if parameters are invalid. |
| // Generates INVALID_OPERATION if ArrayBuffer view type is incompatible with |
| // type. |
| virtual bool ValidateReadPixelsFormatAndType(GLenum format, |
| GLenum type, |
| DOMArrayBufferView*); |
| |
| // Helper function to check parameters of readPixels. Returns true if all |
| // parameters are valid. Otherwise, generates appropriate error and returns |
| // false. |
| bool ValidateReadPixelsFuncParameters(GLsizei width, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| DOMArrayBufferView*, |
| long long buffer_size); |
| |
| virtual GLint GetMaxTextureLevelForTarget(GLenum target); |
| |
| // Helper function to check input level for functions {copy}Tex{Sub}Image. |
| // Generates GL error and returns false if level is invalid. |
| bool ValidateTexFuncLevel(const char* function_name, |
| GLenum target, |
| GLint level); |
| |
| // Helper function to check if a 64-bit value is non-negative and can fit into |
| // a 32-bit integer. Generates GL error and returns false if not. |
| bool ValidateValueFitNonNegInt32(const char* function_name, |
| const char* param_name, |
| long long value); |
| |
| enum TexFuncValidationSourceType { |
| kSourceArrayBufferView, |
| kSourceImageData, |
| kSourceHTMLImageElement, |
| kSourceHTMLCanvasElement, |
| kSourceHTMLVideoElement, |
| kSourceImageBitmap, |
| kSourceUnpackBuffer, |
| }; |
| |
| // Helper function for tex{Sub}Image{2|3}D to check if the input |
| // format/type/level/target/width/height/depth/border/xoffset/yoffset/zoffset |
| // are valid. Otherwise, it would return quickly without doing other work. |
| bool ValidateTexFunc(const char* function_name, |
| TexImageFunctionType, |
| TexFuncValidationSourceType, |
| GLenum target, |
| GLint level, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| GLint border, |
| GLenum format, |
| GLenum type, |
| GLint xoffset, |
| GLint yoffset, |
| GLint zoffset); |
| |
| // Helper function to check input width and height for functions {copy, |
| // compressed}Tex{Sub}Image. Generates GL error and returns false if width or |
| // height is invalid. |
| bool ValidateTexFuncDimensions(const char* function_name, |
| TexImageFunctionType, |
| GLenum target, |
| GLint level, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth); |
| |
| // Helper function to check input parameters for functions |
| // {copy}Tex{Sub}Image. Generates GL error and returns false if parameters |
| // are invalid. |
| bool ValidateTexFuncParameters(const char* function_name, |
| TexImageFunctionType, |
| TexFuncValidationSourceType, |
| GLenum target, |
| GLint level, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| GLint border, |
| GLenum format, |
| GLenum type); |
| |
| enum NullDisposition { kNullAllowed, kNullNotAllowed, kNullNotReachable }; |
| |
| // Helper function to validate that the given ArrayBufferView |
| // is of the correct type and contains enough data for the texImage call. |
| // Generates GL error and returns false if parameters are invalid. |
| bool ValidateTexFuncData(const char* function_name, |
| TexImageDimension, |
| GLint level, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| GLenum format, |
| GLenum type, |
| DOMArrayBufferView* pixels, |
| NullDisposition, |
| GLuint src_offset); |
| |
| // Helper function to validate a given texture format is settable as in |
| // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and |
| // copyTexSubImage2D. |
| // Generates GL error and returns false if the format is not settable. |
| bool ValidateSettableTexFormat(const char* function_name, GLenum format); |
| |
| // Helper function to validate format for CopyTexImage. |
| bool ValidateCopyTexFormat(const char* function_name, GLenum format); |
| |
| // Helper function for validating compressed texture formats. |
| bool ValidateCompressedTexFormat(const char* function_name, GLenum format); |
| |
| // Helper function to validate if front/back stencilMask and stencilFunc |
| // settings are the same. |
| bool ValidateStencilSettings(const char* function_name); |
| |
| // Helper function to validate stencil or depth func. |
| bool ValidateStencilOrDepthFunc(const char* function_name, GLenum); |
| |
| // Helper function for texParameterf and texParameteri. |
| void TexParameter(GLenum target, |
| GLenum pname, |
| GLfloat paramf, |
| GLint parami, |
| bool is_float); |
| |
| // Helper function to print GL errors to console. |
| void PrintGLErrorToConsole(const String&); |
| |
| // Helper function to print warnings to console. Currently |
| // used only to warn about use of obsolete functions. |
| void PrintWarningToConsole(const String&); |
| |
| // Helper function to validate the target for checkFramebufferStatus and |
| // validateFramebufferFuncParameters. |
| virtual bool ValidateFramebufferTarget(GLenum target); |
| |
| // Get the framebuffer bound to given target |
| virtual WebGLFramebuffer* GetFramebufferBinding(GLenum target); |
| |
| virtual WebGLFramebuffer* GetReadFramebufferBinding(); |
| |
| // Helper function to validate input parameters for framebuffer functions. |
| // Generate GL error if parameters are illegal. |
| bool ValidateFramebufferFuncParameters(const char* function_name, |
| GLenum target, |
| GLenum attachment); |
| |
| // Helper function to validate blend equation mode. |
| bool ValidateBlendEquation(const char* function_name, GLenum); |
| |
| // Helper function to validate blend func factors. |
| bool ValidateBlendFuncFactors(const char* function_name, |
| GLenum src, |
| GLenum dst); |
| |
| // Helper function to validate a GL capability. |
| virtual bool ValidateCapability(const char* function_name, GLenum); |
| |
| // Helper function to validate input parameters for uniform functions. |
| bool ValidateUniformParameters(const char* function_name, |
| const WebGLUniformLocation*, |
| void*, |
| GLsizei, |
| GLsizei mod, |
| GLuint src_offset, |
| GLuint src_length); |
| bool ValidateUniformMatrixParameters(const char* function_name, |
| const WebGLUniformLocation*, |
| GLboolean transpose, |
| DOMFloat32Array*, |
| GLsizei mod, |
| GLuint src_offset, |
| GLuint src_length); |
| bool ValidateUniformMatrixParameters(const char* function_name, |
| const WebGLUniformLocation*, |
| GLboolean transpose, |
| void*, |
| GLsizei, |
| GLsizei mod, |
| GLuint src_offset, |
| GLuint src_length); |
| |
| template <typename WTFTypedArray> |
| bool ValidateUniformParameters( |
| const char* function_name, |
| const WebGLUniformLocation* location, |
| const TypedFlexibleArrayBufferView<WTFTypedArray>& v, |
| GLsizei required_min_size, |
| GLuint src_offset, |
| GLuint src_length) { |
| if (!v.DataMaybeOnStack()) { |
| SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array"); |
| return false; |
| } |
| return ValidateUniformMatrixParameters( |
| function_name, location, false, v.DataMaybeOnStack(), v.length(), |
| required_min_size, src_offset, src_length); |
| } |
| |
| // Helper function to validate the target for bufferData and |
| // getBufferParameter. |
| virtual bool ValidateBufferTarget(const char* function_name, GLenum target); |
| |
| // Helper function to validate the target for bufferData. |
| // Return the current bound buffer to target, or 0 if the target is invalid. |
| virtual WebGLBuffer* ValidateBufferDataTarget(const char* function_name, |
| GLenum target); |
| // Helper function to validate the usage for bufferData. |
| virtual bool ValidateBufferDataUsage(const char* function_name, GLenum usage); |
| |
| virtual bool ValidateAndUpdateBufferBindTarget(const char* function_name, |
| GLenum target, |
| WebGLBuffer*); |
| |
| virtual void RemoveBoundBuffer(WebGLBuffer*); |
| |
| // Helper function for tex{Sub}Image2D to make sure image is ready and |
| // wouldn't taint Origin. |
| |
| bool ValidateHTMLImageElement(const SecurityOrigin*, |
| const char* function_name, |
| HTMLImageElement*, |
| ExceptionState&); |
| |
| // Helper function for tex{Sub}Image2D to make sure canvas is ready and |
| // wouldn't taint Origin. |
| bool ValidateHTMLCanvasElement(const SecurityOrigin*, |
| const char* function_name, |
| HTMLCanvasElement*, |
| ExceptionState&); |
| |
| // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't |
| // taint Origin. |
| bool ValidateHTMLVideoElement(const SecurityOrigin*, |
| const char* function_name, |
| HTMLVideoElement*, |
| ExceptionState&); |
| |
| // Helper function for tex{Sub}Image2D to make sure imagebitmap is ready and |
| // wouldn't taint Origin. |
| bool ValidateImageBitmap(const char* function_name, |
| ImageBitmap*, |
| ExceptionState&); |
| |
| // Helper function to validate drawArrays(Instanced) calls |
| bool ValidateDrawArrays(const char* function_name); |
| |
| // Helper function to validate drawElements(Instanced) calls |
| bool ValidateDrawElements(const char* function_name, |
| GLenum type, |
| long long offset); |
| |
| // Helper functions to bufferData() and bufferSubData(). |
| void BufferDataImpl(GLenum target, |
| long long size, |
| const void* data, |
| GLenum usage); |
| void BufferSubDataImpl(GLenum target, |
| long long offset, |
| GLsizeiptr, |
| const void* data); |
| |
| // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions. |
| // Return false if caller should return without further processing. |
| bool DeleteObject(WebGLObject*); |
| |
| // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram. |
| // If the object has already been deleted, set deleted to true upon return. |
| // Return false if caller should return without further processing. |
| bool CheckObjectToBeBound(const char* function_name, |
| WebGLObject*, |
| bool& deleted); |
| |
| void DispatchContextLostEvent(TimerBase*); |
| // Helper for restoration after context lost. |
| void MaybeRestoreContext(TimerBase*); |
| |
| enum ConsoleDisplayPreference { kDisplayInConsole, kDontDisplayInConsole }; |
| |
| // Reports an error to glGetError, sends a message to the JavaScript |
| // console. |
| void SynthesizeGLError(GLenum, |
| const char* function_name, |
| const char* description, |
| ConsoleDisplayPreference = kDisplayInConsole); |
| void EmitGLWarning(const char* function, const char* reason); |
| |
| String EnsureNotNull(const String&) const; |
| |
| // Enable or disable stencil test based on user setting and |
| // whether the current FBO has a stencil buffer. |
| void ApplyStencilTest(); |
| |
| // Helper for enabling or disabling a capability. |
| void EnableOrDisable(GLenum capability, bool enable); |
| |
| // Clamp the width and height to GL_MAX_VIEWPORT_DIMS. |
| IntSize ClampedCanvasSize() const; |
| |
| // First time called, if EXT_draw_buffers is supported, query the value; |
| // otherwise return 0. Later, return the cached value. |
| GLint MaxDrawBuffers(); |
| GLint MaxColorAttachments(); |
| |
| void SetBackDrawBuffer(GLenum); |
| void SetFramebuffer(GLenum, WebGLFramebuffer*); |
| |
| virtual void RestoreCurrentFramebuffer(); |
| void RestoreCurrentTexture2D(); |
| |
| void FindNewMaxNonDefaultTextureUnit(); |
| |
| virtual void RenderbufferStorageImpl(GLenum target, |
| GLsizei samples, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height, |
| const char* function_name); |
| |
| friend class WebGLStateRestorer; |
| friend class WebGLRenderingContextEvictionManager; |
| |
| static void ActivateContext(WebGLRenderingContextBase*); |
| static void DeactivateContext(WebGLRenderingContextBase*); |
| static void AddToEvictedList(WebGLRenderingContextBase*); |
| static void RemoveFromEvictedList(WebGLRenderingContextBase*); |
| static void RestoreEvictedContext(WebGLRenderingContextBase*); |
| static void ForciblyLoseOldestContext(const String& reason); |
| // Return the least recently used context's position in the active context |
| // vector. If the vector is empty, return the maximum allowed active context |
| // number. |
| static WebGLRenderingContextBase* OldestContext(); |
| static WebGLRenderingContextBase* OldestEvictedContext(); |
| |
| friend class ScopedRGBEmulationColorMask; |
| unsigned active_scoped_rgb_emulation_color_masks_; |
| |
| ImageBitmap* TransferToImageBitmapBase(ScriptState*); |
| |
| // Helper functions for tex(Sub)Image2D && texSubImage3D |
| void TexImageHelperDOMArrayBufferView(TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLsizei, |
| GLsizei, |
| GLsizei, |
| GLint, |
| GLenum, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| DOMArrayBufferView*, |
| NullDisposition, |
| GLuint src_offset); |
| void TexImageHelperImageData(TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| GLenum, |
| GLenum, |
| GLsizei, |
| GLint, |
| GLint, |
| GLint, |
| ImageData*, |
| const IntRect&, |
| GLint); |
| |
| void TexImageHelperHTMLImageElement(const SecurityOrigin*, |
| TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLenum, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| HTMLImageElement*, |
| const IntRect&, |
| GLsizei, |
| GLint, |
| ExceptionState&); |
| |
| void TexImageHelperHTMLCanvasElement(const SecurityOrigin*, |
| TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLenum, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| HTMLCanvasElement*, |
| const IntRect&, |
| GLsizei, |
| GLint, |
| ExceptionState&); |
| |
| void TexImageHelperHTMLVideoElement(const SecurityOrigin*, |
| TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLenum, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| HTMLVideoElement*, |
| const IntRect&, |
| GLsizei, |
| GLint, |
| ExceptionState&); |
| void TexImageHelperImageBitmap(TexImageFunctionID, |
| GLenum, |
| GLint, |
| GLint, |
| GLenum, |
| GLenum, |
| GLint, |
| GLint, |
| GLint, |
| ImageBitmap*, |
| const IntRect&, |
| GLsizei, |
| GLint, |
| ExceptionState&); |
| static const char* GetTexImageFunctionName(TexImageFunctionID); |
| IntRect SentinelEmptyRect(); |
| IntRect SafeGetImageSize(Image*); |
| IntRect GetImageDataSize(ImageData*); |
| |
| // Helper implementing readPixels for WebGL 1.0 and 2.0. |
| void ReadPixelsHelper(GLint x, |
| GLint y, |
| GLsizei width, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| DOMArrayBufferView* pixels, |
| GLuint offset); |
| |
| private: |
| WebGLRenderingContextBase(CanvasRenderingContextHost*, |
| scoped_refptr<WebTaskRunner>, |
| std::unique_ptr<WebGraphicsContext3DProvider>, |
| bool using_gpu_compositing, |
| const CanvasContextCreationAttributes&, |
| unsigned); |
| static bool SupportOwnOffscreenSurface(ExecutionContext*); |
| static std::unique_ptr<WebGraphicsContext3DProvider> |
| CreateContextProviderInternal(CanvasRenderingContextHost*, |
| const CanvasContextCreationAttributes&, |
| unsigned web_gl_version, |
| bool* using_gpu_compositing); |
| void TexImageCanvasByGPU(TexImageFunctionID, |
| HTMLCanvasElement*, |
| GLenum, |
| GLuint, |
| GLint, |
| GLint, |
| const IntRect&); |
| void TexImageBitmapByGPU(ImageBitmap*, |
| GLenum, |
| GLuint, |
| GLint, |
| GLint, |
| const IntRect&); |
| |
| scoped_refptr<StaticBitmapImage> MakeImageSnapshot(SkImageInfo&) const; |
| const unsigned version_; |
| |
| bool IsPaintable() const final { return GetDrawingBuffer(); } |
| bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*, |
| SourceDrawingBuffer) const; |
| void HoldReferenceToDrawingBuffer(DrawingBuffer*); |
| }; |
| |
| // TODO(fserb): remove this. |
| DEFINE_TYPE_CASTS(WebGLRenderingContextBase, |
| CanvasRenderingContext, |
| context, |
| context->Is3d(), |
| context.Is3d()); |
| |
| } // namespace blink |
| |
| WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS( |
| blink::WebGLRenderingContextBase::TextureUnitState); |
| |
| #endif // WebGLRenderingContextBase_h |