blob: 15a2ccc26c3d75d0b407f881cbe550b3e888375b [file] [log] [blame]
/*
* 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_;
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