summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/canvas')
-rw-r--r--Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp31
-rw-r--r--Source/WebCore/html/canvas/ANGLEInstancedArrays.h20
-rw-r--r--Source/WebCore/html/canvas/ANGLEInstancedArrays.idl6
-rw-r--r--Source/WebCore/html/canvas/CanvasContextAttributes.cpp41
-rw-r--r--Source/WebCore/html/canvas/CanvasContextAttributes.h48
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.cpp38
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.h60
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.idl13
-rw-r--r--Source/WebCore/html/canvas/CanvasPath.cpp (renamed from Source/WebCore/html/canvas/CanvasPathMethods.cpp)127
-rw-r--r--Source/WebCore/html/canvas/CanvasPath.h (renamed from Source/WebCore/html/canvas/CanvasPathMethods.h)27
-rw-r--r--Source/WebCore/html/canvas/CanvasPath.idl41
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.cpp26
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.h25
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.idl6
-rw-r--r--Source/WebCore/html/canvas/CanvasProxy.cpp4
-rw-r--r--Source/WebCore/html/canvas/CanvasProxy.h8
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp45
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h32
-rw-r--r--[-rwxr-xr-x]Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp2009
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h333
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.idl220
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp304
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.h214
-rw-r--r--Source/WebCore/html/canvas/DOMPath.cpp37
-rw-r--r--Source/WebCore/html/canvas/DOMPath.h47
-rw-r--r--Source/WebCore/html/canvas/DOMPath.idl46
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.h40
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.idl33
-rw-r--r--Source/WebCore/html/canvas/EXTDrawBuffers.idl72
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.h40
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.idl31
-rw-r--r--Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTShaderTextureLOD.h40
-rw-r--r--Source/WebCore/html/canvas/EXTShaderTextureLOD.idl31
-rw-r--r--Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp7
-rw-r--r--Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h15
-rw-r--r--Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.idl7
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.h40
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.idl35
-rw-r--r--Source/WebCore/html/canvas/OESElementIndexUint.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESElementIndexUint.h15
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.h15
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.idl6
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.h15
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloatLinear.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloatLinear.h15
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloat.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloat.h15
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h15
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.cpp78
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.h27
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.idl20
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.cpp1830
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.h201
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.idl468
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLAny.cpp120
-rw-r--r--Source/WebCore/html/canvas/WebGLAny.h79
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp142
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.h46
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp18
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureATC.h19
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureATC.idl11
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp22
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h18
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.idl13
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp27
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h19
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.idl13
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.cpp127
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.h60
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.idl27
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.h35
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.idl7
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.cpp55
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.h47
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.cpp22
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.h25
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.h15
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl8
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.cpp20
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.h19
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLDepthTexture.cpp16
-rw-r--r--Source/WebCore/html/canvas/WebGLDepthTexture.h19
-rw-r--r--Source/WebCore/html/canvas/WebGLDepthTexture.idl6
-rw-r--r--Source/WebCore/html/canvas/WebGLDrawBuffers.cpp (renamed from Source/WebCore/html/canvas/EXTDrawBuffers.cpp)71
-rw-r--r--Source/WebCore/html/canvas/WebGLDrawBuffers.h (renamed from Source/WebCore/html/canvas/EXTDrawBuffers.h)22
-rw-r--r--Source/WebCore/html/canvas/WebGLDrawBuffers.idl72
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.cpp2
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.h23
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp132
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h23
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp322
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.h142
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.cpp13
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.h19
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp30
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h28
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp31
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h38
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLQuery.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLQuery.h42
-rw-r--r--Source/WebCore/html/canvas/WebGLQuery.idl (renamed from Source/WebCore/html/canvas/CanvasRenderingContext.idl)15
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.h22
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp6285
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h800
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl647
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp5897
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.h848
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.idl665
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.h42
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.cpp16
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.h24
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp4
-rw-r--r--Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.cpp26
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.h28
-rw-r--r--Source/WebCore/html/canvas/WebGLSync.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLSync.h44
-rw-r--r--Source/WebCore/html/canvas/WebGLSync.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.cpp111
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.h30
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.h44
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.h17
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.idl7
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp79
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.h47
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.idl30
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp107
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h78
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp107
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h81
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl4
155 files changed, 14801 insertions, 10956 deletions
diff --git a/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp b/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
index a0e573a5f..aed7da6a9 100644
--- a/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
+++ b/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
@@ -28,9 +28,13 @@
#if ENABLE(WEBGL)
#include "ANGLEInstancedArrays.h"
+#if PLATFORM(GTK)
+#include "Extensions3D.h"
+#endif
+
namespace WebCore {
-ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContext* context)
+ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -44,39 +48,38 @@ WebGLExtension::ExtensionName ANGLEInstancedArrays::getName() const
return ANGLEInstancedArraysName;
}
-OwnPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new ANGLEInstancedArrays(context));
-}
-
-bool ANGLEInstancedArrays::supported(WebGLRenderingContext*)
+bool ANGLEInstancedArrays::supported(WebGLRenderingContextBase& context)
{
-#if PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if PLATFORM(COCOA)
+ UNUSED_PARAM(context);
return true;
+#elif PLATFORM(GTK)
+ return context.graphicsContext3D()->getExtensions().supports("GL_ANGLE_instanced_arrays");
#else
+ UNUSED_PARAM(context);
return false;
#endif
}
void ANGLEInstancedArrays::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
{
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return;
- m_context->drawArraysInstanced(mode, first, count, primcount);
+ m_context.drawArraysInstanced(mode, first, count, primcount);
}
void ANGLEInstancedArrays::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
{
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return;
- m_context->drawElementsInstanced(mode, count, type, offset, primcount);
+ m_context.drawElementsInstanced(mode, count, type, offset, primcount);
}
void ANGLEInstancedArrays::vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor)
{
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return;
- m_context->vertexAttribDivisor(index, divisor);
+ m_context.vertexAttribDivisor(index, divisor);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/ANGLEInstancedArrays.h b/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
index f87126fbb..d4138277f 100644
--- a/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
+++ b/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
@@ -23,32 +23,26 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ANGLEInstancedArrays_h
-#define ANGLEInstancedArrays_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class ANGLEInstancedArrays : public WebGLExtension {
+class ANGLEInstancedArrays final : public WebGLExtension {
public:
- static OwnPtr<ANGLEInstancedArrays> create(WebGLRenderingContext*);
+ explicit ANGLEInstancedArrays(WebGLRenderingContextBase&);
virtual ~ANGLEInstancedArrays();
- virtual ExtensionName getName() const;
- static bool supported(WebGLRenderingContext*);
+ ExtensionName getName() const final;
+
+ static bool supported(WebGLRenderingContextBase&);
void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
-
-private:
- ANGLEInstancedArrays(WebGLRenderingContext*);
};
} // namespace WebCore
-
-#endif // ANGLEInstancedArrays_h
diff --git a/Source/WebCore/html/canvas/ANGLEInstancedArrays.idl b/Source/WebCore/html/canvas/ANGLEInstancedArrays.idl
index 95d7ebd3a..bf15db187 100644
--- a/Source/WebCore/html/canvas/ANGLEInstancedArrays.idl
+++ b/Source/WebCore/html/canvas/ANGLEInstancedArrays.idl
@@ -30,7 +30,7 @@
] interface ANGLEInstancedArrays {
const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
- [StrictTypeChecking] void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
- [StrictTypeChecking] void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
- [StrictTypeChecking] void vertexAttribDivisorANGLE(unsigned long index, unsigned long divisor);
+ void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
+ void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
+ void vertexAttribDivisorANGLE(unsigned long index, unsigned long divisor);
};
diff --git a/Source/WebCore/html/canvas/CanvasContextAttributes.cpp b/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
deleted file mode 100644
index d3d0398af..000000000
--- a/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2010, Google 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:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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.
- */
-
-#include "config.h"
-
-#include "CanvasContextAttributes.h"
-
-namespace WebCore {
-
-CanvasContextAttributes::CanvasContextAttributes()
-{
-}
-
-CanvasContextAttributes::~CanvasContextAttributes()
-{
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasContextAttributes.h b/Source/WebCore/html/canvas/CanvasContextAttributes.h
deleted file mode 100644
index 97483b366..000000000
--- a/Source/WebCore/html/canvas/CanvasContextAttributes.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2010, Google 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:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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 CanvasContextAttributes_h
-#define CanvasContextAttributes_h
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-// A base class for any attributes that are needed which would affect
-// the creation of the Canvas's rendering context. Currently only the
-// WebGLRenderingContext uses this mechanism.
-
-class CanvasContextAttributes : public RefCounted<CanvasContextAttributes> {
- public:
- virtual ~CanvasContextAttributes();
-
- protected:
- CanvasContextAttributes();
-};
-
-} // namespace WebCore
-
-#endif // CanvasContextAttributes_h
diff --git a/Source/WebCore/html/canvas/CanvasGradient.cpp b/Source/WebCore/html/canvas/CanvasGradient.cpp
index 8a7ace0cf..a5efa3296 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.cpp
+++ b/Source/WebCore/html/canvas/CanvasGradient.cpp
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -27,48 +27,38 @@
#include "config.h"
#include "CanvasGradient.h"
-#include "CanvasPattern.h"
#include "CanvasStyle.h"
-#include "CSSParser.h"
#include "ExceptionCode.h"
namespace WebCore {
CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1)
: m_gradient(Gradient::create(p0, p1))
-#if ENABLE(DASHBOARD_SUPPORT)
- , m_dashbardCompatibilityMode(false)
-#endif
{
}
CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
: m_gradient(Gradient::create(p0, r0, p1, r1))
-#if ENABLE(DASHBOARD_SUPPORT)
- , m_dashbardCompatibilityMode(false)
-#endif
{
}
-void CanvasGradient::addColorStop(float value, const String& color, ExceptionCode& ec)
+ExceptionOr<void> CanvasGradient::addColorStop(float value, const String& colorString)
{
- if (!(value >= 0 && value <= 1.0f)) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (!(value >= 0 && value <= 1))
+ return Exception { INDEX_SIZE_ERR };
- RGBA32 rgba = 0;
- if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
+ // FIXME: Passing null for canvas means this won't work for current color. Is that OK?
+ Color color = parseColorOrCurrentColor(colorString, nullptr /*canvas*/);
+ if (!color.isValid()) {
#if ENABLE(DASHBOARD_SUPPORT)
- if (!m_dashbardCompatibilityMode)
- ec = SYNTAX_ERR;
-#else
- ec = SYNTAX_ERR;
+ if (m_dashboardCompatibilityMode)
+ return { };
#endif
- return;
+ return Exception { SYNTAX_ERR };
}
- m_gradient->addColorStop(value, Color(rgba));
+ m_gradient->addColorStop(value, color);
+ return { };
}
-} // namespace
+}
diff --git a/Source/WebCore/html/canvas/CanvasGradient.h b/Source/WebCore/html/canvas/CanvasGradient.h
index 8529d584d..bf7501338 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.h
+++ b/Source/WebCore/html/canvas/CanvasGradient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,47 +24,41 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasGradient_h
-#define CanvasGradient_h
+#pragma once
+#include "ExceptionOr.h"
#include "Gradient.h"
-#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
namespace WebCore {
- typedef int ExceptionCode;
+class CanvasGradient : public RefCounted<CanvasGradient> {
+public:
+ static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
+ {
+ return adoptRef(*new CanvasGradient(p0, p1));
+ }
+ static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
+ {
+ return adoptRef(*new CanvasGradient(p0, r0, p1, r1));
+ }
- class CanvasGradient : public RefCounted<CanvasGradient> {
- public:
- static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
- {
- return adoptRef(new CanvasGradient(p0, p1));
- }
- static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
- {
- return adoptRef(new CanvasGradient(p0, r0, p1, r1));
- }
-
- Gradient* gradient() const { return m_gradient.get(); }
+ Gradient& gradient() { return m_gradient; }
+ const Gradient& gradient() const { return m_gradient; }
- void addColorStop(float value, const String& color, ExceptionCode&);
+ ExceptionOr<void> addColorStop(float value, const String& color);
#if ENABLE(DASHBOARD_SUPPORT)
- void setDashboardCompatibilityMode() { m_dashbardCompatibilityMode = true; }
+ void setDashboardCompatibilityMode() { m_dashboardCompatibilityMode = true; }
#endif
- private:
- CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
- CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
-
- RefPtr<Gradient> m_gradient;
+private:
+ CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
+ CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
+
+ Ref<Gradient> m_gradient;
#if ENABLE(DASHBOARD_SUPPORT)
- bool m_dashbardCompatibilityMode;
+ bool m_dashboardCompatibilityMode { false };
#endif
- };
-
-} //namespace
+};
-#endif
+}
diff --git a/Source/WebCore/html/canvas/CanvasGradient.idl b/Source/WebCore/html/canvas/CanvasGradient.idl
index 793be9275..d9c9d0931 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.idl
+++ b/Source/WebCore/html/canvas/CanvasGradient.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -22,12 +22,9 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
[
ImplementationLacksVTable,
] interface CanvasGradient {
-
- [RaisesException] void addColorStop([Default=Undefined] optional float offset,
- [Default=Undefined] optional DOMString color);
-
+ [MayThrowException] void addColorStop(float offset, DOMString color);
};
-
diff --git a/Source/WebCore/html/canvas/CanvasPathMethods.cpp b/Source/WebCore/html/canvas/CanvasPath.cpp
index 9332700e7..a7ff3c947 100644
--- a/Source/WebCore/html/canvas/CanvasPathMethods.cpp
+++ b/Source/WebCore/html/canvas/CanvasPath.cpp
@@ -33,15 +33,16 @@
*/
#include "config.h"
-#include "CanvasPathMethods.h"
+#include "CanvasPath.h"
+#include "AffineTransform.h"
#include "ExceptionCode.h"
#include "FloatRect.h"
#include <wtf/MathExtras.h>
namespace WebCore {
-void CanvasPathMethods::closePath()
+void CanvasPath::closePath()
{
if (m_path.isEmpty())
return;
@@ -51,7 +52,7 @@ void CanvasPathMethods::closePath()
m_path.closeSubpath();
}
-void CanvasPathMethods::moveTo(float x, float y)
+void CanvasPath::moveTo(float x, float y)
{
if (!std::isfinite(x) || !std::isfinite(y))
return;
@@ -60,7 +61,12 @@ void CanvasPathMethods::moveTo(float x, float y)
m_path.moveTo(FloatPoint(x, y));
}
-void CanvasPathMethods::lineTo(float x, float y)
+void CanvasPath::lineTo(FloatPoint point)
+{
+ lineTo(point.x(), point.y());
+}
+
+void CanvasPath::lineTo(float x, float y)
{
if (!std::isfinite(x) || !std::isfinite(y))
return;
@@ -74,7 +80,7 @@ void CanvasPathMethods::lineTo(float x, float y)
m_path.addLineTo(p1);
}
-void CanvasPathMethods::quadraticCurveTo(float cpx, float cpy, float x, float y)
+void CanvasPath::quadraticCurveTo(float cpx, float cpy, float x, float y)
{
if (!std::isfinite(cpx) || !std::isfinite(cpy) || !std::isfinite(x) || !std::isfinite(y))
return;
@@ -89,7 +95,7 @@ void CanvasPathMethods::quadraticCurveTo(float cpx, float cpy, float x, float y)
m_path.addQuadCurveTo(cp, p1);
}
-void CanvasPathMethods::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
+void CanvasPath::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
{
if (!std::isfinite(cp1x) || !std::isfinite(cp1y) || !std::isfinite(cp2x) || !std::isfinite(cp2y) || !std::isfinite(x) || !std::isfinite(y))
return;
@@ -105,19 +111,16 @@ void CanvasPathMethods::bezierCurveTo(float cp1x, float cp1y, float cp2x, float
m_path.addBezierCurveTo(cp1, cp2, p1);
}
-void CanvasPathMethods::arcTo(float x1, float y1, float x2, float y2, float r, ExceptionCode& ec)
+ExceptionOr<void> CanvasPath::arcTo(float x1, float y1, float x2, float y2, float r)
{
- ec = 0;
if (!std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(x2) || !std::isfinite(y2) || !std::isfinite(r))
- return;
+ return { };
- if (r < 0) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (r < 0)
+ return Exception { INDEX_SIZE_ERR };
if (!hasInvertibleTransform())
- return;
+ return { };
FloatPoint p1 = FloatPoint(x1, y1);
FloatPoint p2 = FloatPoint(x2, y2);
@@ -128,42 +131,96 @@ void CanvasPathMethods::arcTo(float x1, float y1, float x2, float y2, float r, E
lineTo(x1, y1);
else
m_path.addArcTo(p1, p2, r);
+
+ return { };
}
-void CanvasPathMethods::arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode& ec)
+static void normalizeAngles(float& startAngle, float& endAngle, bool anticlockwise)
{
- ec = 0;
- if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(r) || !std::isfinite(sa) || !std::isfinite(ea))
- return;
+ float newStartAngle = startAngle;
+ if (newStartAngle < 0)
+ newStartAngle = (2 * piFloat) + fmodf(newStartAngle, -(2 * piFloat));
+ else
+ newStartAngle = fmodf(newStartAngle, 2 * piFloat);
- if (r < 0) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ float delta = newStartAngle - startAngle;
+ startAngle = newStartAngle;
+ endAngle = endAngle + delta;
+ ASSERT(newStartAngle >= 0 && newStartAngle < 2 * piFloat);
+
+ if (anticlockwise && startAngle - endAngle >= 2 * piFloat)
+ endAngle = startAngle - 2 * piFloat;
+ else if (!anticlockwise && endAngle - startAngle >= 2 * piFloat)
+ endAngle = startAngle + 2 * piFloat;
+}
+
+ExceptionOr<void> CanvasPath::arc(float x, float y, float radius, float startAngle, float endAngle, bool anticlockwise)
+{
+ if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
+ return { };
+
+ if (radius < 0)
+ return Exception { INDEX_SIZE_ERR };
- if (!r || sa == ea) {
+ if (!hasInvertibleTransform())
+ return { };
+
+ normalizeAngles(startAngle, endAngle, anticlockwise);
+
+ if (!radius || startAngle == endAngle) {
// The arc is empty but we still need to draw the connecting line.
- lineTo(x + r * cosf(sa), y + r * sinf(sa));
- return;
+ lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle));
+ return { };
}
+ m_path.addArc(FloatPoint(x, y), radius, startAngle, endAngle, anticlockwise);
+ return { };
+}
+
+ExceptionOr<void> CanvasPath::ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise)
+{
+ if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !std::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
+ return { };
+
+ if (radiusX < 0 || radiusY < 0)
+ return Exception { INDEX_SIZE_ERR };
+
if (!hasInvertibleTransform())
- return;
+ return { };
- // If 'sa' and 'ea' differ by more than 2Pi, just add a circle starting/ending at 'sa'.
- if (anticlockwise && sa - ea >= 2 * piFloat) {
- m_path.addArc(FloatPoint(x, y), r, sa, sa - 2 * piFloat, anticlockwise);
- return;
+ normalizeAngles(startAngle, endAngle, anticlockwise);
+
+ if ((!radiusX && !radiusY) || startAngle == endAngle) {
+ AffineTransform transform;
+ transform.translate(x, y).rotate(rad2deg(rotation));
+
+ lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(startAngle), radiusY * sinf(startAngle))));
+ return { };
}
- if (!anticlockwise && ea - sa >= 2 * piFloat) {
- m_path.addArc(FloatPoint(x, y), r, sa, sa + 2 * piFloat, anticlockwise);
- return;
+
+ if (!radiusX || !radiusY) {
+ AffineTransform transform;
+ transform.translate(x, y).rotate(rad2deg(rotation));
+
+ lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(startAngle), radiusY * sinf(startAngle))));
+
+ if (!anticlockwise) {
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; angle < endAngle; angle += piOverTwoFloat)
+ lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(angle), radiusY * sinf(angle))));
+ } else {
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); angle > endAngle; angle -= piOverTwoFloat)
+ lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(angle), radiusY * sinf(angle))));
+ }
+
+ lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(endAngle), radiusY * sinf(endAngle))));
+ return { };
}
- m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
+ m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
+ return { };
}
-void CanvasPathMethods::rect(float x, float y, float width, float height)
+void CanvasPath::rect(float x, float y, float width, float height)
{
if (!hasInvertibleTransform())
return;
diff --git a/Source/WebCore/html/canvas/CanvasPathMethods.h b/Source/WebCore/html/canvas/CanvasPath.h
index 041808df1..e752560b8 100644
--- a/Source/WebCore/html/canvas/CanvasPathMethods.h
+++ b/Source/WebCore/html/canvas/CanvasPath.h
@@ -26,39 +26,38 @@
* SUCH DAMAGE.
*/
-#ifndef CanvasPathMethods_h
-#define CanvasPathMethods_h
+#pragma once
+#include "ExceptionOr.h"
#include "Path.h"
namespace WebCore {
-class FloatRect;
-
-typedef int ExceptionCode;
-
-class CanvasPathMethods {
+class CanvasPath {
public:
- virtual ~CanvasPathMethods() { }
+ virtual ~CanvasPath() { }
void closePath();
void moveTo(float x, float y);
void lineTo(float x, float y);
void quadraticCurveTo(float cpx, float cpy, float x, float y);
void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
- void arcTo(float x0, float y0, float x1, float y1, float radius, ExceptionCode&);
- void arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode&);
+ ExceptionOr<void> arcTo(float x0, float y0, float x1, float y1, float radius);
+ ExceptionOr<void> arc(float x, float y, float r, float sa, float ea, bool anticlockwise);
+ ExceptionOr<void> ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngled, bool anticlockwise);
void rect(float x, float y, float width, float height);
protected:
- CanvasPathMethods() { }
- CanvasPathMethods(const Path& path) : m_path(path) { }
+ CanvasPath() { }
+ CanvasPath(const Path& path)
+ : m_path(path)
+ { }
virtual bool hasInvertibleTransform() const { return true; }
+ void lineTo(FloatPoint);
+
Path m_path;
};
}
-
-#endif
diff --git a/Source/WebCore/html/canvas/CanvasPath.idl b/Source/WebCore/html/canvas/CanvasPath.idl
new file mode 100644
index 000000000..da0cc878b
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPath.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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.
+ */
+
+[
+ NoInterfaceObject
+] interface CanvasPath {
+ void closePath();
+ void moveTo(unrestricted double x, unrestricted double y);
+ void lineTo(unrestricted double x, unrestricted double y);
+ void quadraticCurveTo(unrestricted double cpx, unrestricted double cpy, unrestricted double x, unrestricted double y);
+ void bezierCurveTo(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y);
+ [MayThrowException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius);
+ // [MayThrowException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation);
+ void rect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
+ [MayThrowException] void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
+ [MayThrowException] void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
+};
diff --git a/Source/WebCore/html/canvas/CanvasPattern.cpp b/Source/WebCore/html/canvas/CanvasPattern.cpp
index a4557418e..e95eb6330 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.cpp
+++ b/Source/WebCore/html/canvas/CanvasPattern.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,20 +26,19 @@
#include "config.h"
#include "CanvasPattern.h"
-#include "ExceptionCode.h"
#include "Image.h"
#include "Pattern.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
-PassRefPtr<CanvasPattern> CanvasPattern::create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+Ref<CanvasPattern> CanvasPattern::create(Ref<Image>&& image, bool repeatX, bool repeatY, bool originClean)
{
- return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
+ return adoptRef(*new CanvasPattern(WTFMove(image), repeatX, repeatY, originClean));
}
-CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
- : m_pattern(Pattern::create(image, repeatX, repeatY))
+CanvasPattern::CanvasPattern(Ref<Image>&& image, bool repeatX, bool repeatY, bool originClean)
+ : m_pattern(Pattern::create(WTFMove(image), repeatX, repeatY))
, m_originClean(originClean)
{
}
@@ -48,30 +47,29 @@ CanvasPattern::~CanvasPattern()
{
}
-void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& repeatY, ExceptionCode& ec)
+bool CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& repeatY)
{
- ec = 0;
if (type.isEmpty() || type == "repeat") {
repeatX = true;
repeatY = true;
- return;
+ return true;
}
if (type == "no-repeat") {
repeatX = false;
repeatY = false;
- return;
+ return true;
}
if (type == "repeat-x") {
repeatX = true;
repeatY = false;
- return;
+ return true;
}
if (type == "repeat-y") {
repeatX = false;
repeatY = true;
- return;
+ return true;
}
- ec = SYNTAX_ERR;
+ return false;
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasPattern.h b/Source/WebCore/html/canvas/CanvasPattern.h
index 9fed5759a..b8faaab1a 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.h
+++ b/Source/WebCore/html/canvas/CanvasPattern.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,39 +23,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasPattern_h
-#define CanvasPattern_h
+#pragma once
#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
namespace WebCore {
class Image;
class Pattern;
-typedef int ExceptionCode;
-
class CanvasPattern : public RefCounted<CanvasPattern> {
public:
- static PassRefPtr<CanvasPattern> create(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
+ static Ref<CanvasPattern> create(Ref<Image>&&, bool repeatX, bool repeatY, bool originClean);
~CanvasPattern();
- static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
+ static bool parseRepetitionType(const String&, bool& repeatX, bool& repeatY);
- Pattern* pattern() const { return m_pattern.get(); }
+ Pattern& pattern() { return m_pattern; }
+ const Pattern& pattern() const { return m_pattern; }
bool originClean() const { return m_originClean; }
private:
- CanvasPattern(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
+ CanvasPattern(Ref<Image>&&, bool repeatX, bool repeatY, bool originClean);
- RefPtr<Pattern> m_pattern;
+ Ref<Pattern> m_pattern;
bool m_originClean;
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/canvas/CanvasPattern.idl b/Source/WebCore/html/canvas/CanvasPattern.idl
index 4ded936d7..733d5511f 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.idl
+++ b/Source/WebCore/html/canvas/CanvasPattern.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/CanvasProxy.cpp b/Source/WebCore/html/canvas/CanvasProxy.cpp
index 3006ed65e..baf0a0846 100644
--- a/Source/WebCore/html/canvas/CanvasProxy.cpp
+++ b/Source/WebCore/html/canvas/CanvasProxy.cpp
@@ -32,9 +32,9 @@
namespace WebCore {
-PassRefPtr<CanvasProxy> CanvasProxy::create()
+Ref<CanvasProxy> CanvasProxy::create()
{
- return adoptRef(new CanvasProxy());
+ return adoptRef(*new CanvasProxy());
}
CanvasProxy::CanvasProxy()
diff --git a/Source/WebCore/html/canvas/CanvasProxy.h b/Source/WebCore/html/canvas/CanvasProxy.h
index 2591f0eb0..0dcfb1fb9 100644
--- a/Source/WebCore/html/canvas/CanvasProxy.h
+++ b/Source/WebCore/html/canvas/CanvasProxy.h
@@ -24,17 +24,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasProxy_h
-#define CanvasProxy_h
+#pragma once
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class CanvasProxy : public RefCounted<CanvasProxy> {
public:
- static PassRefPtr<CanvasProxy> create();
+ static Ref<CanvasProxy> create();
virtual ~CanvasProxy();
@@ -43,5 +41,3 @@ private:
};
} // namespace WebCore
-
-#endif // CanvasProxy_h
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
index e8bf03a90..2b718e6ba 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -36,35 +36,48 @@
namespace WebCore {
-CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
+CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement& canvas)
: m_canvas(canvas)
{
}
bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
{
- if (canvas()->originClean() && pattern && !pattern->originClean())
+ if (canvas().originClean() && pattern && !pattern->originClean())
return true;
return false;
}
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
{
- if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
+ if (canvas().originClean() && sourceCanvas && !sourceCanvas->originClean())
return true;
return false;
}
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* element)
{
- if (!image || !canvas()->originClean())
+ if (!element || !canvas().originClean())
return false;
- CachedImage* cachedImage = image->cachedImage();
- if (!cachedImage->image()->hasSingleSecurityOrigin())
+ auto* cachedImage = element->cachedImage();
+ if (!cachedImage)
+ return false;
+
+ auto* image = cachedImage->image();
+ if (!image)
+ return false;
+
+ if (!image->hasSingleSecurityOrigin())
+ return true;
+
+ if (!cachedImage->isCORSSameOrigin())
return true;
- return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
+ ASSERT(canvas().securityOrigin());
+ ASSERT(cachedImage->origin());
+ ASSERT(canvas().securityOrigin()->toString() == cachedImage->origin()->toString());
+ return false;
}
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
@@ -74,7 +87,7 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
// to test the finalURL. Please be careful when fixing this issue not to
// make currentSrc be the final URL because then the
// HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
- if (!video || !canvas()->originClean())
+ if (!video || !canvas().originClean())
return false;
if (!video->hasSingleSecurityOrigin())
@@ -92,23 +105,19 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
bool CanvasRenderingContext::wouldTaintOrigin(const URL& url)
{
- if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
+ if (!canvas().originClean())
return false;
- if (canvas()->securityOrigin()->taintsCanvas(url))
- return true;
-
if (url.protocolIsData())
return false;
- m_cleanURLs.add(url.string());
- return false;
+ return !canvas().securityOrigin()->canRequest(url);
}
void CanvasRenderingContext::checkOrigin(const URL& url)
{
if (wouldTaintOrigin(url))
- canvas()->setOriginTainted();
+ canvas().setOriginTainted();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
index b5b2781f7..759080f53 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasRenderingContext_h
-#define CanvasRenderingContext_h
+#pragma once
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
@@ -47,22 +46,21 @@ class CanvasRenderingContext : public ScriptWrappable {
public:
virtual ~CanvasRenderingContext() { }
- void ref() { m_canvas->ref(); }
- void deref() { m_canvas->deref(); }
- HTMLCanvasElement* canvas() const { return m_canvas; }
+ void ref() { m_canvas.ref(); }
+ void deref() { m_canvas.deref(); }
+ HTMLCanvasElement& canvas() const { return m_canvas; }
virtual bool is2d() const { return false; }
- virtual bool is3d() const { return false; }
+ virtual bool isWebGL1() const { return false; }
+ virtual bool isWebGL2() const { return false; }
+ bool is3d() const { return isWebGL1() || isWebGL2(); }
virtual bool isAccelerated() const { return false; }
virtual void paintRenderingResultsToCanvas() {}
-
-#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const { return 0; }
-#endif
protected:
- CanvasRenderingContext(HTMLCanvasElement*);
+ CanvasRenderingContext(HTMLCanvasElement&);
bool wouldTaintOrigin(const CanvasPattern*);
bool wouldTaintOrigin(const HTMLCanvasElement*);
bool wouldTaintOrigin(const HTMLImageElement*);
@@ -72,15 +70,17 @@ protected:
template<class T> void checkOrigin(const T* arg)
{
if (wouldTaintOrigin(arg))
- canvas()->setOriginTainted();
+ canvas().setOriginTainted();
}
void checkOrigin(const URL&);
private:
- HTMLCanvasElement* m_canvas;
- HashSet<String> m_cleanURLs;
+ HTMLCanvasElement& m_canvas;
};
} // namespace WebCore
-#endif
+#define SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(ToValueTypeName, predicate) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
+ static bool isType(const WebCore::CanvasRenderingContext& context) { return context.predicate; } \
+SPECIALIZE_TYPE_TRAITS_END()
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index dc55df0e3..5bd1c76f2 100755..100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
* Copyright (C) 2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2013, 2014 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -17,10 +17,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -33,6 +33,7 @@
#include "config.h"
#include "CanvasRenderingContext2D.h"
+#include "BitmapImage.h"
#include "CSSFontSelector.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
@@ -40,47 +41,68 @@
#include "CanvasGradient.h"
#include "CanvasPattern.h"
#include "DOMPath.h"
-#include "ExceptionCodePlaceholder.h"
+#include "DisplayListRecorder.h"
+#include "DisplayListReplayer.h"
#include "FloatQuad.h"
-#include "FontCache.h"
-#include "GraphicsContext.h"
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
#include "ImageData.h"
#include "RenderElement.h"
+#include "RenderImage.h"
+#include "RenderLayer.h"
+#include "RenderTheme.h"
#include "SecurityOrigin.h"
#include "StrokeStyleApplier.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
#include "TextMetrics.h"
#include "TextRun.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-#include "RenderLayer.h"
-#endif
-
+#include "TextStream.h"
#include <wtf/CheckedArithmetic.h>
#include <wtf/MathExtras.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>
-#if USE(CG)
-#if !PLATFORM(IOS)
+#if USE(CG) && !PLATFORM(IOS)
#include <ApplicationServices/ApplicationServices.h>
-#endif // !PLATFORM(IOS)
-#endif
-
-#if PLATFORM(IOS)
-#include "Settings.h"
#endif
namespace WebCore {
using namespace HTMLNames;
+#if USE(CG)
+const CanvasRenderingContext2D::ImageSmoothingQuality defaultSmoothingQuality = CanvasRenderingContext2D::ImageSmoothingQuality::Low;
+#else
+const CanvasRenderingContext2D::ImageSmoothingQuality defaultSmoothingQuality = CanvasRenderingContext2D::ImageSmoothingQuality::Medium;
+#endif
+
static const int defaultFontSize = 10;
static const char* const defaultFontFamily = "sans-serif";
static const char* const defaultFont = "10px sans-serif";
+struct DisplayListDrawingContext {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ GraphicsContext context;
+ DisplayList::Recorder recorder;
+ DisplayList::DisplayList displayList;
+
+ DisplayListDrawingContext(const FloatRect& clip)
+ : recorder(context, displayList, clip, AffineTransform())
+ {
+ }
+};
+
+typedef HashMap<const CanvasRenderingContext2D*, std::unique_ptr<DisplayList::DisplayList>> ContextDisplayListHashMap;
+
+static ContextDisplayListHashMap& contextDisplayListMap()
+{
+ static NeverDestroyed<ContextDisplayListHashMap> sharedHashMap;
+ return sharedHashMap;
+}
+
class CanvasStrokeStyleApplier : public StrokeStyleApplier {
public:
CanvasStrokeStyleApplier(CanvasRenderingContext2D* canvasContext)
@@ -88,7 +110,7 @@ public:
{
}
- virtual void strokeStyle(GraphicsContext* c) override
+ void strokeStyle(GraphicsContext* c) override
{
c->setStrokeThickness(m_canvasContext->lineWidth());
c->setLineCap(m_canvasContext->getLineCap());
@@ -105,10 +127,9 @@ private:
CanvasRenderingContext2D* m_canvasContext;
};
-CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
+CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement& canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
: CanvasRenderingContext(canvas)
, m_stateStack(1)
- , m_unrealizedSaveCount(0)
, m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
#if ENABLE(DASHBOARD_SUPPORT)
, m_usesDashboardCompatibilityMode(usesDashboardCompatibilityMode)
@@ -125,7 +146,7 @@ void CanvasRenderingContext2D::unwindStateStack()
// is cleared before destruction, to avoid assertions in the
// GraphicsContext dtor.
if (size_t stackSize = m_stateStack.size()) {
- if (GraphicsContext* context = canvas()->existingDrawingContext()) {
+ if (GraphicsContext* context = canvas().existingDrawingContext()) {
while (--stackSize)
context->restore();
}
@@ -137,14 +158,17 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
#if !ASSERT_DISABLED
unwindStateStack();
#endif
+
+ if (UNLIKELY(tracksDisplayListReplay()))
+ contextDisplayListMap().remove(this);
}
bool CanvasRenderingContext2D::isAccelerated() const
{
#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
- if (!canvas()->hasCreatedImageBuffer())
+ if (!canvas().hasCreatedImageBuffer())
return false;
- GraphicsContext* context = drawingContext();
+ auto* context = drawingContext();
return context && context->isAcceleratedContext();
#else
return false;
@@ -158,58 +182,59 @@ void CanvasRenderingContext2D::reset()
m_stateStack.first() = State();
m_path.clear();
m_unrealizedSaveCount = 0;
+
+ m_recordingContext = nullptr;
}
CanvasRenderingContext2D::State::State()
- : m_strokeStyle(Color::black)
- , m_fillStyle(Color::black)
- , m_lineWidth(1)
- , m_lineCap(ButtCap)
- , m_lineJoin(MiterJoin)
- , m_miterLimit(10)
- , m_shadowBlur(0)
- , m_shadowColor(Color::transparent)
- , m_globalAlpha(1)
- , m_globalComposite(CompositeSourceOver)
- , m_globalBlend(BlendModeNormal)
- , m_hasInvertibleTransform(true)
- , m_lineDashOffset(0)
- , m_imageSmoothingEnabled(true)
- , m_textAlign(StartTextAlign)
- , m_textBaseline(AlphabeticTextBaseline)
- , m_unparsedFont(defaultFont)
- , m_realizedFont(false)
+ : strokeStyle(Color::black)
+ , fillStyle(Color::black)
+ , lineWidth(1)
+ , lineCap(ButtCap)
+ , lineJoin(MiterJoin)
+ , miterLimit(10)
+ , shadowBlur(0)
+ , shadowColor(Color::transparent)
+ , globalAlpha(1)
+ , globalComposite(CompositeSourceOver)
+ , globalBlend(BlendModeNormal)
+ , hasInvertibleTransform(true)
+ , lineDashOffset(0)
+ , imageSmoothingEnabled(true)
+ , imageSmoothingQuality(defaultSmoothingQuality)
+ , textAlign(StartTextAlign)
+ , textBaseline(AlphabeticTextBaseline)
+ , direction(Direction::Inherit)
+ , unparsedFont(defaultFont)
{
}
CanvasRenderingContext2D::State::State(const State& other)
- : FontSelectorClient()
- , m_unparsedStrokeColor(other.m_unparsedStrokeColor)
- , m_unparsedFillColor(other.m_unparsedFillColor)
- , m_strokeStyle(other.m_strokeStyle)
- , m_fillStyle(other.m_fillStyle)
- , m_lineWidth(other.m_lineWidth)
- , m_lineCap(other.m_lineCap)
- , m_lineJoin(other.m_lineJoin)
- , m_miterLimit(other.m_miterLimit)
- , m_shadowOffset(other.m_shadowOffset)
- , m_shadowBlur(other.m_shadowBlur)
- , m_shadowColor(other.m_shadowColor)
- , m_globalAlpha(other.m_globalAlpha)
- , m_globalComposite(other.m_globalComposite)
- , m_globalBlend(other.m_globalBlend)
- , m_transform(other.m_transform)
- , m_hasInvertibleTransform(other.m_hasInvertibleTransform)
- , m_lineDashOffset(other.m_lineDashOffset)
- , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled)
- , m_textAlign(other.m_textAlign)
- , m_textBaseline(other.m_textBaseline)
- , m_unparsedFont(other.m_unparsedFont)
- , m_font(other.m_font)
- , m_realizedFont(other.m_realizedFont)
-{
- if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ : unparsedStrokeColor(other.unparsedStrokeColor)
+ , unparsedFillColor(other.unparsedFillColor)
+ , strokeStyle(other.strokeStyle)
+ , fillStyle(other.fillStyle)
+ , lineWidth(other.lineWidth)
+ , lineCap(other.lineCap)
+ , lineJoin(other.lineJoin)
+ , miterLimit(other.miterLimit)
+ , shadowOffset(other.shadowOffset)
+ , shadowBlur(other.shadowBlur)
+ , shadowColor(other.shadowColor)
+ , globalAlpha(other.globalAlpha)
+ , globalComposite(other.globalComposite)
+ , globalBlend(other.globalBlend)
+ , transform(other.transform)
+ , hasInvertibleTransform(other.hasInvertibleTransform)
+ , lineDashOffset(other.lineDashOffset)
+ , imageSmoothingEnabled(other.imageSmoothingEnabled)
+ , imageSmoothingQuality(other.imageSmoothingQuality)
+ , textAlign(other.textAlign)
+ , textBaseline(other.textBaseline)
+ , direction(other.direction)
+ , unparsedFont(other.unparsedFont)
+ , font(other.font)
+{
}
CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
@@ -217,50 +242,119 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
if (this == &other)
return *this;
- if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
-
- m_unparsedStrokeColor = other.m_unparsedStrokeColor;
- m_unparsedFillColor = other.m_unparsedFillColor;
- m_strokeStyle = other.m_strokeStyle;
- m_fillStyle = other.m_fillStyle;
- m_lineWidth = other.m_lineWidth;
- m_lineCap = other.m_lineCap;
- m_lineJoin = other.m_lineJoin;
- m_miterLimit = other.m_miterLimit;
- m_shadowOffset = other.m_shadowOffset;
- m_shadowBlur = other.m_shadowBlur;
- m_shadowColor = other.m_shadowColor;
- m_globalAlpha = other.m_globalAlpha;
- m_globalComposite = other.m_globalComposite;
- m_globalBlend = other.m_globalBlend;
- m_transform = other.m_transform;
- m_hasInvertibleTransform = other.m_hasInvertibleTransform;
- m_imageSmoothingEnabled = other.m_imageSmoothingEnabled;
- m_textAlign = other.m_textAlign;
- m_textBaseline = other.m_textBaseline;
- m_unparsedFont = other.m_unparsedFont;
+ unparsedStrokeColor = other.unparsedStrokeColor;
+ unparsedFillColor = other.unparsedFillColor;
+ strokeStyle = other.strokeStyle;
+ fillStyle = other.fillStyle;
+ lineWidth = other.lineWidth;
+ lineCap = other.lineCap;
+ lineJoin = other.lineJoin;
+ miterLimit = other.miterLimit;
+ shadowOffset = other.shadowOffset;
+ shadowBlur = other.shadowBlur;
+ shadowColor = other.shadowColor;
+ globalAlpha = other.globalAlpha;
+ globalComposite = other.globalComposite;
+ globalBlend = other.globalBlend;
+ transform = other.transform;
+ hasInvertibleTransform = other.hasInvertibleTransform;
+ imageSmoothingEnabled = other.imageSmoothingEnabled;
+ imageSmoothingQuality = other.imageSmoothingQuality;
+ textAlign = other.textAlign;
+ textBaseline = other.textBaseline;
+ direction = other.direction;
+ unparsedFont = other.unparsedFont;
+ font = other.font;
+
+ return *this;
+}
+
+CanvasRenderingContext2D::FontProxy::~FontProxy()
+{
+ if (realized())
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+}
+
+CanvasRenderingContext2D::FontProxy::FontProxy(const FontProxy& other)
+ : m_font(other.m_font)
+{
+ if (realized())
+ m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+}
+
+auto CanvasRenderingContext2D::FontProxy::operator=(const FontProxy& other) -> FontProxy&
+{
+ if (realized())
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+
m_font = other.m_font;
- m_realizedFont = other.m_realizedFont;
- if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ if (realized())
+ m_font.fontSelector()->registerForInvalidationCallbacks(*this);
return *this;
}
-CanvasRenderingContext2D::State::~State()
+inline void CanvasRenderingContext2D::FontProxy::update(FontSelector& selector)
{
- if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+ ASSERT(&selector == m_font.fontSelector()); // This is an invariant. We should only ever be registered for callbacks on m_font.m_fonts.m_fontSelector.
+ if (realized())
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+ m_font.update(&selector);
+ if (realized())
+ m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+ ASSERT(&selector == m_font.fontSelector());
}
-void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+void CanvasRenderingContext2D::FontProxy::fontsNeedUpdate(FontSelector& selector)
{
- ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
- ASSERT(m_realizedFont);
+ ASSERT_ARG(selector, &selector == m_font.fontSelector());
+ ASSERT(realized());
+
+ update(selector);
+}
- m_font.update(fontSelector);
+inline void CanvasRenderingContext2D::FontProxy::initialize(FontSelector& fontSelector, const RenderStyle& newStyle)
+{
+ // Beware! m_font.fontSelector() might not point to document.fontSelector()!
+ ASSERT(newStyle.fontCascade().fontSelector() == &fontSelector);
+ if (realized())
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+ m_font = newStyle.fontCascade();
+ m_font.update(&fontSelector);
+ ASSERT(&fontSelector == m_font.fontSelector());
+ m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+}
+
+inline FontMetrics CanvasRenderingContext2D::FontProxy::fontMetrics() const
+{
+ return m_font.fontMetrics();
+}
+
+inline const FontCascadeDescription& CanvasRenderingContext2D::FontProxy::fontDescription() const
+{
+ return m_font.fontDescription();
+}
+
+inline float CanvasRenderingContext2D::FontProxy::width(const TextRun& textRun) const
+{
+ return m_font.width(textRun);
+}
+
+inline void CanvasRenderingContext2D::FontProxy::drawBidiText(GraphicsContext& context, const TextRun& run, const FloatPoint& point, FontCascade::CustomFontNotReadyAction action) const
+{
+ context.drawBidiText(m_font, run, point, action);
+}
+
+void CanvasRenderingContext2D::realizeSaves()
+{
+ if (m_unrealizedSaveCount)
+ realizeSavesLoop();
+
+ if (m_unrealizedSaveCount) {
+ static NeverDestroyed<String> consoleMessage(ASCIILiteral("CanvasRenderingContext2D.save() has been called without a matching restore() too many times. Ignoring save()."));
+ canvas().document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Error, consoleMessage);
+ }
}
void CanvasRenderingContext2D::realizeSavesLoop()
@@ -269,6 +363,8 @@ void CanvasRenderingContext2D::realizeSavesLoop()
ASSERT(m_stateStack.size() >= 1);
GraphicsContext* context = drawingContext();
do {
+ if (m_stateStack.size() > MaxSaveCount)
+ break;
m_stateStack.append(state());
if (context)
context->save();
@@ -284,9 +380,10 @@ void CanvasRenderingContext2D::restore()
ASSERT(m_stateStack.size() >= 1);
if (m_stateStack.size() <= 1)
return;
- m_path.transform(state().m_transform);
+ m_path.transform(state().transform);
m_stateStack.removeLast();
- m_path.transform(state().m_transform.inverse());
+ if (std::optional<AffineTransform> inverse = state().transform.inverse())
+ m_path.transform(inverse.value());
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -298,25 +395,26 @@ void CanvasRenderingContext2D::setStrokeStyle(CanvasStyle style)
if (!style.isValid())
return;
- if (state().m_strokeStyle.isValid() && state().m_strokeStyle.isEquivalentColor(style))
+ if (state().strokeStyle.isValid() && state().strokeStyle.isEquivalentColor(style))
return;
if (style.isCurrentColor()) {
- if (style.hasOverrideAlpha())
- style = CanvasStyle(colorWithOverrideAlpha(currentColor(canvas()), style.overrideAlpha()));
- else
- style = CanvasStyle(currentColor(canvas()));
+ if (style.hasOverrideAlpha()) {
+ // FIXME: Should not use RGBA32 here.
+ style = CanvasStyle(colorWithOverrideAlpha(currentColor(&canvas()).rgb(), style.overrideAlpha()));
+ } else
+ style = CanvasStyle(currentColor(&canvas()));
} else
checkOrigin(style.canvasPattern());
realizeSaves();
State& state = modifiableState();
- state.m_strokeStyle = style;
+ state.strokeStyle = style;
GraphicsContext* c = drawingContext();
if (!c)
return;
- state.m_strokeStyle.applyStrokeColor(c);
- state.m_unparsedStrokeColor = String();
+ state.strokeStyle.applyStrokeColor(*c);
+ state.unparsedStrokeColor = String();
}
void CanvasRenderingContext2D::setFillStyle(CanvasStyle style)
@@ -324,40 +422,41 @@ void CanvasRenderingContext2D::setFillStyle(CanvasStyle style)
if (!style.isValid())
return;
- if (state().m_fillStyle.isValid() && state().m_fillStyle.isEquivalentColor(style))
+ if (state().fillStyle.isValid() && state().fillStyle.isEquivalentColor(style))
return;
if (style.isCurrentColor()) {
- if (style.hasOverrideAlpha())
- style = CanvasStyle(colorWithOverrideAlpha(currentColor(canvas()), style.overrideAlpha()));
- else
- style = CanvasStyle(currentColor(canvas()));
+ if (style.hasOverrideAlpha()) {
+ // FIXME: Should not use RGBA32 here.
+ style = CanvasStyle(colorWithOverrideAlpha(currentColor(&canvas()).rgb(), style.overrideAlpha()));
+ } else
+ style = CanvasStyle(currentColor(&canvas()));
} else
checkOrigin(style.canvasPattern());
realizeSaves();
State& state = modifiableState();
- state.m_fillStyle = style;
+ state.fillStyle = style;
GraphicsContext* c = drawingContext();
if (!c)
return;
- state.m_fillStyle.applyFillColor(c);
- state.m_unparsedFillColor = String();
+ state.fillStyle.applyFillColor(*c);
+ state.unparsedFillColor = String();
}
float CanvasRenderingContext2D::lineWidth() const
{
- return state().m_lineWidth;
+ return state().lineWidth;
}
void CanvasRenderingContext2D::setLineWidth(float width)
{
if (!(std::isfinite(width) && width > 0))
return;
- if (state().m_lineWidth == width)
+ if (state().lineWidth == width)
return;
realizeSaves();
- modifiableState().m_lineWidth = width;
+ modifiableState().lineWidth = width;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -366,7 +465,7 @@ void CanvasRenderingContext2D::setLineWidth(float width)
String CanvasRenderingContext2D::lineCap() const
{
- return lineCapName(state().m_lineCap);
+ return lineCapName(state().lineCap);
}
void CanvasRenderingContext2D::setLineCap(const String& s)
@@ -374,10 +473,10 @@ void CanvasRenderingContext2D::setLineCap(const String& s)
LineCap cap;
if (!parseLineCap(s, cap))
return;
- if (state().m_lineCap == cap)
+ if (state().lineCap == cap)
return;
realizeSaves();
- modifiableState().m_lineCap = cap;
+ modifiableState().lineCap = cap;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -386,7 +485,7 @@ void CanvasRenderingContext2D::setLineCap(const String& s)
String CanvasRenderingContext2D::lineJoin() const
{
- return lineJoinName(state().m_lineJoin);
+ return lineJoinName(state().lineJoin);
}
void CanvasRenderingContext2D::setLineJoin(const String& s)
@@ -394,10 +493,10 @@ void CanvasRenderingContext2D::setLineJoin(const String& s)
LineJoin join;
if (!parseLineJoin(s, join))
return;
- if (state().m_lineJoin == join)
+ if (state().lineJoin == join)
return;
realizeSaves();
- modifiableState().m_lineJoin = join;
+ modifiableState().lineJoin = join;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -406,17 +505,17 @@ void CanvasRenderingContext2D::setLineJoin(const String& s)
float CanvasRenderingContext2D::miterLimit() const
{
- return state().m_miterLimit;
+ return state().miterLimit;
}
void CanvasRenderingContext2D::setMiterLimit(float limit)
{
if (!(std::isfinite(limit) && limit > 0))
return;
- if (state().m_miterLimit == limit)
+ if (state().miterLimit == limit)
return;
realizeSaves();
- modifiableState().m_miterLimit = limit;
+ modifiableState().miterLimit = limit;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -425,72 +524,72 @@ void CanvasRenderingContext2D::setMiterLimit(float limit)
float CanvasRenderingContext2D::shadowOffsetX() const
{
- return state().m_shadowOffset.width();
+ return state().shadowOffset.width();
}
void CanvasRenderingContext2D::setShadowOffsetX(float x)
{
if (!std::isfinite(x))
return;
- if (state().m_shadowOffset.width() == x)
+ if (state().shadowOffset.width() == x)
return;
realizeSaves();
- modifiableState().m_shadowOffset.setWidth(x);
+ modifiableState().shadowOffset.setWidth(x);
applyShadow();
}
float CanvasRenderingContext2D::shadowOffsetY() const
{
- return state().m_shadowOffset.height();
+ return state().shadowOffset.height();
}
void CanvasRenderingContext2D::setShadowOffsetY(float y)
{
if (!std::isfinite(y))
return;
- if (state().m_shadowOffset.height() == y)
+ if (state().shadowOffset.height() == y)
return;
realizeSaves();
- modifiableState().m_shadowOffset.setHeight(y);
+ modifiableState().shadowOffset.setHeight(y);
applyShadow();
}
float CanvasRenderingContext2D::shadowBlur() const
{
- return state().m_shadowBlur;
+ return state().shadowBlur;
}
void CanvasRenderingContext2D::setShadowBlur(float blur)
{
if (!(std::isfinite(blur) && blur >= 0))
return;
- if (state().m_shadowBlur == blur)
+ if (state().shadowBlur == blur)
return;
realizeSaves();
- modifiableState().m_shadowBlur = blur;
+ modifiableState().shadowBlur = blur;
applyShadow();
}
String CanvasRenderingContext2D::shadowColor() const
{
- return Color(state().m_shadowColor).serialized();
+ return Color(state().shadowColor).serialized();
}
-void CanvasRenderingContext2D::setShadowColor(const String& color)
+void CanvasRenderingContext2D::setShadowColor(const String& colorString)
{
- RGBA32 rgba;
- if (!parseColorOrCurrentColor(rgba, color, canvas()))
+ Color color = parseColorOrCurrentColor(colorString, &canvas());
+ if (!color.isValid())
return;
- if (state().m_shadowColor == rgba)
+ if (state().shadowColor == color)
return;
realizeSaves();
- modifiableState().m_shadowColor = rgba;
+ modifiableState().shadowColor = color;
applyShadow();
}
const Vector<float>& CanvasRenderingContext2D::getLineDash() const
{
- return state().m_lineDash;
+ return state().lineDash;
}
static bool lineDashSequenceIsValid(const Vector<float>& dash)
@@ -508,11 +607,11 @@ void CanvasRenderingContext2D::setLineDash(const Vector<float>& dash)
return;
realizeSaves();
- modifiableState().m_lineDash = dash;
+ modifiableState().lineDash = dash;
// Spec requires the concatenation of two copies the dash list when the
// number of elements is odd
if (dash.size() % 2)
- modifiableState().m_lineDash.appendVector(dash);
+ modifiableState().lineDash.appendVector(dash);
applyLineDash();
}
@@ -523,60 +622,50 @@ void CanvasRenderingContext2D::setWebkitLineDash(const Vector<float>& dash)
return;
realizeSaves();
- modifiableState().m_lineDash = dash;
+ modifiableState().lineDash = dash;
applyLineDash();
}
float CanvasRenderingContext2D::lineDashOffset() const
{
- return state().m_lineDashOffset;
+ return state().lineDashOffset;
}
void CanvasRenderingContext2D::setLineDashOffset(float offset)
{
- if (!std::isfinite(offset) || state().m_lineDashOffset == offset)
+ if (!std::isfinite(offset) || state().lineDashOffset == offset)
return;
realizeSaves();
- modifiableState().m_lineDashOffset = offset;
+ modifiableState().lineDashOffset = offset;
applyLineDash();
}
-float CanvasRenderingContext2D::webkitLineDashOffset() const
-{
- return lineDashOffset();
-}
-
-void CanvasRenderingContext2D::setWebkitLineDashOffset(float offset)
-{
- setLineDashOffset(offset);
-}
-
void CanvasRenderingContext2D::applyLineDash() const
{
GraphicsContext* c = drawingContext();
if (!c)
return;
- DashArray convertedLineDash(state().m_lineDash.size());
- for (size_t i = 0; i < state().m_lineDash.size(); ++i)
- convertedLineDash[i] = static_cast<DashArrayElement>(state().m_lineDash[i]);
- c->setLineDash(convertedLineDash, state().m_lineDashOffset);
+ DashArray convertedLineDash(state().lineDash.size());
+ for (size_t i = 0; i < state().lineDash.size(); ++i)
+ convertedLineDash[i] = static_cast<DashArrayElement>(state().lineDash[i]);
+ c->setLineDash(convertedLineDash, state().lineDashOffset);
}
float CanvasRenderingContext2D::globalAlpha() const
{
- return state().m_globalAlpha;
+ return state().globalAlpha;
}
void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
{
if (!(alpha >= 0 && alpha <= 1))
return;
- if (state().m_globalAlpha == alpha)
+ if (state().globalAlpha == alpha)
return;
realizeSaves();
- modifiableState().m_globalAlpha = alpha;
+ modifiableState().globalAlpha = alpha;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -585,7 +674,7 @@ void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
String CanvasRenderingContext2D::globalCompositeOperation() const
{
- return compositeOperatorName(state().m_globalComposite, state().m_globalBlend);
+ return compositeOperatorName(state().globalComposite, state().globalBlend);
}
void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operation)
@@ -594,11 +683,11 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
BlendMode blendMode = BlendModeNormal;
if (!parseCompositeAndBlendOperator(operation, op, blendMode))
return;
- if ((state().m_globalComposite == op) && (state().m_globalBlend == blendMode))
+ if ((state().globalComposite == op) && (state().globalBlend == blendMode))
return;
realizeSaves();
- modifiableState().m_globalComposite = op;
- modifiableState().m_globalBlend = blendMode;
+ modifiableState().globalComposite = op;
+ modifiableState().globalBlend = blendMode;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -610,25 +699,25 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
GraphicsContext* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
- if (!std::isfinite(sx) | !std::isfinite(sy))
+ if (!std::isfinite(sx) || !std::isfinite(sy))
return;
- AffineTransform newTransform = state().m_transform;
+ AffineTransform newTransform = state().transform;
newTransform.scaleNonUniform(sx, sy);
- if (state().m_transform == newTransform)
+ if (state().transform == newTransform)
return;
realizeSaves();
- if (!newTransform.isInvertible()) {
- modifiableState().m_hasInvertibleTransform = false;
+ if (!sx || !sy) {
+ modifiableState().hasInvertibleTransform = false;
return;
}
- modifiableState().m_transform = newTransform;
+ modifiableState().transform = newTransform;
c->scale(FloatSize(sx, sy));
m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}
@@ -638,25 +727,20 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
GraphicsContext* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
if (!std::isfinite(angleInRadians))
return;
- AffineTransform newTransform = state().m_transform;
+ AffineTransform newTransform = state().transform;
newTransform.rotate(angleInRadians / piDouble * 180.0);
- if (state().m_transform == newTransform)
+ if (state().transform == newTransform)
return;
realizeSaves();
- if (!newTransform.isInvertible()) {
- modifiableState().m_hasInvertibleTransform = false;
- return;
- }
-
- modifiableState().m_transform = newTransform;
+ modifiableState().transform = newTransform;
c->rotate(angleInRadians);
m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
}
@@ -666,25 +750,20 @@ void CanvasRenderingContext2D::translate(float tx, float ty)
GraphicsContext* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
if (!std::isfinite(tx) | !std::isfinite(ty))
return;
- AffineTransform newTransform = state().m_transform;
+ AffineTransform newTransform = state().transform;
newTransform.translate(tx, ty);
- if (state().m_transform == newTransform)
+ if (state().transform == newTransform)
return;
realizeSaves();
- if (!newTransform.isInvertible()) {
- modifiableState().m_hasInvertibleTransform = false;
- return;
- }
-
- modifiableState().m_transform = newTransform;
+ modifiableState().transform = newTransform;
c->translate(tx, ty);
m_path.transform(AffineTransform().translate(-tx, -ty));
}
@@ -694,27 +773,26 @@ void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float
GraphicsContext* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
if (!std::isfinite(m11) | !std::isfinite(m21) | !std::isfinite(dx) | !std::isfinite(m12) | !std::isfinite(m22) | !std::isfinite(dy))
return;
AffineTransform transform(m11, m12, m21, m22, dx, dy);
- AffineTransform newTransform = state().m_transform * transform;
- if (state().m_transform == newTransform)
+ AffineTransform newTransform = state().transform * transform;
+ if (state().transform == newTransform)
return;
realizeSaves();
- if (!newTransform.isInvertible()) {
- modifiableState().m_hasInvertibleTransform = false;
+ if (auto inverse = transform.inverse()) {
+ modifiableState().transform = newTransform;
+ c->concatCTM(transform);
+ m_path.transform(inverse.value());
return;
}
-
- modifiableState().m_transform = newTransform;
- c->concatCTM(transform);
- m_path.transform(transform.inverse());
+ modifiableState().hasInvertibleTransform = false;
}
void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, float m22, float dx, float dy)
@@ -726,100 +804,98 @@ void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, flo
if (!std::isfinite(m11) | !std::isfinite(m21) | !std::isfinite(dx) | !std::isfinite(m12) | !std::isfinite(m22) | !std::isfinite(dy))
return;
- AffineTransform ctm = state().m_transform;
- if (!ctm.isInvertible())
- return;
-
- realizeSaves();
-
- c->setCTM(canvas()->baseTransform());
- modifiableState().m_transform = AffineTransform();
- m_path.transform(ctm);
-
- modifiableState().m_hasInvertibleTransform = true;
+ resetTransform();
transform(m11, m12, m21, m22, dx, dy);
}
-void CanvasRenderingContext2D::setStrokeColor(const String& color)
+void CanvasRenderingContext2D::resetTransform()
{
- if (color == state().m_unparsedStrokeColor)
+ GraphicsContext* c = drawingContext();
+ if (!c)
return;
+
+ AffineTransform ctm = state().transform;
+ bool hasInvertibleTransform = state().hasInvertibleTransform;
+
realizeSaves();
- setStrokeStyle(CanvasStyle::createFromString(color, &canvas()->document()));
- modifiableState().m_unparsedStrokeColor = color;
+
+ c->setCTM(canvas().baseTransform());
+ modifiableState().transform = AffineTransform();
+
+ if (hasInvertibleTransform)
+ m_path.transform(ctm);
+
+ modifiableState().hasInvertibleTransform = true;
}
-void CanvasRenderingContext2D::setStrokeColor(float grayLevel)
+void CanvasRenderingContext2D::setStrokeColor(const String& color, std::optional<float> alpha)
{
- if (state().m_strokeStyle.isValid() && state().m_strokeStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ if (alpha) {
+ setStrokeStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha.value()));
return;
- setStrokeStyle(CanvasStyle(grayLevel, 1.0f));
-}
+ }
-void CanvasRenderingContext2D::setStrokeColor(const String& color, float alpha)
-{
- setStrokeStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+ if (color == state().unparsedStrokeColor)
+ return;
+
+ realizeSaves();
+ setStrokeStyle(CanvasStyle::createFromString(color, &canvas().document()));
+ modifiableState().unparsedStrokeColor = color;
}
void CanvasRenderingContext2D::setStrokeColor(float grayLevel, float alpha)
{
- if (state().m_strokeStyle.isValid() && state().m_strokeStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ if (state().strokeStyle.isValid() && state().strokeStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
return;
setStrokeStyle(CanvasStyle(grayLevel, alpha));
}
void CanvasRenderingContext2D::setStrokeColor(float r, float g, float b, float a)
{
- if (state().m_strokeStyle.isValid() && state().m_strokeStyle.isEquivalentRGBA(r, g, b, a))
+ if (state().strokeStyle.isValid() && state().strokeStyle.isEquivalentRGBA(r, g, b, a))
return;
setStrokeStyle(CanvasStyle(r, g, b, a));
}
void CanvasRenderingContext2D::setStrokeColor(float c, float m, float y, float k, float a)
{
- if (state().m_strokeStyle.isValid() && state().m_strokeStyle.isEquivalentCMYKA(c, m, y, k, a))
+ if (state().strokeStyle.isValid() && state().strokeStyle.isEquivalentCMYKA(c, m, y, k, a))
return;
setStrokeStyle(CanvasStyle(c, m, y, k, a));
}
-void CanvasRenderingContext2D::setFillColor(const String& color)
+void CanvasRenderingContext2D::setFillColor(const String& color, std::optional<float> alpha)
{
- if (color == state().m_unparsedFillColor)
+ if (alpha) {
+ setFillStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha.value()));
return;
- realizeSaves();
- setFillStyle(CanvasStyle::createFromString(color, &canvas()->document()));
- modifiableState().m_unparsedFillColor = color;
-}
+ }
-void CanvasRenderingContext2D::setFillColor(float grayLevel)
-{
- if (state().m_fillStyle.isValid() && state().m_fillStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ if (color == state().unparsedFillColor)
return;
- setFillStyle(CanvasStyle(grayLevel, 1.0f));
-}
-void CanvasRenderingContext2D::setFillColor(const String& color, float alpha)
-{
- setFillStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+ realizeSaves();
+ setFillStyle(CanvasStyle::createFromString(color, &canvas().document()));
+ modifiableState().unparsedFillColor = color;
}
void CanvasRenderingContext2D::setFillColor(float grayLevel, float alpha)
{
- if (state().m_fillStyle.isValid() && state().m_fillStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ if (state().fillStyle.isValid() && state().fillStyle.isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
return;
setFillStyle(CanvasStyle(grayLevel, alpha));
}
void CanvasRenderingContext2D::setFillColor(float r, float g, float b, float a)
{
- if (state().m_fillStyle.isValid() && state().m_fillStyle.isEquivalentRGBA(r, g, b, a))
+ if (state().fillStyle.isValid() && state().fillStyle.isEquivalentRGBA(r, g, b, a))
return;
setFillStyle(CanvasStyle(r, g, b, a));
}
void CanvasRenderingContext2D::setFillColor(float c, float m, float y, float k, float a)
{
- if (state().m_fillStyle.isValid() && state().m_fillStyle.isEquivalentCMYKA(c, m, y, k, a))
+ if (state().fillStyle.isValid() && state().fillStyle.isEquivalentCMYKA(c, m, y, k, a))
return;
setFillStyle(CanvasStyle(c, m, y, k, a));
}
@@ -829,22 +905,6 @@ void CanvasRenderingContext2D::beginPath()
m_path.clear();
}
-#if ENABLE(CANVAS_PATH)
-
-PassRefPtr<DOMPath> CanvasRenderingContext2D::currentPath()
-{
- return DOMPath::create(m_path);
-}
-
-void CanvasRenderingContext2D::setCurrentPath(DOMPath* path)
-{
- if (!path)
- return;
- m_path = path->path();
-}
-
-#endif
-
static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
{
if (!std::isfinite(x) | !std::isfinite(y) | !std::isfinite(width) | !std::isfinite(height))
@@ -866,13 +926,13 @@ static bool validateRectForCanvas(float& x, float& y, float& width, float& heigh
return true;
}
-#if ENABLE(DASHBOARD_SUPPORT)
-void CanvasRenderingContext2D::clearPathForDashboardBackwardCompatibilityMode()
+inline void CanvasRenderingContext2D::clearPathForDashboardBackwardCompatibilityMode()
{
+#if ENABLE(DASHBOARD_SUPPORT)
if (m_usesDashboardCompatibilityMode)
m_path.clear();
-}
#endif
+}
static bool isFullCanvasCompositeMode(CompositeOperator op)
{
@@ -882,152 +942,197 @@ static bool isFullCanvasCompositeMode(CompositeOperator op)
return op == CompositeSourceIn || op == CompositeSourceOut || op == CompositeDestinationIn || op == CompositeDestinationAtop;
}
-static bool parseWinding(const String& windingRuleString, WindRule& windRule)
+static WindRule toWindRule(CanvasRenderingContext2D::WindingRule rule)
{
- if (windingRuleString == "nonzero")
- windRule = RULE_NONZERO;
- else if (windingRuleString == "evenodd")
- windRule = RULE_EVENODD;
- else
- return false;
-
- return true;
+ return rule == CanvasRenderingContext2D::WindingRule::Nonzero ? RULE_NONZERO : RULE_EVENODD;
}
-void CanvasRenderingContext2D::fill(const String& windingRuleString)
+void CanvasRenderingContext2D::fill(WindingRule windingRule)
{
- GraphicsContext* c = drawingContext();
+ fillInternal(m_path, windingRule);
+ clearPathForDashboardBackwardCompatibilityMode();
+}
+
+void CanvasRenderingContext2D::stroke()
+{
+ strokeInternal(m_path);
+ clearPathForDashboardBackwardCompatibilityMode();
+}
+
+void CanvasRenderingContext2D::clip(WindingRule windingRule)
+{
+ clipInternal(m_path, windingRule);
+ clearPathForDashboardBackwardCompatibilityMode();
+}
+
+void CanvasRenderingContext2D::fill(DOMPath& path, WindingRule windingRule)
+{
+ fillInternal(path.path(), windingRule);
+}
+
+void CanvasRenderingContext2D::stroke(DOMPath& path)
+{
+ strokeInternal(path.path());
+}
+
+void CanvasRenderingContext2D::clip(DOMPath& path, WindingRule windingRule)
+{
+ clipInternal(path.path(), windingRule);
+}
+
+void CanvasRenderingContext2D::fillInternal(const Path& path, WindingRule windingRule)
+{
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
// If gradient size is zero, then paint nothing.
- Gradient* gradient = c->fillGradient();
+ auto* gradient = c->fillGradient();
if (gradient && gradient->isZeroSize())
return;
- if (!m_path.isEmpty()) {
- WindRule windRule = c->fillRule();
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
- return;
- c->setFillRule(newWindRule);
+ if (!path.isEmpty()) {
+ auto savedFillRule = c->fillRule();
+ c->setFillRule(toWindRule(windingRule));
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedFill(m_path);
+ if (isFullCanvasCompositeMode(state().globalComposite)) {
+ beginCompositeLayer();
+ c->fillPath(path);
+ endCompositeLayer();
didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
+ } else if (state().globalComposite == CompositeCopy) {
clearCanvas();
- c->fillPath(m_path);
+ c->fillPath(path);
didDrawEntireCanvas();
} else {
- c->fillPath(m_path);
- didDraw(m_path.fastBoundingRect());
+ c->fillPath(path);
+ didDraw(path.fastBoundingRect());
}
- c->setFillRule(windRule);
+ c->setFillRule(savedFillRule);
}
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
-#endif
}
-void CanvasRenderingContext2D::stroke()
+void CanvasRenderingContext2D::strokeInternal(const Path& path)
{
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
// If gradient size is zero, then paint nothing.
- Gradient* gradient = c->strokeGradient();
+ auto* gradient = c->strokeGradient();
if (gradient && gradient->isZeroSize())
return;
- if (!m_path.isEmpty()) {
- FloatRect dirtyRect = m_path.fastBoundingRect();
- inflateStrokeRect(dirtyRect);
-
- c->strokePath(m_path);
- didDraw(dirtyRect);
+ if (!path.isEmpty()) {
+ if (isFullCanvasCompositeMode(state().globalComposite)) {
+ beginCompositeLayer();
+ c->strokePath(path);
+ endCompositeLayer();
+ didDrawEntireCanvas();
+ } else if (state().globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokePath(path);
+ didDrawEntireCanvas();
+ } else {
+ FloatRect dirtyRect = path.fastBoundingRect();
+ inflateStrokeRect(dirtyRect);
+ c->strokePath(path);
+ didDraw(dirtyRect);
+ }
}
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
-#endif
}
-void CanvasRenderingContext2D::clip(const String& windingRuleString)
+void CanvasRenderingContext2D::clipInternal(const Path& path, WindingRule windingRule)
{
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
- return;
-
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
+ if (!state().hasInvertibleTransform)
return;
realizeSaves();
- c->canvasClip(m_path, newWindRule);
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
+ c->canvasClip(path, toWindRule(windingRule));
+}
+
+inline void CanvasRenderingContext2D::beginCompositeLayer()
+{
+#if !USE(CAIRO)
+ drawingContext()->beginTransparencyLayer(1);
#endif
}
-bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
+inline void CanvasRenderingContext2D::endCompositeLayer()
{
- GraphicsContext* c = drawingContext();
+#if !USE(CAIRO)
+ drawingContext()->endTransparencyLayer();
+#endif
+}
+
+bool CanvasRenderingContext2D::isPointInPath(float x, float y, WindingRule windingRule)
+{
+ return isPointInPathInternal(m_path, x, y, windingRule);
+}
+
+bool CanvasRenderingContext2D::isPointInStroke(float x, float y)
+{
+ return isPointInStrokeInternal(m_path, x, y);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(DOMPath& path, float x, float y, WindingRule windingRule)
+{
+ return isPointInPathInternal(path.path(), x, y, windingRule);
+}
+
+bool CanvasRenderingContext2D::isPointInStroke(DOMPath& path, float x, float y)
+{
+ return isPointInStrokeInternal(path.path(), x, y);
+}
+
+bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, float x, float y, WindingRule windingRule)
+{
+ auto* c = drawingContext();
if (!c)
return false;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return false;
- FloatPoint point(x, y);
- AffineTransform ctm = state().m_transform;
- FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
+ auto transformedPoint = state().transform.inverse().value_or(AffineTransform()).mapPoint(FloatPoint(x, y));
+
if (!std::isfinite(transformedPoint.x()) || !std::isfinite(transformedPoint.y()))
return false;
- WindRule windRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, windRule))
- return false;
-
- return m_path.contains(transformedPoint, windRule);
+ return path.contains(transformedPoint, toWindRule(windingRule));
}
-
-bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
+bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, float x, float y)
{
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return false;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return false;
- FloatPoint point(x, y);
- AffineTransform ctm = state().m_transform;
- FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
+ auto transformedPoint = state().transform.inverse().value_or(AffineTransform()).mapPoint(FloatPoint(x, y));
if (!std::isfinite(transformedPoint.x()) || !std::isfinite(transformedPoint.y()))
return false;
CanvasStrokeStyleApplier applier(this);
- return m_path.strokeContains(&applier, transformedPoint);
+ return path.strokeContains(&applier, transformedPoint);
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
{
if (!validateRectForCanvas(x, y, width, height))
return;
- GraphicsContext* context = drawingContext();
+ auto* context = drawingContext();
if (!context)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
FloatRect rect(x, y, width, height);
@@ -1035,16 +1140,16 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
if (shouldDrawShadows()) {
context->save();
saved = true;
- context->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+ context->setLegacyShadow(FloatSize(), 0, Color::transparent);
}
- if (state().m_globalAlpha != 1) {
+ if (state().globalAlpha != 1) {
if (!saved) {
context->save();
saved = true;
}
context->setAlpha(1);
}
- if (state().m_globalComposite != CompositeSourceOver) {
+ if (state().globalComposite != CompositeSourceOver) {
if (!saved) {
context->save();
saved = true;
@@ -1062,16 +1167,16 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
if (!validateRectForCanvas(x, y, width, height))
return;
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
// from the HTML5 Canvas spec:
// If x0 = x1 and y0 = y1, then the linear gradient must paint nothing
// If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint nothing
- Gradient* gradient = c->fillGradient();
+ auto* gradient = c->fillGradient();
if (gradient && gradient->isZeroSize())
return;
@@ -1080,10 +1185,12 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
if (rectContainsCanvas(rect)) {
c->fillRect(rect);
didDrawEntireCanvas();
- } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedFill(rect);
+ } else if (isFullCanvasCompositeMode(state().globalComposite)) {
+ beginCompositeLayer();
+ c->fillRect(rect);
+ endCompositeLayer();
didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
+ } else if (state().globalComposite == CompositeCopy) {
clearCanvas();
c->fillRect(rect);
didDrawEntireCanvas();
@@ -1098,67 +1205,62 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
if (!validateRectForCanvas(x, y, width, height))
return;
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
- if (!(state().m_lineWidth >= 0))
+ if (!(state().lineWidth >= 0))
return;
// If gradient size is zero, then paint nothing.
- Gradient* gradient = c->strokeGradient();
+ auto* gradient = c->strokeGradient();
if (gradient && gradient->isZeroSize())
return;
FloatRect rect(x, y, width, height);
-
- FloatRect boundingRect = rect;
- boundingRect.inflate(state().m_lineWidth / 2);
-
- c->strokeRect(rect, state().m_lineWidth);
- didDraw(boundingRect);
-}
-
-void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
-{
- setShadow(FloatSize(width, height), blur, Color::transparent);
-}
-
-void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color)
-{
- RGBA32 rgba;
- if (!parseColorOrCurrentColor(rgba, color, canvas()))
- return;
- setShadow(FloatSize(width, height), blur, rgba);
-}
-
-void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel)
-{
- setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, 1));
+ if (isFullCanvasCompositeMode(state().globalComposite)) {
+ beginCompositeLayer();
+ c->strokeRect(rect, state().lineWidth);
+ endCompositeLayer();
+ didDrawEntireCanvas();
+ } else if (state().globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokeRect(rect, state().lineWidth);
+ didDrawEntireCanvas();
+ } else {
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(state().lineWidth / 2);
+ c->strokeRect(rect, state().lineWidth);
+ didDraw(boundingRect);
+ }
}
-void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color, float alpha)
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& colorString, std::optional<float> alpha)
{
- RGBA32 rgba;
- if (!parseColorOrCurrentColor(rgba, color, canvas()))
- return;
- setShadow(FloatSize(width, height), blur, colorWithOverrideAlpha(rgba, alpha));
+ Color color = Color::transparent;
+ if (!colorString.isNull()) {
+ color = parseColorOrCurrentColor(colorString, &canvas());
+ if (!color.isValid())
+ return;
+ }
+ // FIXME: Should not use RGBA32 here.
+ setShadow(FloatSize(width, height), blur, colorWithOverrideAlpha(color.rgb(), alpha));
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha)
{
- setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha));
+ setShadow(FloatSize(width, height), blur, Color(grayLevel, grayLevel, grayLevel, alpha));
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a)
{
- setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(r, g, b, a));
+ setShadow(FloatSize(width, height), blur, Color(r, g, b, a));
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a)
{
- setShadow(FloatSize(width, height), blur, makeRGBAFromCMYKA(c, m, y, k, a));
+ setShadow(FloatSize(width, height), blur, Color(c, m, y, k, a));
}
void CanvasRenderingContext2D::clearShadow()
@@ -1166,15 +1268,15 @@ void CanvasRenderingContext2D::clearShadow()
setShadow(FloatSize(), 0, Color::transparent);
}
-void CanvasRenderingContext2D::setShadow(const FloatSize& offset, float blur, RGBA32 color)
+void CanvasRenderingContext2D::setShadow(const FloatSize& offset, float blur, const Color& color)
{
- if (state().m_shadowOffset == offset && state().m_shadowBlur == blur && state().m_shadowColor == color)
+ if (state().shadowOffset == offset && state().shadowBlur == blur && state().shadowColor == color)
return;
bool wasDrawingShadows = shouldDrawShadows();
realizeSaves();
- modifiableState().m_shadowOffset = offset;
- modifiableState().m_shadowBlur = blur;
- modifiableState().m_shadowColor = color;
+ modifiableState().shadowOffset = offset;
+ modifiableState().shadowBlur = blur;
+ modifiableState().shadowColor = color;
if (!wasDrawingShadows && !shouldDrawShadows())
return;
applyShadow();
@@ -1182,37 +1284,50 @@ void CanvasRenderingContext2D::setShadow(const FloatSize& offset, float blur, RG
void CanvasRenderingContext2D::applyShadow()
{
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
if (shouldDrawShadows()) {
- float width = state().m_shadowOffset.width();
- float height = state().m_shadowOffset.height();
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ float width = state().shadowOffset.width();
+ float height = state().shadowOffset.height();
+ c->setLegacyShadow(FloatSize(width, -height), state().shadowBlur, state().shadowColor);
} else
- c->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+ c->setLegacyShadow(FloatSize(), 0, Color::transparent);
}
bool CanvasRenderingContext2D::shouldDrawShadows() const
{
- return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !state().m_shadowOffset.isZero());
+ return state().shadowColor.isVisible() && (state().shadowBlur || !state().shadowOffset.isZero());
+}
+
+enum class ImageSizeType { AfterDevicePixelRatio, BeforeDevicePixelRatio };
+static LayoutSize size(HTMLImageElement& element, ImageSizeType sizeType = ImageSizeType::BeforeDevicePixelRatio)
+{
+ LayoutSize size;
+ if (auto* cachedImage = element.cachedImage()) {
+ size = cachedImage->imageSizeForRenderer(element.renderer(), 1.0f); // FIXME: Not sure about this.
+ if (sizeType == ImageSizeType::AfterDevicePixelRatio && is<RenderImage>(element.renderer()) && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
+ size.scale(downcast<RenderImage>(*element.renderer()).imageDevicePixelRatio());
+ }
+ return size;
}
-static LayoutSize size(HTMLImageElement* image)
+static inline FloatSize size(HTMLCanvasElement& canvasElement)
{
- if (CachedImage* cachedImage = image->cachedImage())
- return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
- return IntSize();
+ return canvasElement.size();
}
#if ENABLE(VIDEO)
-static IntSize size(HTMLVideoElement* video)
+
+static inline FloatSize size(HTMLVideoElement& video)
{
- if (MediaPlayer* player = video->player())
- return player->naturalSize();
- return IntSize();
+ auto* player = video.player();
+ if (!player)
+ return { };
+ return player->naturalSize();
}
+
#endif
static inline FloatRect normalizeRect(const FloatRect& rect)
@@ -1223,248 +1338,208 @@ static inline FloatRect normalizeRect(const FloatRect& rect)
std::max(rect.height(), -rect.height()));
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(CanvasImageSource&& image, float dx, float dy)
{
- if (!image) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- LayoutSize s = size(image);
- drawImage(image, x, y, s.width(), s.height(), ec);
+ return WTF::switchOn(image,
+ [&] (RefPtr<HTMLImageElement>& imageElement) -> ExceptionOr<void> {
+ LayoutSize destRectSize = size(*imageElement, ImageSizeType::AfterDevicePixelRatio);
+ LayoutSize sourceRectSize = size(*imageElement, ImageSizeType::BeforeDevicePixelRatio);
+ return this->drawImage(*imageElement, FloatRect { 0, 0, sourceRectSize.width(), sourceRectSize.height() }, FloatRect { dx, dy, destRectSize.width(), destRectSize.height() });
+ },
+ [&] (auto& element) -> ExceptionOr<void> {
+ FloatSize elementSize = size(*element);
+ return this->drawImage(*element, FloatRect { 0, 0, elementSize.width(), elementSize.height() }, FloatRect { dx, dy, elementSize.width(), elementSize.height() });
+ }
+ );
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float x, float y, float width, float height, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(CanvasImageSource&& image, float dx, float dy, float dw, float dh)
{
- if (!image) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- LayoutSize s = size(image);
- drawImage(image, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
+ return WTF::switchOn(image,
+ [&] (auto& element) -> ExceptionOr<void> {
+ FloatSize elementSize = size(*element);
+ return this->drawImage(*element, FloatRect { 0, 0, elementSize.width(), elementSize.height() }, FloatRect { dx, dy, dw, dh });
+ }
+ );
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(CanvasImageSource&& image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh)
{
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+ return WTF::switchOn(image,
+ [&] (auto& element) -> ExceptionOr<void> {
+ return this->drawImage(*element, FloatRect { sx, sy, sw, sh }, FloatRect { dx, dy, dw, dh });
+ }
+ );
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(HTMLImageElement& imageElement, const FloatRect& srcRect, const FloatRect& dstRect)
{
- drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_globalBlend, ec);
+ return drawImage(imageElement, srcRect, dstRect, state().globalComposite, state().globalBlend);
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(HTMLImageElement& imageElement, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode)
{
- if (!image) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
-
- ec = 0;
-
if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
|| !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
+ return { };
if (!dstRect.width() || !dstRect.height())
- return;
+ return { };
- if (!image->complete())
- return;
+ if (!imageElement.complete())
+ return { };
FloatRect normalizedSrcRect = normalizeRect(srcRect);
FloatRect normalizedDstRect = normalizeRect(dstRect);
- FloatRect imageRect = FloatRect(FloatPoint(), size(image));
- if (!srcRect.width() || !srcRect.height()) {
- ec = INDEX_SIZE_ERR;
- return;
+ FloatRect imageRect = FloatRect(FloatPoint(), size(imageElement, ImageSizeType::BeforeDevicePixelRatio));
+ if (!srcRect.width() || !srcRect.height())
+ return Exception { INDEX_SIZE_ERR };
+
+ // When the source rectangle is outside the source image, the source rectangle must be clipped
+ // to the source image and the destination rectangle must be clipped in the same proportion.
+ FloatRect originalNormalizedSrcRect = normalizedSrcRect;
+ normalizedSrcRect.intersect(imageRect);
+ if (normalizedSrcRect.isEmpty())
+ return { };
+
+ if (normalizedSrcRect != originalNormalizedSrcRect) {
+ normalizedDstRect.setWidth(normalizedDstRect.width() * normalizedSrcRect.width() / originalNormalizedSrcRect.width());
+ normalizedDstRect.setHeight(normalizedDstRect.height() * normalizedSrcRect.height() / originalNormalizedSrcRect.height());
+ if (normalizedDstRect.isEmpty())
+ return { };
}
- if (!imageRect.contains(normalizedSrcRect))
- return;
GraphicsContext* c = drawingContext();
if (!c)
- return;
- if (!state().m_hasInvertibleTransform)
- return;
+ return { };
+ if (!state().hasInvertibleTransform)
+ return { };
- CachedImage* cachedImage = image->cachedImage();
+ CachedImage* cachedImage = imageElement.cachedImage();
if (!cachedImage)
- return;
+ return { };
+
+ Image* image = cachedImage->imageForRenderer(imageElement.renderer());
+ if (!image)
+ return { };
+
+ ImageObserver* observer = image->imageObserver();
+
+ if (image->isSVGImage()) {
+ image->setImageObserver(nullptr);
+ image->setContainerSize(imageRect.size());
+ }
if (rectContainsCanvas(normalizedDstRect)) {
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
+ c->drawImage(*image, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
didDrawEntireCanvas();
} else if (isFullCanvasCompositeMode(op)) {
- fullCanvasCompositedDrawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
+ fullCanvasCompositedDrawImage(*image, normalizedDstRect, normalizedSrcRect, op);
didDrawEntireCanvas();
} else if (op == CompositeCopy) {
clearCanvas();
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
+ c->drawImage(*image, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
didDrawEntireCanvas();
} else {
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
+ c->drawImage(*image, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
didDraw(normalizedDstRect);
}
+
+ if (image->isSVGImage())
+ image->setImageObserver(observer);
- checkOrigin(image);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionCode& ec)
-{
- drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(), x, y, sourceCanvas->width(), sourceCanvas->height(), ec);
-}
+ checkOrigin(&imageElement);
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float x, float y, float width, float height, ExceptionCode& ec)
-{
- drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas->height()), FloatRect(x, y, width, height), ec);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionCode& ec)
-{
- drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+ return { };
}
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
- const FloatRect& dstRect, ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(HTMLCanvasElement& sourceCanvas, const FloatRect& srcRect, const FloatRect& dstRect)
{
- if (!sourceCanvas) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
+ FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas.size());
- FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
-
- if (!srcCanvasRect.width() || !srcCanvasRect.height()) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- if (!srcRect.width() || !srcRect.height()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (!srcCanvasRect.width() || !srcCanvasRect.height())
+ return Exception { INVALID_STATE_ERR };
- ec = 0;
+ if (!srcRect.width() || !srcRect.height())
+ return Exception { INDEX_SIZE_ERR };
if (!srcCanvasRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
- return;
+ return { };
GraphicsContext* c = drawingContext();
if (!c)
- return;
- if (!state().m_hasInvertibleTransform)
- return;
+ return { };
+ if (!state().hasInvertibleTransform)
+ return { };
// FIXME: Do this through platform-independent GraphicsContext API.
- ImageBuffer* buffer = sourceCanvas->buffer();
+ ImageBuffer* buffer = sourceCanvas.buffer();
if (!buffer)
- return;
+ return { };
- checkOrigin(sourceCanvas);
+ checkOrigin(&sourceCanvas);
#if ENABLE(ACCELERATED_2D_CANVAS)
- // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
+ // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas.makeRenderingResultsAvailable()
// as that will do a readback to software.
- CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
+ CanvasRenderingContext* sourceContext = sourceCanvas.renderingContext();
// FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d())
- sourceCanvas->makeRenderingResultsAvailable();
+ sourceCanvas.makeRenderingResultsAvailable();
#else
- sourceCanvas->makeRenderingResultsAvailable();
+ sourceCanvas.makeRenderingResultsAvailable();
#endif
if (rectContainsCanvas(dstRect)) {
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
+ c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
didDrawEntireCanvas();
- } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedDrawImage(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite);
+ } else if (isFullCanvasCompositeMode(state().globalComposite)) {
+ fullCanvasCompositedDrawImage(*buffer, dstRect, srcRect, state().globalComposite);
didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
+ } else if (state().globalComposite == CompositeCopy) {
clearCanvas();
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
+ c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
didDrawEntireCanvas();
} else {
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
+ c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
didDraw(dstRect);
}
-}
-#if ENABLE(VIDEO)
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionCode& ec)
-{
- if (!video) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- IntSize s = size(video);
- drawImage(video, x, y, s.width(), s.height(), ec);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float x, float y, float width, float height, ExceptionCode& ec)
-{
- if (!video) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- IntSize s = size(video);
- drawImage(video, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
+ return { };
}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionCode& ec)
-{
- drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
-}
+#if ENABLE(VIDEO)
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect,
- ExceptionCode& ec)
+ExceptionOr<void> CanvasRenderingContext2D::drawImage(HTMLVideoElement& video, const FloatRect& srcRect, const FloatRect& dstRect)
{
- if (!video) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
-
- ec = 0;
-
- if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
- return;
+ if (video.readyState() == HTMLMediaElement::HAVE_NOTHING || video.readyState() == HTMLMediaElement::HAVE_METADATA)
+ return { };
FloatRect videoRect = FloatRect(FloatPoint(), size(video));
- if (!srcRect.width() || !srcRect.height()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (!srcRect.width() || !srcRect.height())
+ return Exception { INDEX_SIZE_ERR };
if (!videoRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
- return;
+ return { };
GraphicsContext* c = drawingContext();
if (!c)
- return;
- if (!state().m_hasInvertibleTransform)
- return;
+ return { };
+ if (!state().hasInvertibleTransform)
+ return { };
- checkOrigin(video);
+ checkOrigin(&video);
-#if USE(CG)
- if (PassNativeImagePtr image = video->nativeImageForCurrentTime()) {
- c->drawNativeImage(image, FloatSize(video->videoWidth(), video->videoHeight()), ColorSpaceDeviceRGB, dstRect, srcRect);
+#if USE(CG) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(GSTREAMER_GL) && USE(CAIRO))
+ if (NativeImagePtr image = video.nativeImageForCurrentTime()) {
+ c->drawNativeImage(image, FloatSize(video.videoWidth(), video.videoHeight()), dstRect, srcRect);
if (rectContainsCanvas(dstRect))
didDrawEntireCanvas();
else
didDraw(dstRect);
- return;
+ return { };
}
#endif
@@ -1473,23 +1548,22 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
c->translate(dstRect.x(), dstRect.y());
c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
c->translate(-srcRect.x(), -srcRect.y());
- video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video)));
+ video.paintCurrentFrameInContext(*c, FloatRect(FloatPoint(), size(video)));
stateSaver.restore();
didDraw(dstRect);
+
+ return { };
}
+
#endif
-void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh,
- const String& compositeOperation)
+void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement& imageElement, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, const String& compositeOperation)
{
CompositeOperator op;
- BlendMode blendOp = BlendModeNormal;
+ auto blendOp = BlendModeNormal;
if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blendOp != BlendModeNormal)
op = CompositeSourceOver;
-
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, BlendModeNormal, IGNORE_EXCEPTION);
+ drawImage(imageElement, FloatRect { sx, sy, sw, sh }, FloatRect { dx, dy, dw, dh }, op, BlendModeNormal);
}
void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1504,22 +1578,21 @@ void CanvasRenderingContext2D::setCompositeOperation(const String& operation)
void CanvasRenderingContext2D::clearCanvas()
{
- FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
c->save();
- c->setCTM(canvas()->baseTransform());
- c->clearRect(canvasRect);
+ c->setCTM(canvas().baseTransform());
+ c->clearRect(FloatRect(0, 0, canvas().width(), canvas().height()));
c->restore();
}
Path CanvasRenderingContext2D::transformAreaToDevice(const Path& path) const
{
Path transformed(path);
- transformed.transform(state().m_transform);
- transformed.transform(canvas()->baseTransform());
+ transformed.transform(state().transform);
+ transformed.transform(canvas().baseTransform());
return transformed;
}
@@ -1533,14 +1606,14 @@ Path CanvasRenderingContext2D::transformAreaToDevice(const FloatRect& rect) cons
bool CanvasRenderingContext2D::rectContainsCanvas(const FloatRect& rect) const
{
FloatQuad quad(rect);
- FloatQuad canvasQuad(FloatRect(0, 0, canvas()->width(), canvas()->height()));
- return state().m_transform.mapQuad(quad).containsQuad(canvasQuad);
+ FloatQuad canvasQuad(FloatRect(0, 0, canvas().width(), canvas().height()));
+ return state().transform.mapQuad(quad).containsQuad(canvasQuad);
}
template<class T> IntRect CanvasRenderingContext2D::calculateCompositingBufferRect(const T& area, IntSize* croppedOffset)
{
- IntRect canvasRect(0, 0, canvas()->width(), canvas()->height());
- canvasRect = canvas()->baseTransform().mapRect(canvasRect);
+ IntRect canvasRect(0, 0, canvas().width(), canvas().height());
+ canvasRect = canvas().baseTransform().mapRect(canvasRect);
Path path = transformAreaToDevice(area);
IntRect bufferRect = enclosingIntRect(path.fastBoundingRect());
IntPoint originalLocation = bufferRect.location();
@@ -1552,16 +1625,15 @@ template<class T> IntRect CanvasRenderingContext2D::calculateCompositingBufferRe
std::unique_ptr<ImageBuffer> CanvasRenderingContext2D::createCompositingBuffer(const IntRect& bufferRect)
{
- RenderingMode renderMode = isAccelerated() ? Accelerated : Unaccelerated;
- return ImageBuffer::create(bufferRect.size(), 1, ColorSpaceDeviceRGB, renderMode);
+ return ImageBuffer::create(bufferRect.size(), isAccelerated() ? Accelerated : Unaccelerated);
}
-void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRect& bufferRect, CompositeOperator op)
+void CanvasRenderingContext2D::compositeBuffer(ImageBuffer& buffer, const IntRect& bufferRect, CompositeOperator op)
{
- IntRect canvasRect(0, 0, canvas()->width(), canvas()->height());
- canvasRect = canvas()->baseTransform().mapRect(canvasRect);
+ IntRect canvasRect(0, 0, canvas().width(), canvas().height());
+ canvasRect = canvas().baseTransform().mapRect(canvasRect);
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
@@ -1573,37 +1645,36 @@ void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRec
c->clipOut(bufferRect);
c->clearRect(canvasRect);
c->restore();
-
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, bufferRect.location(), state().m_globalComposite);
+ c->drawImageBuffer(buffer, bufferRect.location(), state().globalComposite);
c->restore();
}
-static void drawImageToContext(Image* image, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+static void drawImageToContext(Image& image, GraphicsContext& context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
- context->drawImage(image, styleColorSpace, dest, src, op, ImageOrientationDescription());
+ context.drawImage(image, dest, src, op);
}
-static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+static void drawImageToContext(ImageBuffer& imageBuffer, GraphicsContext& context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
- context->drawImageBuffer(imageBuffer, styleColorSpace, dest, src, op);
+ context.drawImageBuffer(imageBuffer, dest, src, op);
}
-template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T& image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
ASSERT(isFullCanvasCompositeMode(op));
IntSize croppedOffset;
- IntRect bufferRect = calculateCompositingBufferRect(dest, &croppedOffset);
+ auto bufferRect = calculateCompositingBufferRect(dest, &croppedOffset);
if (bufferRect.isEmpty()) {
clearCanvas();
return;
}
- std::unique_ptr<ImageBuffer> buffer = createCompositingBuffer(bufferRect);
+ auto buffer = createCompositingBuffer(bufferRect);
if (!buffer)
return;
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
@@ -1611,142 +1682,172 @@ template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(
adjustedDest.setLocation(FloatPoint(0, 0));
AffineTransform effectiveTransform = c->getCTM();
IntRect transformedAdjustedRect = enclosingIntRect(effectiveTransform.mapRect(adjustedDest));
- buffer->context()->translate(-transformedAdjustedRect.location().x(), -transformedAdjustedRect.location().y());
- buffer->context()->translate(croppedOffset.width(), croppedOffset.height());
- buffer->context()->concatCTM(effectiveTransform);
- drawImageToContext(image, buffer->context(), styleColorSpace, adjustedDest, src, CompositeSourceOver);
+ buffer->context().translate(-transformedAdjustedRect.location().x(), -transformedAdjustedRect.location().y());
+ buffer->context().translate(croppedOffset.width(), croppedOffset.height());
+ buffer->context().concatCTM(effectiveTransform);
+ drawImageToContext(image, buffer->context(), adjustedDest, src, CompositeSourceOver);
- compositeBuffer(buffer.get(), bufferRect, op);
+ compositeBuffer(*buffer, bufferRect, op);
}
-template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const T& area)
+void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient& gradient) const
{
- ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
-
- IntRect bufferRect = calculateCompositingBufferRect(area, 0);
- if (bufferRect.isEmpty()) {
- clearCanvas();
- return;
- }
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (m_usesDashboardCompatibilityMode)
+ gradient.setDashboardCompatibilityMode();
+#else
+ UNUSED_PARAM(gradient);
+#endif
+}
- std::unique_ptr<ImageBuffer> buffer = createCompositingBuffer(bufferRect);
- if (!buffer)
- return;
+static CanvasRenderingContext2D::Style toStyle(const CanvasStyle& style)
+{
+ if (auto* gradient = style.canvasGradient())
+ return RefPtr<CanvasGradient> { gradient };
+ if (auto* pattern = style.canvasPattern())
+ return RefPtr<CanvasPattern> { pattern };
+ return style.color();
+}
- Path path = transformAreaToDevice(area);
- path.translate(FloatSize(-bufferRect.x(), -bufferRect.y()));
+CanvasRenderingContext2D::Style CanvasRenderingContext2D::strokeStyle() const
+{
+ return toStyle(state().strokeStyle);
+}
- buffer->context()->setCompositeOperation(CompositeSourceOver);
- modifiableState().m_fillStyle.applyFillColor(buffer->context());
- buffer->context()->fillPath(path);
+void CanvasRenderingContext2D::setStrokeStyle(CanvasRenderingContext2D::Style&& style)
+{
+ WTF::switchOn(style,
+ [this] (const String& string) { this->setStrokeColor(string); },
+ [this] (const RefPtr<CanvasGradient>& gradient) { this->setStrokeStyle(CanvasStyle(*gradient)); },
+ [this] (const RefPtr<CanvasPattern>& pattern) { this->setStrokeStyle(CanvasStyle(*pattern)); }
+ );
+}
- compositeBuffer(buffer.get(), bufferRect, state().m_globalComposite);
+CanvasRenderingContext2D::Style CanvasRenderingContext2D::fillStyle() const
+{
+ return toStyle(state().fillStyle);
}
-void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient* gradient) const
+void CanvasRenderingContext2D::setFillStyle(CanvasRenderingContext2D::Style&& style)
{
-#if ENABLE(DASHBOARD_SUPPORT)
- if (m_usesDashboardCompatibilityMode)
- gradient->setDashboardCompatibilityMode();
-#else
- UNUSED_PARAM(gradient);
-#endif
+ WTF::switchOn(style,
+ [this] (const String& string) { this->setFillColor(string); },
+ [this] (const RefPtr<CanvasGradient>& gradient) { this->setFillStyle(CanvasStyle(*gradient)); },
+ [this] (const RefPtr<CanvasPattern>& pattern) { this->setFillStyle(CanvasStyle(*pattern)); }
+ );
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
+ExceptionOr<Ref<CanvasGradient>> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(x1) || !std::isfinite(y1)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(x1) || !std::isfinite(y1))
+ return Exception { NOT_SUPPORTED_ERR };
- RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ auto gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
prepareGradientForDashboard(gradient.get());
- return gradient.release();
+ return WTFMove(gradient);
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
+ExceptionOr<Ref<CanvasGradient>> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(r0) || !std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(r1)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(r0) || !std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(r1))
+ return Exception { NOT_SUPPORTED_ERR };
- if (r0 < 0 || r1 < 0) {
- ec = INDEX_SIZE_ERR;
- return 0;
- }
+ if (r0 < 0 || r1 < 0)
+ return Exception { INDEX_SIZE_ERR };
- RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ auto gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
prepareGradientForDashboard(gradient.get());
- return gradient.release();
+ return WTFMove(gradient);
}
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
- const String& repetitionType, ExceptionCode& ec)
+ExceptionOr<RefPtr<CanvasPattern>> CanvasRenderingContext2D::createPattern(CanvasImageSource&& image, const String& repetition)
{
- if (!image) {
- ec = TYPE_MISMATCH_ERR;
- return 0;
- }
bool repeatX, repeatY;
- ec = 0;
- CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
- if (ec)
- return 0;
+ if (!CanvasPattern::parseRepetitionType(repetition, repeatX, repeatY))
+ return Exception { SYNTAX_ERR };
+
+ return WTF::switchOn(image,
+ [&] (auto& element) -> ExceptionOr<RefPtr<CanvasPattern>> { return this->createPattern(*element, repeatX, repeatY); }
+ );
+}
+
+ExceptionOr<RefPtr<CanvasPattern>> CanvasRenderingContext2D::createPattern(HTMLImageElement& imageElement, bool repeatX, bool repeatY)
+{
+ auto* cachedImage = imageElement.cachedImage();
- if (!image->complete())
- return 0;
+ // If the image loading hasn't started or the image is not complete, it is not fully decodable.
+ if (!cachedImage || !imageElement.complete())
+ return nullptr;
- CachedImage* cachedImage = image->cachedImage();
- if (!cachedImage || !image->cachedImage()->imageForRenderer(image->renderer()))
- return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+ if (cachedImage->status() == CachedResource::LoadError)
+ return Exception { INVALID_STATE_ERR };
- bool originClean = cachedImage->isOriginClean(canvas()->securityOrigin());
- return CanvasPattern::create(cachedImage->imageForRenderer(image->renderer()), repeatX, repeatY, originClean);
+ bool originClean = cachedImage->isOriginClean(canvas().securityOrigin());
+
+ // FIXME: SVG images with animations can switch between clean and dirty (leaking cross-origin
+ // data). We should either:
+ // 1) Take a fixed snapshot of an SVG image when creating a pattern and determine then whether
+ // the origin is clean.
+ // 2) Dynamically verify the origin checks at draw time, and dirty the canvas accordingly.
+ // To be on the safe side, taint the origin for all patterns containing SVG images for now.
+ if (cachedImage->image()->isSVGImage())
+ originClean = false;
+
+ return RefPtr<CanvasPattern> { CanvasPattern::create(*cachedImage->imageForRenderer(imageElement.renderer()), repeatX, repeatY, originClean) };
}
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
- const String& repetitionType, ExceptionCode& ec)
+ExceptionOr<RefPtr<CanvasPattern>> CanvasRenderingContext2D::createPattern(HTMLCanvasElement& canvas, bool repeatX, bool repeatY)
{
- if (!canvas) {
- ec = TYPE_MISMATCH_ERR;
- return 0;
- }
- if (!canvas->width() || !canvas->height()) {
- ec = INVALID_STATE_ERR;
- return 0;
- }
+ if (!canvas.width() || !canvas.height() || !canvas.buffer())
+ return Exception { INVALID_STATE_ERR };
- bool repeatX, repeatY;
- ec = 0;
- CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
- if (ec)
- return 0;
- return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+ return RefPtr<CanvasPattern> { CanvasPattern::create(*canvas.copiedImage(), repeatX, repeatY, canvas.originClean()) };
+}
+
+#if ENABLE(VIDEO)
+
+ExceptionOr<RefPtr<CanvasPattern>> CanvasRenderingContext2D::createPattern(HTMLVideoElement& videoElement, bool repeatX, bool repeatY)
+{
+ if (videoElement.readyState() < HTMLMediaElement::HAVE_CURRENT_DATA)
+ return nullptr;
+
+ checkOrigin(&videoElement);
+ bool originClean = canvas().originClean();
+
+#if USE(CG) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(GSTREAMER_GL) && USE(CAIRO))
+ if (auto nativeImage = videoElement.nativeImageForCurrentTime())
+ return RefPtr<CanvasPattern> { CanvasPattern::create(BitmapImage::create(WTFMove(nativeImage)), repeatX, repeatY, originClean) };
+#endif
+
+ auto imageBuffer = ImageBuffer::create(size(videoElement), drawingContext() ? drawingContext()->renderingMode() : Accelerated);
+ videoElement.paintCurrentFrameInContext(imageBuffer->context(), FloatRect(FloatPoint(), size(videoElement)));
+
+ return RefPtr<CanvasPattern> { CanvasPattern::create(ImageBuffer::sinkIntoImage(WTFMove(imageBuffer), Unscaled).releaseNonNull(), repeatX, repeatY, originClean) };
}
+#endif
+
void CanvasRenderingContext2D::didDrawEntireCanvas()
{
- didDraw(FloatRect(FloatPoint::zero(), canvas()->size()), CanvasDidDrawApplyClip);
+ didDraw(FloatRect(FloatPoint::zero(), canvas().size()), CanvasDidDrawApplyClip);
}
void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
{
- GraphicsContext* c = drawingContext();
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
-#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+#if ENABLE(ACCELERATED_2D_CANVAS)
// If we are drawing to hardware and we have a composited layer, just call contentChanged().
if (isAccelerated()) {
- RenderBox* renderBox = canvas()->renderBox();
+ RenderBox* renderBox = canvas().renderBox();
if (renderBox && renderBox->hasAcceleratedCompositing()) {
renderBox->contentChanged(CanvasPixelsChanged);
- canvas()->clearCopiedImage();
- canvas()->notifyObserversCanvasChanged(r);
+ canvas().clearCopiedImage();
+ canvas().notifyObserversCanvasChanged(r);
return;
}
}
@@ -1754,15 +1855,15 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
FloatRect dirtyRect = r;
if (options & CanvasDidDrawApplyTransform) {
- AffineTransform ctm = state().m_transform;
+ AffineTransform ctm = state().transform;
dirtyRect = ctm.mapRect(r);
}
- if (options & CanvasDidDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
+ if (options & CanvasDidDrawApplyShadow && state().shadowColor.isVisible()) {
// The shadow gets applied after transformation
FloatRect shadowRect(dirtyRect);
- shadowRect.move(state().m_shadowOffset);
- shadowRect.inflate(state().m_shadowBlur);
+ shadowRect.move(state().shadowOffset);
+ shadowRect.inflate(state().shadowBlur);
dirtyRect.unite(shadowRect);
}
@@ -1772,61 +1873,88 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
// we'd have to keep the clip path around.
}
- canvas()->didDraw(dirtyRect);
+ canvas().didDraw(dirtyRect);
}
-GraphicsContext* CanvasRenderingContext2D::drawingContext() const
+void CanvasRenderingContext2D::setTracksDisplayListReplay(bool tracksDisplayListReplay)
{
- return canvas()->drawingContext();
+ if (tracksDisplayListReplay == m_tracksDisplayListReplay)
+ return;
+
+ m_tracksDisplayListReplay = tracksDisplayListReplay;
+ if (!m_tracksDisplayListReplay)
+ contextDisplayListMap().remove(this);
}
-static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+String CanvasRenderingContext2D::displayListAsText(DisplayList::AsTextFlags flags) const
{
- Checked<int, RecordOverflow> dataSize = 4;
- dataSize *= size.width();
- dataSize *= size.height();
- if (dataSize.hasOverflowed())
- return 0;
+ if (!m_recordingContext)
+ return { };
+ return m_recordingContext->displayList.asText(flags);
+}
- RefPtr<ImageData> data = ImageData::create(size);
- data->data()->zeroFill();
- return data.release();
+String CanvasRenderingContext2D::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
+{
+ auto* displayList = contextDisplayListMap().get(this);
+ if (!displayList)
+ return { };
+ return displayList->asText(flags);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionCode& ec) const
+void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
{
- if (!imageData) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (UNLIKELY(m_usesDisplayListDrawing)) {
+ if (!m_recordingContext)
+ return;
- return createEmptyImageData(imageData->size());
+ FloatRect clip(FloatPoint::zero(), canvas().size());
+ DisplayList::Replayer replayer(*canvas().drawingContext(), m_recordingContext->displayList);
+
+ if (UNLIKELY(m_tracksDisplayListReplay)) {
+ auto replayList = replayer.replay(clip, m_tracksDisplayListReplay);
+ contextDisplayListMap().add(this, WTFMove(replayList));
+ } else
+ replayer.replay(clip);
+
+ m_recordingContext->displayList.clear();
+ }
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const
+GraphicsContext* CanvasRenderingContext2D::drawingContext() const
{
- ec = 0;
- if (!sw || !sh) {
- ec = INDEX_SIZE_ERR;
- return 0;
- }
- if (!std::isfinite(sw) || !std::isfinite(sh)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
+ if (UNLIKELY(m_usesDisplayListDrawing)) {
+ if (!m_recordingContext)
+ m_recordingContext = std::make_unique<DisplayListDrawingContext>(FloatRect(FloatPoint::zero(), canvas().size()));
+ return &m_recordingContext->context;
}
-#if PLATFORM(IOS)
- // If the canvas element was created before Document had a Frame,
- // then no maximumDecodedImageSize was set.
- if (!canvas()->maximumDecodedImageSize()) {
- if (Settings* settings = canvas()->document().settings())
- canvas()->setMaximumDecodedImageSize(settings->maximumDecodedImageSize());
- }
-#endif
+ return canvas().drawingContext();
+}
+
+static RefPtr<ImageData> createEmptyImageData(const IntSize& size)
+{
+ auto data = ImageData::create(size);
+ if (data)
+ data->data()->zeroFill();
+ return data;
+}
+
+ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::createImageData(ImageData* imageData) const
+{
+ if (!imageData)
+ return Exception { NOT_SUPPORTED_ERR };
+
+ return createEmptyImageData(imageData->size());
+}
- FloatSize logicalSize(fabs(sw), fabs(sh));
+ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::createImageData(float sw, float sh) const
+{
+ if (!sw || !sh)
+ return Exception { INDEX_SIZE_ERR };
+
+ FloatSize logicalSize(std::abs(sw), std::abs(sh));
if (!logicalSize.isExpressibleAsIntSize())
- return 0;
+ return nullptr;
IntSize size = expandedIntSize(logicalSize);
if (size.width() < 1)
@@ -1837,33 +1965,26 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float
return createEmptyImageData(size);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh) const
{
- return getImageData(ImageBuffer::LogicalCoordinateSystem, sx, sy, sw, sh, ec);
+ return getImageData(ImageBuffer::LogicalCoordinateSystem, sx, sy, sw, sh);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh) const
{
- return getImageData(ImageBuffer::BackingStoreCoordinateSystem, sx, sy, sw, sh, ec);
+ return getImageData(ImageBuffer::BackingStoreCoordinateSystem, sx, sy, sw, sh);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh) const
{
- if (!canvas()->originClean()) {
- DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Unable to get image data from canvas because the canvas has been tainted by cross-origin data.")));
- canvas()->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
- ec = SECURITY_ERR;
- return 0;
+ if (!canvas().originClean()) {
+ static NeverDestroyed<String> consoleMessage(ASCIILiteral("Unable to get image data from canvas because the canvas has been tainted by cross-origin data."));
+ canvas().document().addConsoleMessage(MessageSource::Security, MessageLevel::Error, consoleMessage);
+ return Exception { SECURITY_ERR };
}
- if (!sw || !sh) {
- ec = INDEX_SIZE_ERR;
- return 0;
- }
- if (!std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!sw || !sh)
+ return Exception { INDEX_SIZE_ERR };
if (sw < 0) {
sx += sw;
@@ -1874,77 +1995,75 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::Coordi
sh = -sh;
}
-#if PLATFORM(IOS)
- // If the canvas element was created before Document had a Frame,
- // then no maximumDecodedImageSize was set.
- if (!canvas()->maximumDecodedImageSize()) {
- if (Settings* settings = canvas()->document().settings())
- canvas()->setMaximumDecodedImageSize(settings->maximumDecodedImageSize());
- }
-#endif
-
FloatRect logicalRect(sx, sy, sw, sh);
if (logicalRect.width() < 1)
logicalRect.setWidth(1);
if (logicalRect.height() < 1)
logicalRect.setHeight(1);
if (!logicalRect.isExpressibleAsIntRect())
- return 0;
+ return nullptr;
IntRect imageDataRect = enclosingIntRect(logicalRect);
- ImageBuffer* buffer = canvas()->buffer();
+ ImageBuffer* buffer = canvas().buffer();
if (!buffer)
return createEmptyImageData(imageDataRect.size());
- RefPtr<Uint8ClampedArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect, coordinateSystem);
- if (!byteArray)
- return 0;
+ auto byteArray = buffer->getUnmultipliedImageData(imageDataRect, coordinateSystem);
+ if (!byteArray) {
+ StringBuilder consoleMessage;
+ consoleMessage.appendLiteral("Unable to get image data from canvas. Requested size was ");
+ consoleMessage.appendNumber(imageDataRect.width());
+ consoleMessage.appendLiteral(" x ");
+ consoleMessage.appendNumber(imageDataRect.height());
- return ImageData::create(imageDataRect.size(), byteArray.release());
+ canvas().document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Error, consoleMessage.toString());
+ return Exception { INVALID_STATE_ERR };
+ }
+
+ return ImageData::create(imageDataRect.size(), byteArray.releaseNonNull());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionCode& ec)
+void CanvasRenderingContext2D::putImageData(ImageData& data, float dx, float dy)
{
- if (!data) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- putImageData(data, dx, dy, 0, 0, data->width(), data->height(), ec);
+ putImageData(data, dx, dy, 0, 0, data.width(), data.height());
}
-void CanvasRenderingContext2D::webkitPutImageDataHD(ImageData* data, float dx, float dy, ExceptionCode& ec)
+void CanvasRenderingContext2D::webkitPutImageDataHD(ImageData& data, float dx, float dy)
{
- if (!data) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- webkitPutImageDataHD(data, dx, dy, 0, 0, data->width(), data->height(), ec);
+ webkitPutImageDataHD(data, dx, dy, 0, 0, data.width(), data.height());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
- float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+void CanvasRenderingContext2D::putImageData(ImageData& data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
{
- putImageData(data, ImageBuffer::LogicalCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight, ec);
+ putImageData(data, ImageBuffer::LogicalCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
}
-void CanvasRenderingContext2D::webkitPutImageDataHD(ImageData* data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+void CanvasRenderingContext2D::webkitPutImageDataHD(ImageData& data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
{
- putImageData(data, ImageBuffer::BackingStoreCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight, ec);
+ putImageData(data, ImageBuffer::BackingStoreCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, ImageBuffer::CoordinateSystem coordinateSystem, float dx, float dy, float dirtyX, float dirtyY,
- float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+void CanvasRenderingContext2D::drawFocusIfNeeded(Element& element)
{
- if (!data) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
- if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dirtyX) || !std::isfinite(dirtyY) || !std::isfinite(dirtyWidth) || !std::isfinite(dirtyHeight)) {
- ec = NOT_SUPPORTED_ERR;
+ drawFocusIfNeededInternal(m_path, element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeeded(DOMPath& path, Element& element)
+{
+ drawFocusIfNeededInternal(path.path(), element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeededInternal(const Path& path, Element& element)
+{
+ auto* context = drawingContext();
+ if (!element.focused() || !state().hasInvertibleTransform || path.isEmpty() || !element.isDescendantOf(canvas()) || !context)
return;
- }
+ context->drawFocusRing(path, 1, 1, RenderTheme::focusRingColor());
+}
- ImageBuffer* buffer = canvas()->buffer();
+void CanvasRenderingContext2D::putImageData(ImageData& data, ImageBuffer::CoordinateSystem coordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
+{
+ ImageBuffer* buffer = canvas().buffer();
if (!buffer)
return;
@@ -1959,7 +2078,7 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, ImageBuffer::Coordi
}
FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
- clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
+ clipRect.intersect(IntRect(0, 0, data.width(), data.height()));
IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
IntRect destRect = enclosingIntRect(clipRect);
destRect.move(destOffset);
@@ -1968,38 +2087,35 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, ImageBuffer::Coordi
return;
IntRect sourceRect(destRect);
sourceRect.move(-destOffset);
+ sourceRect.intersect(IntRect(0, 0, data.width(), data.height()));
- buffer->putByteArray(Unmultiplied, data->data(), IntSize(data->width(), data->height()), sourceRect, IntPoint(destOffset), coordinateSystem);
+ if (!sourceRect.isEmpty())
+ buffer->putByteArray(Unmultiplied, data.data(), IntSize(data.width(), data.height()), sourceRect, IntPoint(destOffset), coordinateSystem);
- if (coordinateSystem == ImageBuffer::BackingStoreCoordinateSystem) {
- FloatRect dirtyRect = destRect;
- dirtyRect.scale(1 / canvas()->deviceScaleFactor());
- destRect = enclosingIntRect(dirtyRect);
- }
didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
}
String CanvasRenderingContext2D::font() const
{
- if (!state().m_realizedFont)
+ if (!state().font.realized())
return defaultFont;
StringBuilder serializedFont;
- const FontDescription& fontDescription = state().m_font.fontDescription();
+ const auto& fontDescription = state().font.fontDescription();
if (fontDescription.italic())
serializedFont.appendLiteral("italic ");
- if (fontDescription.smallCaps() == FontSmallCapsOn)
+ if (fontDescription.variantCaps() == FontVariantCaps::Small)
serializedFont.appendLiteral("small-caps ");
serializedFont.appendNumber(fontDescription.computedPixelSize());
serializedFont.appendLiteral("px");
- for (unsigned i = 0; i < state().m_font.familyCount(); ++i) {
+ for (unsigned i = 0; i < fontDescription.familyCount(); ++i) {
if (i)
serializedFont.append(',');
// FIXME: We should append family directly to serializedFont rather than building a temporary string.
- String family = state().m_font.familyAt(i);
+ String family = fontDescription.familyAt(i);
if (family.startsWith("-webkit-"))
family = family.substring(8);
if (family.contains(' '))
@@ -2014,11 +2130,11 @@ String CanvasRenderingContext2D::font() const
void CanvasRenderingContext2D::setFont(const String& newFont)
{
- if (newFont == state().m_unparsedFont && state().m_realizedFont)
+ if (newFont == state().unparsedFont && state().font.realized())
return;
- RefPtr<MutableStyleProperties> parsedStyle = MutableStyleProperties::create();
- CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode), 0);
+ auto parsedStyle = MutableStyleProperties::create();
+ CSSParser::parseValue(parsedStyle, CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
if (parsedStyle->isEmpty())
return;
@@ -2032,15 +2148,19 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
// The parse succeeded.
String newFontSafeCopy(newFont); // Create a string copy since newFont can be deleted inside realizeSaves.
realizeSaves();
- modifiableState().m_unparsedFont = newFontSafeCopy;
+ modifiableState().unparsedFont = newFontSafeCopy;
// Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
// relative to the canvas.
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- if (RenderStyle* computedStyle = canvas()->computedStyle())
+ auto newStyle = RenderStyle::createPtr();
+
+ Document& document = canvas().document();
+ document.updateStyleIfNeeded();
+
+ if (auto* computedStyle = canvas().computedStyle())
newStyle->setFontDescription(computedStyle->fontDescription());
else {
- FontDescription defaultFontDescription;
+ FontCascadeDescription defaultFontDescription;
defaultFontDescription.setOneFamily(defaultFontFamily);
defaultFontDescription.setSpecifiedSize(defaultFontSize);
defaultFontDescription.setComputedSize(defaultFontSize);
@@ -2048,13 +2168,13 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
newStyle->setFontDescription(defaultFontDescription);
}
- newStyle->font().update(newStyle->font().fontSelector());
+ newStyle->fontCascade().update(&document.fontSelector());
// Now map the font property longhands into the style.
- StyleResolver& styleResolver = canvas()->document().ensureStyleResolver();
- styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());
+ StyleResolver& styleResolver = canvas().styleResolver();
+ styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), WTFMove(newStyle));
styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
- styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariant, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariant).get());
+ styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariantCaps, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariantCaps).get());
styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
// As described in BUG66291, setting font-size and line-height on a font may entail a CSSPrimitiveValue::computeLengthDouble call,
@@ -2065,15 +2185,12 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
styleResolver.updateFont();
styleResolver.applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
- modifiableState().m_font = newStyle->font();
- modifiableState().m_font.update(styleResolver.fontSelector());
- modifiableState().m_realizedFont = true;
- styleResolver.fontSelector()->registerForInvalidationCallbacks(&modifiableState());
+ modifiableState().font.initialize(document.fontSelector(), *styleResolver.style());
}
String CanvasRenderingContext2D::textAlign() const
{
- return textAlignName(state().m_textAlign);
+ return textAlignName(state().textAlign);
}
void CanvasRenderingContext2D::setTextAlign(const String& s)
@@ -2081,15 +2198,15 @@ void CanvasRenderingContext2D::setTextAlign(const String& s)
TextAlign align;
if (!parseTextAlign(s, align))
return;
- if (state().m_textAlign == align)
+ if (state().textAlign == align)
return;
realizeSaves();
- modifiableState().m_textAlign = align;
+ modifiableState().textAlign = align;
}
String CanvasRenderingContext2D::textBaseline() const
{
- return textBaselineName(state().m_textBaseline);
+ return textBaselineName(state().textBaseline);
}
void CanvasRenderingContext2D::setTextBaseline(const String& s)
@@ -2097,30 +2214,63 @@ void CanvasRenderingContext2D::setTextBaseline(const String& s)
TextBaseline baseline;
if (!parseTextBaseline(s, baseline))
return;
- if (state().m_textBaseline == baseline)
+ if (state().textBaseline == baseline)
return;
realizeSaves();
- modifiableState().m_textBaseline = baseline;
+ modifiableState().textBaseline = baseline;
}
-void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
+inline TextDirection CanvasRenderingContext2D::toTextDirection(Direction direction, const RenderStyle** computedStyle) const
{
- drawTextInternal(text, x, y, true);
+ auto* style = (computedStyle || direction == Direction::Inherit) ? canvas().computedStyle() : nullptr;
+ if (computedStyle)
+ *computedStyle = style;
+ switch (direction) {
+ case Direction::Inherit:
+ return style ? style->direction() : LTR;
+ case Direction::RTL:
+ return RTL;
+ case Direction::LTR:
+ return LTR;
+ }
+ ASSERT_NOT_REACHED();
+ return LTR;
}
-void CanvasRenderingContext2D::fillText(const String& text, float x, float y, float maxWidth)
+String CanvasRenderingContext2D::direction() const
{
- drawTextInternal(text, x, y, true, maxWidth, true);
+ if (state().direction == Direction::Inherit)
+ canvas().document().updateStyleIfNeeded();
+ return toTextDirection(state().direction) == RTL ? ASCIILiteral("rtl") : ASCIILiteral("ltr");
}
-void CanvasRenderingContext2D::strokeText(const String& text, float x, float y)
+void CanvasRenderingContext2D::setDirection(const String& directionString)
{
- drawTextInternal(text, x, y, false);
+ Direction direction;
+ if (directionString == "inherit")
+ direction = Direction::Inherit;
+ else if (directionString == "rtl")
+ direction = Direction::RTL;
+ else if (directionString == "ltr")
+ direction = Direction::LTR;
+ else
+ return;
+
+ if (state().direction == direction)
+ return;
+
+ realizeSaves();
+ modifiableState().direction = direction;
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y, std::optional<float> maxWidth)
+{
+ drawTextInternal(text, x, y, true, maxWidth);
}
-void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, float maxWidth)
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, std::optional<float> maxWidth)
{
- drawTextInternal(text, x, y, false, maxWidth, true);
+ drawTextInternal(text, x, y, false, maxWidth);
}
static inline bool isSpaceThatNeedsReplacing(UChar c)
@@ -2137,13 +2287,12 @@ static inline bool isSpaceThatNeedsReplacing(UChar c)
static void normalizeSpaces(String& text)
{
size_t i = text.find(isSpaceThatNeedsReplacing);
-
if (i == notFound)
return;
unsigned textLength = text.length();
Vector<UChar> charVector(textLength);
- memcpy(charVector.data(), text.deprecatedCharacters(), textLength * sizeof(UChar));
+ StringView(text).getCharactersWithUpconvert(charVector.data());
charVector[i++] = ' ';
@@ -2151,37 +2300,38 @@ static void normalizeSpaces(String& text)
if (isSpaceThatNeedsReplacing(charVector[i]))
charVector[i] = ' ';
}
- text = String::adopt(charVector);
+ text = String::adopt(WTFMove(charVector));
}
-PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+Ref<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
{
- FontCachePurgePreventer fontCachePurgePreventer;
-
- RefPtr<TextMetrics> metrics = TextMetrics::create();
+ Ref<TextMetrics> metrics = TextMetrics::create();
String normalizedText = text;
normalizeSpaces(normalizedText);
- metrics->setWidth(accessFont().width(TextRun(normalizedText)));
+ metrics->setWidth(fontProxy().width(TextRun(normalizedText)));
- return metrics.release();
+ return metrics;
}
-void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
+void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, std::optional<float> maxWidth)
{
- GraphicsContext* c = drawingContext();
+ auto& fontProxy = this->fontProxy();
+ const auto& fontMetrics = fontProxy.fontMetrics();
+
+ auto* c = drawingContext();
if (!c)
return;
- if (!state().m_hasInvertibleTransform)
+ if (!state().hasInvertibleTransform)
return;
if (!std::isfinite(x) | !std::isfinite(y))
return;
- if (useMaxWidth && (!std::isfinite(maxWidth) || maxWidth <= 0))
+ if (maxWidth && (!std::isfinite(maxWidth.value()) || maxWidth.value() <= 0))
return;
// If gradient size is zero, then paint nothing.
- Gradient* gradient = c->strokeGradient();
+ auto* gradient = c->strokeGradient();
if (!fill && gradient && gradient->isZeroSize())
return;
@@ -2189,25 +2339,20 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
if (fill && gradient && gradient->isZeroSize())
return;
- FontCachePurgePreventer fontCachePurgePreventer;
-
- const Font& font = accessFont();
- const FontMetrics& fontMetrics = font.fontMetrics();
-
String normalizedText = text;
normalizeSpaces(normalizedText);
// FIXME: Need to turn off font smoothing.
- RenderStyle* computedStyle = canvas()->computedStyle();
- TextDirection direction = computedStyle ? computedStyle->direction() : LTR;
+ const RenderStyle* computedStyle;
+ auto direction = toTextDirection(state().direction, &computedStyle);
bool isRTL = direction == RTL;
bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : false;
- TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
+ TextRun textRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override, true);
// Draw the item text at the correct point.
FloatPoint location(x, y);
- switch (state().m_textBaseline) {
+ switch (state().textBaseline) {
case TopTextBaseline:
case HangingTextBaseline:
location.setY(y + fontMetrics.ascent());
@@ -2225,12 +2370,12 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
break;
}
- float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
+ float fontWidth = fontProxy.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
- useMaxWidth = (useMaxWidth && maxWidth < fontWidth);
- float width = useMaxWidth ? maxWidth : fontWidth;
+ bool useMaxWidth = maxWidth && maxWidth.value() < fontWidth;
+ float width = useMaxWidth ? maxWidth.value() : fontWidth;
- TextAlign align = state().m_textAlign;
+ auto align = state().textAlign;
if (align == StartTextAlign)
align = isRTL ? RightTextAlign : LeftTextAlign;
else if (align == EndTextAlign)
@@ -2249,41 +2394,73 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
// The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
FloatRect textRect = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
- width + fontMetrics.height(), fontMetrics.lineSpacing());
+ width + fontMetrics.height(), fontMetrics.lineSpacing());
if (!fill)
inflateStrokeRect(textRect);
#if USE(CG)
- const CanvasStyle& drawStyle = fill ? state().m_fillStyle : state().m_strokeStyle;
+ const CanvasStyle& drawStyle = fill ? state().fillStyle : state().strokeStyle;
if (drawStyle.canvasGradient() || drawStyle.canvasPattern()) {
IntRect maskRect = enclosingIntRect(textRect);
- std::unique_ptr<ImageBuffer> maskImage = c->createCompatibleBuffer(maskRect.size());
+ // If we have a shadow, we need to draw it before the mask operation.
+ // Follow a procedure similar to paintTextWithShadows in TextPainter.
+
+ if (shouldDrawShadows()) {
+ GraphicsContextStateSaver stateSaver(*c);
- GraphicsContext* maskImageContext = maskImage->context();
+ FloatSize offset(0, 2 * maskRect.height());
+
+ FloatSize shadowOffset;
+ float shadowRadius;
+ Color shadowColor;
+ c->getShadow(shadowOffset, shadowRadius, shadowColor);
+
+ FloatRect shadowRect(maskRect);
+ shadowRect.inflate(shadowRadius * 1.4);
+ shadowRect.move(shadowOffset * -1);
+ c->clip(shadowRect);
+
+ shadowOffset += offset;
+
+ c->setLegacyShadow(shadowOffset, shadowRadius, shadowColor);
+
+ if (fill)
+ c->setFillColor(Color::black);
+ else
+ c->setStrokeColor(Color::black);
+
+ fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
+ }
+
+ auto maskImage = ImageBuffer::createCompatibleBuffer(maskRect.size(), ColorSpaceSRGB, *c);
+ if (!maskImage)
+ return;
+
+ auto& maskImageContext = maskImage->context();
if (fill)
- maskImageContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ maskImageContext.setFillColor(Color::black);
else {
- maskImageContext->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
- maskImageContext->setStrokeThickness(c->strokeThickness());
+ maskImageContext.setStrokeColor(Color::black);
+ maskImageContext.setStrokeThickness(c->strokeThickness());
}
- maskImageContext->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+ maskImageContext.setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
if (useMaxWidth) {
- maskImageContext->translate(location.x() - maskRect.x(), location.y() - maskRect.y());
+ maskImageContext.translate(location.x() - maskRect.x(), location.y() - maskRect.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
- maskImageContext->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
+ maskImageContext.scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
+ fontProxy.drawBidiText(maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
} else {
- maskImageContext->translate(-maskRect.x(), -maskRect.y());
- maskImageContext->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
+ maskImageContext.translate(-maskRect.x(), -maskRect.y());
+ fontProxy.drawBidiText(maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady);
}
GraphicsContextStateSaver stateSaver(*c);
- c->clipToImageBuffer(maskImage.get(), maskRect);
- drawStyle.applyFillColor(c);
+ c->clipToImageBuffer(*maskImage, maskRect);
+ drawStyle.applyFillColor(*c);
c->fillRect(maskRect);
return;
}
@@ -2291,16 +2468,27 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+ GraphicsContextStateSaver stateSaver(*c);
if (useMaxWidth) {
- GraphicsContextStateSaver stateSaver(*c);
c->translate(location.x(), location.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- c->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
- } else
- c->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
+ location = FloatPoint();
+ }
- didDraw(textRect);
+ if (isFullCanvasCompositeMode(state().globalComposite)) {
+ beginCompositeLayer();
+ fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+ endCompositeLayer();
+ didDrawEntireCanvas();
+ } else if (state().globalComposite == CompositeCopy) {
+ clearCanvas();
+ fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+ didDrawEntireCanvas();
+ } else {
+ fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+ didDraw(textRect);
+ }
}
void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
@@ -2309,46 +2497,81 @@ void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
// This yields a slightly oversized rect but is very fast
// compared to Path::strokeBoundingRect().
static const float root2 = sqrtf(2);
- float delta = state().m_lineWidth / 2;
- if (state().m_lineJoin == MiterJoin)
- delta *= state().m_miterLimit;
- else if (state().m_lineCap == SquareCap)
+ float delta = state().lineWidth / 2;
+ if (state().lineJoin == MiterJoin)
+ delta *= state().miterLimit;
+ else if (state().lineCap == SquareCap)
delta *= root2;
-
rect.inflate(delta);
}
-const Font& CanvasRenderingContext2D::accessFont()
+auto CanvasRenderingContext2D::fontProxy() -> const FontProxy&
{
- canvas()->document().updateStyleIfNeeded();
-
- if (!state().m_realizedFont)
- setFont(state().m_unparsedFont);
- return state().m_font;
+ canvas().document().updateStyleIfNeeded();
+ if (!state().font.realized())
+ setFont(state().unparsedFont);
+ return state().font;
}
-#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+#if ENABLE(ACCELERATED_2D_CANVAS)
+
PlatformLayer* CanvasRenderingContext2D::platformLayer() const
{
- return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
+ return canvas().buffer() ? canvas().buffer()->platformLayer() : nullptr;
}
+
#endif
-bool CanvasRenderingContext2D::webkitImageSmoothingEnabled() const
+static inline InterpolationQuality smoothingToInterpolationQuality(CanvasRenderingContext2D::ImageSmoothingQuality quality)
+{
+ switch (quality) {
+ case CanvasRenderingContext2D::ImageSmoothingQuality::Low:
+ return InterpolationLow;
+ case CanvasRenderingContext2D::ImageSmoothingQuality::Medium:
+ return InterpolationMedium;
+ case CanvasRenderingContext2D::ImageSmoothingQuality::High:
+ return InterpolationHigh;
+ }
+
+ ASSERT_NOT_REACHED();
+ return InterpolationLow;
+};
+
+auto CanvasRenderingContext2D::imageSmoothingQuality() const -> ImageSmoothingQuality
{
- return state().m_imageSmoothingEnabled;
+ return state().imageSmoothingQuality;
}
-void CanvasRenderingContext2D::setWebkitImageSmoothingEnabled(bool enabled)
+void CanvasRenderingContext2D::setImageSmoothingQuality(ImageSmoothingQuality quality)
{
- if (enabled == state().m_imageSmoothingEnabled)
+ if (quality == state().imageSmoothingQuality)
return;
realizeSaves();
- modifiableState().m_imageSmoothingEnabled = enabled;
- GraphicsContext* c = drawingContext();
+ modifiableState().imageSmoothingQuality = quality;
+
+ if (!state().imageSmoothingEnabled)
+ return;
+
+ if (auto* context = drawingContext())
+ context->setImageInterpolationQuality(smoothingToInterpolationQuality(quality));
+}
+
+bool CanvasRenderingContext2D::imageSmoothingEnabled() const
+{
+ return state().imageSmoothingEnabled;
+}
+
+void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
+{
+ if (enabled == state().imageSmoothingEnabled)
+ return;
+
+ realizeSaves();
+ modifiableState().imageSmoothingEnabled = enabled;
+ auto* c = drawingContext();
if (c)
- c->setImageInterpolationQuality(enabled ? DefaultInterpolationQuality : InterpolationNone);
+ c->setImageInterpolationQuality(enabled ? smoothingToInterpolationQuality(state().imageSmoothingQuality) : InterpolationNone);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
index 27b7e33c8..13bdc553b 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,27 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasRenderingContext2D_h
-#define CanvasRenderingContext2D_h
+#pragma once
#include "AffineTransform.h"
-#include "CanvasPathMethods.h"
+#include "CanvasPath.h"
#include "CanvasRenderingContext.h"
#include "CanvasStyle.h"
#include "Color.h"
-#include "ColorSpace.h"
#include "FloatSize.h"
-#include "Font.h"
+#include "FontCascade.h"
+#include "FontSelectorClient.h"
+#include "GraphicsContext.h"
#include "GraphicsTypes.h"
#include "ImageBuffer.h"
#include "Path.h"
+#include "PlatformLayer.h"
+#include "TextFlags.h"
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-#if USE(ACCELERATED_COMPOSITING)
-#include "PlatformLayer.h"
-#endif
-
namespace WebCore {
class CanvasGradient;
@@ -57,22 +55,17 @@ class HTMLVideoElement;
class ImageData;
class TextMetrics;
-typedef int ExceptionCode;
+#if ENABLE(VIDEO)
+using CanvasImageSource = Variant<RefPtr<HTMLImageElement>, RefPtr<HTMLVideoElement>, RefPtr<HTMLCanvasElement>>;
+#else
+using CanvasImageSource = Variant<RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
+#endif
-class CanvasRenderingContext2D : public CanvasRenderingContext, public CanvasPathMethods {
+class CanvasRenderingContext2D final : public CanvasRenderingContext, public CanvasPath {
public:
- static OwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
- {
- return adoptPtr(new CanvasRenderingContext2D(canvas, usesCSSCompatibilityParseMode, usesDashboardCompatibilityMode));
- }
+ CanvasRenderingContext2D(HTMLCanvasElement&, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
virtual ~CanvasRenderingContext2D();
- const CanvasStyle& strokeStyle() const { return state().m_strokeStyle; }
- void setStrokeStyle(CanvasStyle);
-
- const CanvasStyle& fillStyle() const { return state().m_fillStyle; }
- void setFillStyle(CanvasStyle);
-
float lineWidth() const;
void setLineWidth(float);
@@ -87,12 +80,11 @@ public:
const Vector<float>& getLineDash() const;
void setLineDash(const Vector<float>&);
+ const Vector<float>& webkitLineDash() const { return getLineDash(); }
void setWebkitLineDash(const Vector<float>&);
float lineDashOffset() const;
void setLineDashOffset(float);
- float webkitLineDashOffset() const;
- void setWebkitLineDashOffset(float);
float shadowOffsetX() const;
void setShadowOffsetX(float);
@@ -115,92 +107,88 @@ public:
void save() { ++m_unrealizedSaveCount; }
void restore();
+ // This is a no-op in a direct-2d canvas.
+ void commit() { }
+
void scale(float sx, float sy);
void rotate(float angleInRadians);
void translate(float tx, float ty);
void transform(float m11, float m12, float m21, float m22, float dx, float dy);
void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
+ void resetTransform();
- void setStrokeColor(const String& color);
- void setStrokeColor(float grayLevel);
- void setStrokeColor(const String& color, float alpha);
- void setStrokeColor(float grayLevel, float alpha);
+ void setStrokeColor(const String& color, std::optional<float> alpha = std::nullopt);
+ void setStrokeColor(float grayLevel, float alpha = 1.0);
void setStrokeColor(float r, float g, float b, float a);
void setStrokeColor(float c, float m, float y, float k, float a);
- void setFillColor(const String& color);
- void setFillColor(float grayLevel);
- void setFillColor(const String& color, float alpha);
- void setFillColor(float grayLevel, float alpha);
+ void setFillColor(const String& color, std::optional<float> alpha = std::nullopt);
+ void setFillColor(float grayLevel, float alpha = 1.0f);
void setFillColor(float r, float g, float b, float a);
void setFillColor(float c, float m, float y, float k, float a);
void beginPath();
-#if ENABLE(CANVAS_PATH)
- PassRefPtr<DOMPath> currentPath();
- void setCurrentPath(DOMPath*);
-#endif
+ enum class WindingRule { Nonzero, Evenodd };
- void fill(const String& winding = "nonzero");
+ void fill(WindingRule = WindingRule::Nonzero);
void stroke();
- void clip(const String& winding = "nonzero");
+ void clip(WindingRule = WindingRule::Nonzero);
- bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
- bool isPointInStroke(const float x, const float y);
+ void fill(DOMPath&, WindingRule = WindingRule::Nonzero);
+ void stroke(DOMPath&);
+ void clip(DOMPath&, WindingRule = WindingRule::Nonzero);
+
+ bool isPointInPath(float x, float y, WindingRule = WindingRule::Nonzero);
+ bool isPointInStroke(float x, float y);
+
+ bool isPointInPath(DOMPath&, float x, float y, WindingRule = WindingRule::Nonzero);
+ bool isPointInStroke(DOMPath&, float x, float y);
void clearRect(float x, float y, float width, float height);
void fillRect(float x, float y, float width, float height);
void strokeRect(float x, float y, float width, float height);
- void setShadow(float width, float height, float blur);
- void setShadow(float width, float height, float blur, const String& color);
- void setShadow(float width, float height, float blur, float grayLevel);
- void setShadow(float width, float height, float blur, const String& color, float alpha);
- void setShadow(float width, float height, float blur, float grayLevel, float alpha);
+ void setShadow(float width, float height, float blur, const String& color = String(), std::optional<float> alpha = std::nullopt);
+ void setShadow(float width, float height, float blur, float grayLevel, float alpha = 1.0);
void setShadow(float width, float height, float blur, float r, float g, float b, float a);
void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
void clearShadow();
- void drawImage(HTMLImageElement*, float x, float y, ExceptionCode&);
- void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionCode&);
- void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
- void drawImage(HTMLCanvasElement*, float x, float y, ExceptionCode&);
- void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionCode&);
- void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
- void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&, ExceptionCode&);
-#if ENABLE(VIDEO)
- void drawImage(HTMLVideoElement*, float x, float y, ExceptionCode&);
- void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionCode&);
- void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
- void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
-#endif
+ ExceptionOr<void> drawImage(CanvasImageSource&&, float dx, float dy);
+ ExceptionOr<void> drawImage(CanvasImageSource&&, float dx, float dy, float dw, float dh);
+ ExceptionOr<void> drawImage(CanvasImageSource&&, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
- float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
+ void drawImageFromRect(HTMLImageElement&, float sx = 0, float sy = 0, float sw = 0, float sh = 0, float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
void setAlpha(float);
void setCompositeOperation(const String&);
- PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
- PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
- PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
- PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
+ using Style = Variant<String, RefPtr<CanvasGradient>, RefPtr<CanvasPattern>>;
+ Style strokeStyle() const;
+ void setStrokeStyle(Style&&);
+ Style fillStyle() const;
+ void setFillStyle(Style&&);
+
+ ExceptionOr<Ref<CanvasGradient>> createLinearGradient(float x0, float y0, float x1, float y1);
+ ExceptionOr<Ref<CanvasGradient>> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ ExceptionOr<RefPtr<CanvasPattern>> createPattern(CanvasImageSource&&, const String& repetition);
+
+ ExceptionOr<RefPtr<ImageData>> createImageData(ImageData*) const;
+ ExceptionOr<RefPtr<ImageData>> createImageData(float width, float height) const;
+ ExceptionOr<RefPtr<ImageData>> getImageData(float sx, float sy, float sw, float sh) const;
+ ExceptionOr<RefPtr<ImageData>> webkitGetImageDataHD(float sx, float sy, float sw, float sh) const;
+ void putImageData(ImageData&, float dx, float dy);
+ void putImageData(ImageData&, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
+ void webkitPutImageDataHD(ImageData&, float dx, float dy);
+ void webkitPutImageDataHD(ImageData&, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
- PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionCode&) const;
- PassRefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const;
- PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
- PassRefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode&) const;
- void putImageData(ImageData*, float dx, float dy, ExceptionCode&);
- void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
- void webkitPutImageDataHD(ImageData*, float dx, float dy, ExceptionCode&);
- void webkitPutImageDataHD(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
+ void drawFocusIfNeeded(Element&);
+ void drawFocusIfNeeded(DOMPath&, Element&);
- float webkitBackingStorePixelRatio() const { return canvas()->deviceScaleFactor(); }
+ float webkitBackingStorePixelRatio() const { return 1; }
void reset();
@@ -213,55 +201,94 @@ public:
String textBaseline() const;
void setTextBaseline(const String&);
- void fillText(const String& text, float x, float y);
- void fillText(const String& text, float x, float y, float maxWidth);
- void strokeText(const String& text, float x, float y);
- void strokeText(const String& text, float x, float y, float maxWidth);
- PassRefPtr<TextMetrics> measureText(const String& text);
+ String direction() const;
+ void setDirection(const String&);
+
+ void fillText(const String& text, float x, float y, std::optional<float> maxWidth = std::nullopt);
+ void strokeText(const String& text, float x, float y, std::optional<float> maxWidth = std::nullopt);
+ Ref<TextMetrics> measureText(const String& text);
+
+ LineCap getLineCap() const { return state().lineCap; }
+ LineJoin getLineJoin() const { return state().lineJoin; }
+
+ bool imageSmoothingEnabled() const;
+ void setImageSmoothingEnabled(bool);
+
+ enum class ImageSmoothingQuality { Low, Medium, High };
+ ImageSmoothingQuality imageSmoothingQuality() const;
+ void setImageSmoothingQuality(ImageSmoothingQuality);
+
+ bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; };
+ void setUsesDisplayListDrawing(bool flag) { m_usesDisplayListDrawing = flag; };
- LineCap getLineCap() const { return state().m_lineCap; }
- LineJoin getLineJoin() const { return state().m_lineJoin; }
+ bool tracksDisplayListReplay() const { return m_tracksDisplayListReplay; }
+ void setTracksDisplayListReplay(bool);
- bool webkitImageSmoothingEnabled() const;
- void setWebkitImageSmoothingEnabled(bool);
+ String displayListAsText(DisplayList::AsTextFlags) const;
+ String replayDisplayListAsText(DisplayList::AsTextFlags) const;
private:
- struct State : FontSelectorClient {
+ enum class Direction {
+ Inherit,
+ RTL,
+ LTR
+ };
+
+ class FontProxy : public FontSelectorClient {
+ public:
+ FontProxy() = default;
+ virtual ~FontProxy();
+ FontProxy(const FontProxy&);
+ FontProxy& operator=(const FontProxy&);
+
+ bool realized() const { return m_font.fontSelector(); }
+ void initialize(FontSelector&, const RenderStyle&);
+ FontMetrics fontMetrics() const;
+ const FontCascadeDescription& fontDescription() const;
+ float width(const TextRun&) const;
+ void drawBidiText(GraphicsContext&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction) const;
+
+ private:
+ void update(FontSelector&);
+ void fontsNeedUpdate(FontSelector&) override;
+
+ FontCascade m_font;
+ };
+
+ struct State final {
State();
- virtual ~State();
State(const State&);
State& operator=(const State&);
- virtual void fontsNeedUpdate(FontSelector*) override;
-
- String m_unparsedStrokeColor;
- String m_unparsedFillColor;
- CanvasStyle m_strokeStyle;
- CanvasStyle m_fillStyle;
- float m_lineWidth;
- LineCap m_lineCap;
- LineJoin m_lineJoin;
- float m_miterLimit;
- FloatSize m_shadowOffset;
- float m_shadowBlur;
- RGBA32 m_shadowColor;
- float m_globalAlpha;
- CompositeOperator m_globalComposite;
- BlendMode m_globalBlend;
- AffineTransform m_transform;
- bool m_hasInvertibleTransform;
- Vector<float> m_lineDash;
- float m_lineDashOffset;
- bool m_imageSmoothingEnabled;
+ String unparsedStrokeColor;
+ String unparsedFillColor;
+ CanvasStyle strokeStyle;
+ CanvasStyle fillStyle;
+ float lineWidth;
+ LineCap lineCap;
+ LineJoin lineJoin;
+ float miterLimit;
+ FloatSize shadowOffset;
+ float shadowBlur;
+ Color shadowColor;
+ float globalAlpha;
+ CompositeOperator globalComposite;
+ BlendMode globalBlend;
+ AffineTransform transform;
+ bool hasInvertibleTransform;
+ Vector<float> lineDash;
+ float lineDashOffset;
+ bool imageSmoothingEnabled;
+ ImageSmoothingQuality imageSmoothingQuality;
// Text state.
- TextAlign m_textAlign;
- TextBaseline m_textBaseline;
+ TextAlign textAlign;
+ TextBaseline textBaseline;
+ Direction direction;
- String m_unparsedFont;
- Font m_font;
- bool m_realizedFont;
+ String unparsedFont;
+ FontProxy font;
};
enum CanvasDidDrawOption {
@@ -272,40 +299,64 @@ private:
CanvasDidDrawApplyAll = 0xffffffff
};
- CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
-
- State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
+ State& modifiableState() { ASSERT(!m_unrealizedSaveCount || m_stateStack.size() >= MaxSaveCount); return m_stateStack.last(); }
const State& state() const { return m_stateStack.last(); }
void applyLineDash() const;
- void setShadow(const FloatSize& offset, float blur, RGBA32 color);
+ void setShadow(const FloatSize& offset, float blur, const Color&);
void applyShadow();
bool shouldDrawShadows() const;
void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
void didDrawEntireCanvas();
+ void paintRenderingResultsToCanvas() override;
+
GraphicsContext* drawingContext() const;
void unwindStateStack();
- void realizeSaves()
- {
- if (m_unrealizedSaveCount)
- realizeSavesLoop();
- }
+ void realizeSaves();
void realizeSavesLoop();
void applyStrokePattern();
void applyFillPattern();
- void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
+ void setStrokeStyle(CanvasStyle);
+ void setFillStyle(CanvasStyle);
- const Font& accessFont();
+ ExceptionOr<RefPtr<CanvasPattern>> createPattern(HTMLImageElement&, bool repeatX, bool repeatY);
+ ExceptionOr<RefPtr<CanvasPattern>> createPattern(HTMLCanvasElement&, bool repeatX, bool repeatY);
+#if ENABLE(VIDEO)
+ ExceptionOr<RefPtr<CanvasPattern>> createPattern(HTMLVideoElement&, bool repeatX, bool repeatY);
+#endif
-#if ENABLE(DASHBOARD_SUPPORT)
- void clearPathForDashboardBackwardCompatibilityMode();
+ ExceptionOr<void> drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect);
+ ExceptionOr<void> drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&);
+ ExceptionOr<void> drawImage(HTMLCanvasElement&, const FloatRect& srcRect, const FloatRect& dstRect);
+#if ENABLE(VIDEO)
+ ExceptionOr<void> drawImage(HTMLVideoElement&, const FloatRect& srcRect, const FloatRect& dstRect);
#endif
+ void drawTextInternal(const String& text, float x, float y, bool fill, std::optional<float> maxWidth = std::nullopt);
+
+ // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
+ // Therefore, all font operations must pass through the State.
+ const FontProxy& fontProxy();
+
+ void clearPathForDashboardBackwardCompatibilityMode();
+
+ void beginCompositeLayer();
+ void endCompositeLayer();
+
+ void fillInternal(const Path&, WindingRule);
+ void strokeInternal(const Path&);
+ void clipInternal(const Path&, WindingRule);
+
+ bool isPointInPathInternal(const Path&, float x, float y, WindingRule);
+ bool isPointInStrokeInternal(const Path&, float x, float y);
+
+ void drawFocusIfNeededInternal(const Path&, Element&);
+
void clearCanvas();
Path transformAreaToDevice(const Path&) const;
Path transformAreaToDevice(const FloatRect&) const;
@@ -313,35 +364,39 @@ private:
template<class T> IntRect calculateCompositingBufferRect(const T&, IntSize*);
std::unique_ptr<ImageBuffer> createCompositingBuffer(const IntRect&);
- void compositeBuffer(ImageBuffer*, const IntRect&, CompositeOperator);
+ void compositeBuffer(ImageBuffer&, const IntRect&, CompositeOperator);
void inflateStrokeRect(FloatRect&) const;
- template<class T> void fullCanvasCompositedFill(const T&);
- template<class T> void fullCanvasCompositedDrawImage(T*, ColorSpace, const FloatRect&, const FloatRect&, CompositeOperator);
+ template<class T> void fullCanvasCompositedDrawImage(T&, const FloatRect&, const FloatRect&, CompositeOperator);
- void prepareGradientForDashboard(CanvasGradient* gradient) const;
+ void prepareGradientForDashboard(CanvasGradient& gradient) const;
- PassRefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode&) const;
- void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
+ ExceptionOr<RefPtr<ImageData>> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh) const;
+ void putImageData(ImageData&, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
- virtual bool is2d() const override { return true; }
- virtual bool isAccelerated() const override;
+ bool is2d() const override { return true; }
+ bool isAccelerated() const override;
- virtual bool hasInvertibleTransform() const override { return state().m_hasInvertibleTransform; }
+ bool hasInvertibleTransform() const override { return state().hasInvertibleTransform; }
+ TextDirection toTextDirection(Direction, const RenderStyle** computedStyle = nullptr) const;
-#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
- virtual PlatformLayer* platformLayer() const override;
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ PlatformLayer* platformLayer() const override;
#endif
+ static const unsigned MaxSaveCount = 1024 * 16;
Vector<State, 1> m_stateStack;
- unsigned m_unrealizedSaveCount;
+ unsigned m_unrealizedSaveCount { 0 };
bool m_usesCSSCompatibilityParseMode;
#if ENABLE(DASHBOARD_SUPPORT)
bool m_usesDashboardCompatibilityMode;
#endif
+ bool m_usesDisplayListDrawing { false };
+ bool m_tracksDisplayListReplay { false };
+ mutable std::unique_ptr<struct DisplayListDrawingContext> m_recordingContext;
};
} // namespace WebCore
-#endif
+SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::CanvasRenderingContext2D, is2d())
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
index ffac89618..6dbb17553 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,146 +23,168 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum ImageSmoothingQuality { "low", "medium", "high" };
enum CanvasWindingRule { "nonzero", "evenodd" };
-interface CanvasRenderingContext2D : CanvasRenderingContext {
+// FIXME: This should include SVGImageElement and ImageBitmap.
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+typedef (HTMLImageElement or HTMLVideoElement or HTMLCanvasElement) CanvasImageSource;
+#else
+typedef (HTMLImageElement or HTMLCanvasElement) CanvasImageSource;
+#endif
+
+[
+ CustomIsReachable,
+ JSGenerateToJSObject,
+ JSCustomMarkFunction,
+] interface CanvasRenderingContext2D {
+
+ // back-reference to the canvas
+ readonly attribute HTMLCanvasElement canvas;
void save();
void restore();
- void scale(float sx, float sy);
- void rotate(float angle);
- void translate(float tx, float ty);
- void transform(float m11, float m12, float m21, float m22, float dx, float dy);
- void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
+ void commit();
+
+ void scale(unrestricted float sx, unrestricted float sy);
+ void rotate(unrestricted float angle);
+ void translate(unrestricted float tx, unrestricted float ty);
+ void transform(unrestricted float m11, unrestricted float m12, unrestricted float m21, unrestricted float m22,
+ unrestricted float dx, unrestricted float dy);
+ void setTransform(unrestricted float m11, unrestricted float m12, unrestricted float m21, unrestricted float m22,
+ unrestricted float dx, unrestricted float dy);
+ void resetTransform();
- attribute float globalAlpha;
- [TreatNullAs=NullString] attribute DOMString globalCompositeOperation;
+ attribute unrestricted float globalAlpha;
- [RaisesException] CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
- [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ attribute DOMString globalCompositeOperation;
- attribute float lineWidth;
- [TreatNullAs=NullString] attribute DOMString lineCap;
- [TreatNullAs=NullString] attribute DOMString lineJoin;
- attribute float miterLimit;
+ attribute unrestricted float lineWidth;
+ attribute DOMString lineCap;
+ attribute DOMString lineJoin;
+ attribute unrestricted float miterLimit;
- attribute float shadowOffsetX;
- attribute float shadowOffsetY;
- attribute float shadowBlur;
- [TreatNullAs=NullString] attribute DOMString shadowColor;
+ attribute unrestricted float shadowOffsetX;
+ attribute unrestricted float shadowOffsetY;
+ attribute unrestricted float shadowBlur;
+ attribute DOMString shadowColor;
- void setLineDash(sequence<float> dash);
- sequence<float> getLineDash();
- attribute float lineDashOffset;
+ void setLineDash(sequence<unrestricted float> dash);
+ sequence<unrestricted float> getLineDash();
+ attribute unrestricted float lineDashOffset;
- [Custom] attribute Array webkitLineDash;
- attribute float webkitLineDashOffset;
+ attribute sequence<unrestricted float> webkitLineDash;
+ [ImplementedAs=lineDashOffset] attribute unrestricted float webkitLineDashOffset;
- void clearRect(float x, float y, float width, float height);
- void fillRect(float x, float y, float width, float height);
+ void clearRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void fillRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
void beginPath();
-#if defined(ENABLE_CANVAS_PATH) && ENABLE_CANVAS_PATH
- attribute DOMPath currentPath;
-#endif
+ void fill(DOMPath path, optional CanvasWindingRule winding = "nonzero");
+ void stroke(DOMPath path);
+ void clip(DOMPath path, optional CanvasWindingRule winding = "nonzero");
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- void closePath();
- void moveTo(float x, float y);
- void lineTo(float x, float y);
- void quadraticCurveTo(float cpx, float cpy, float x, float y);
- void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
- [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
- void rect(float x, float y, float width, float height);
- [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
-
- void fill(optional CanvasWindingRule winding);
+ void fill(optional CanvasWindingRule winding = "nonzero");
void stroke();
- void clip(optional CanvasWindingRule winding);
- boolean isPointInPath(float x, float y, optional CanvasWindingRule winding);
- boolean isPointInStroke(float x, float y);
+ void clip(optional CanvasWindingRule winding = "nonzero");
+
+ boolean isPointInPath(DOMPath path, unrestricted float x, unrestricted float y, optional CanvasWindingRule winding = "nonzero");
+ boolean isPointInStroke(DOMPath path, unrestricted float x, unrestricted float y);
+
+ boolean isPointInPath(unrestricted float x, unrestricted float y, optional CanvasWindingRule winding = "nonzero");
+ boolean isPointInStroke(unrestricted float x, unrestricted float y);
// text
attribute DOMString font;
attribute DOMString textAlign;
attribute DOMString textBaseline;
+ attribute DOMString direction;
TextMetrics measureText(DOMString text);
// other
- void setAlpha([Default=Undefined] optional float alpha);
- void setCompositeOperation([Default=Undefined] optional DOMString compositeOperation);
+ void setAlpha(optional unrestricted float alpha = NaN);
-#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
- void setLineWidth([Default=Undefined] optional float width);
- void setLineCap([Default=Undefined] optional DOMString cap);
- void setLineJoin([Default=Undefined] optional DOMString join);
- void setMiterLimit([Default=Undefined] optional float limit);
-#endif
+ // FIXME: Using "undefined" as default parameter value is wrong.
+ void setCompositeOperation(optional DOMString compositeOperation = "undefined");
- void clearShadow();
-
- void fillText(DOMString text, float x, float y, optional float maxWidth);
- void strokeText(DOMString text, float x, float y, optional float maxWidth);
+ void setLineWidth(optional unrestricted float width = NaN);
- void setStrokeColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setStrokeColor(float grayLevel, optional float alpha);
- void setStrokeColor(float r, float g, float b, float a);
- void setStrokeColor(float c, float m, float y, float k, float a);
+ // FIXME: Using "undefined" as default parameter value is wrong.
+ void setLineCap(optional DOMString cap = "undefined");
+ void setLineJoin(optional DOMString join = "undefined");
- void setFillColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setFillColor(float grayLevel, optional float alpha);
- void setFillColor(float r, float g, float b, float a);
- void setFillColor(float c, float m, float y, float k, float a);
+ void setMiterLimit(optional unrestricted float limit = NaN);
- void strokeRect(float x, float y, float width, float height);
+ void clearShadow();
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y);
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLImageElement? image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
-#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y);
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLVideoElement? video, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
-#endif
+ void fillText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
+ void strokeText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
- void drawImageFromRect(HTMLImageElement image,
- optional float sx, optional float sy, optional float sw, optional float sh,
- optional float dx, optional float dy, optional float dw, optional float dh,
- optional DOMString compositeOperation);
+ void setStrokeColor(DOMString color, optional unrestricted float alpha);
+ void setStrokeColor(unrestricted float grayLevel, optional float alpha = 1);
+ void setStrokeColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ void setStrokeColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
- void setShadow(float width, float height, float blur, [StrictTypeChecking] optional DOMString color, optional float alpha);
- void setShadow(float width, float height, float blur, float grayLevel, optional float alpha);
- void setShadow(float width, float height, float blur, float r, float g, float b, float a);
- void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
+ void setFillColor(DOMString color, optional unrestricted float alpha);
+ void setFillColor(unrestricted float grayLevel, optional unrestricted float alpha = 1);
+ void setFillColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ void setFillColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy);
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
+ void strokeRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy);
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
+ // FIXME: This should move to the CanvasDrawImage interface.
+ // FIXME: All the unrestricted float arguments below should be unrestricted doubles.
+ [MayThrowException] void drawImage(CanvasImageSource image, unrestricted float x, unrestricted float y);
+ [MayThrowException] void drawImage(CanvasImageSource image, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [MayThrowException] void drawImage(CanvasImageSource image, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
- [RaisesException] CanvasPattern createPattern(HTMLCanvasElement? canvas, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] CanvasPattern createPattern(HTMLImageElement? image, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] ImageData createImageData(ImageData? imagedata);
- [RaisesException] ImageData createImageData(float sw, float sh);
- [Custom] attribute custom strokeStyle;
- [Custom] attribute custom fillStyle;
+ void drawImageFromRect(HTMLImageElement image,
+ optional unrestricted float sx = 0, optional unrestricted float sy = 0, optional unrestricted float sw = 0, optional unrestricted float sh = 0,
+ optional unrestricted float dx = 0, optional unrestricted float dy = 0, optional unrestricted float dw = 0, optional unrestricted float dh = 0,
+ optional DOMString compositeOperation = "");
+
+ void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur,
+ optional DOMString color, optional unrestricted float alpha);
+ void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float grayLevel,
+ optional unrestricted float alpha = 1);
+ void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float r,
+ unrestricted float g, unrestricted float b, unrestricted float a);
+ void setShadow(float width, unrestricted float height, unrestricted float blur, unrestricted float c, unrestricted float m,
+ unrestricted float y, unrestricted float k, unrestricted float a);
+
+ void putImageData(ImageData imagedata, float dx, float dy);
+ void putImageData(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
+
+ void webkitPutImageDataHD(ImageData imagedata, float dx, float dy);
+ void webkitPutImageDataHD(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
+
+ [MayThrowException] ImageData createImageData(ImageData? imagedata);
+ [MayThrowException] ImageData createImageData(float sw, float sh);
+
+ attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle;
+ attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle;
+ [MayThrowException] CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
+ [MayThrowException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ [MayThrowException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
// pixel manipulation
- [RaisesException] ImageData getImageData(float sx, float sy, float sw, float sh);
-
- [RaisesException] ImageData webkitGetImageDataHD(float sx, float sy, float sw, float sh);
+ [MayThrowException] ImageData getImageData(float sx, float sy, float sw, float sh);
+ [MayThrowException] ImageData webkitGetImageDataHD(float sx, float sy, float sw, float sh);
+
+ // Focus rings
+ void drawFocusIfNeeded(Element element);
+ void drawFocusIfNeeded(DOMPath path, Element element);
readonly attribute float webkitBackingStorePixelRatio;
- attribute boolean webkitImageSmoothingEnabled;
+ attribute boolean imageSmoothingEnabled;
+ [ImplementedAs=imageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
+ attribute ImageSmoothingQuality imageSmoothingQuality;
};
+CanvasRenderingContext2D implements CanvasPath;
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
index 8b0883951..052fa3164 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.cpp
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
@@ -13,10 +13,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -43,260 +43,182 @@
namespace WebCore {
-enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
+static bool isCurrentColorString(const String& colorString)
+{
+ return equalLettersIgnoringASCIICase(colorString, "currentcolor");
+}
-static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0)
+static Color parseColor(const String& colorString, Document* document = nullptr)
{
- if (equalIgnoringCase(colorString, "currentcolor"))
- return ParsedCurrentColor;
- if (CSSParser::parseColor(parsedColor, colorString))
- return ParsedRGBA;
- if (CSSParser::parseSystemColor(parsedColor, colorString, document))
- return ParsedSystemColor;
- return ParseFailed;
+ Color color = CSSParser::parseColor(colorString);
+ if (color.isValid())
+ return color;
+ return CSSParser::parseSystemColor(colorString, document);
}
-RGBA32 currentColor(HTMLCanvasElement* canvas)
+Color currentColor(HTMLCanvasElement* canvas)
{
- if (!canvas || !canvas->inDocument() || !canvas->inlineStyle())
+ if (!canvas || !canvas->isConnected() || !canvas->inlineStyle())
return Color::black;
- RGBA32 rgba = Color::black;
- CSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
- return rgba;
+ Color color = CSSParser::parseColor(canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
+ if (!color.isValid())
+ return Color::black;
+ return color;
}
-bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
+Color parseColorOrCurrentColor(const String& colorString, HTMLCanvasElement* canvas)
{
- ColorParseResult parseResult = parseColor(parsedColor, colorString, canvas ? &canvas->document() : 0);
- switch (parseResult) {
- case ParsedRGBA:
- case ParsedSystemColor:
- return true;
- case ParsedCurrentColor:
- parsedColor = currentColor(canvas);
- return true;
- case ParseFailed:
- return false;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
+ if (isCurrentColorString(colorString))
+ return currentColor(canvas);
+
+ return parseColor(colorString, canvas ? &canvas->document() : nullptr);
}
-CanvasStyle::CanvasStyle(RGBA32 rgba)
- : m_rgba(rgba)
- , m_type(RGBA)
+CanvasStyle::CanvasStyle(Color color)
+ : m_style(color)
{
}
CanvasStyle::CanvasStyle(float grayLevel, float alpha)
- : m_rgba(makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha))
- , m_type(RGBA)
+ : m_style(Color { grayLevel, grayLevel, grayLevel, alpha })
{
}
CanvasStyle::CanvasStyle(float r, float g, float b, float a)
- : m_rgba(makeRGBA32FromFloats(r, g, b, a))
- , m_type(RGBA)
+ : m_style(Color { r, g, b, a })
{
}
CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
- : m_cmyka(new CMYKAValues(makeRGBAFromCMYKA(c, m, y, k, a), c, m, y, k, a))
- , m_type(CMYKA)
+ : m_style(CMYKAColor { Color { c, m, y, k, a }, c, m, y, k, a })
{
}
-CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
- : m_gradient(gradient.leakRef())
- , m_type(Gradient)
+CanvasStyle::CanvasStyle(CanvasGradient& gradient)
+ : m_style(makeRefPtr(gradient))
{
- if (!m_gradient)
- m_type = Invalid;
}
-CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
- : m_pattern(pattern.leakRef())
- , m_type(ImagePattern)
+CanvasStyle::CanvasStyle(CanvasPattern& pattern)
+ : m_style(makeRefPtr(pattern))
{
- if (!m_pattern)
- m_type = Invalid;
}
-CanvasStyle::~CanvasStyle()
+inline CanvasStyle::CanvasStyle(CurrentColor color)
+ : m_style(color)
{
- if (m_type == Gradient)
- m_gradient->deref();
- else if (m_type == ImagePattern)
- m_pattern->deref();
- else if (m_type == CMYKA)
- delete m_cmyka;
}
-CanvasStyle CanvasStyle::createFromString(const String& color, Document* document)
+CanvasStyle CanvasStyle::createFromString(const String& colorString, Document* document)
{
- RGBA32 rgba;
- ColorParseResult parseResult = parseColor(rgba, color, document);
- switch (parseResult) {
- case ParsedRGBA:
- case ParsedSystemColor:
- return CanvasStyle(rgba);
- case ParsedCurrentColor:
- return CanvasStyle(ConstructCurrentColor);
- case ParseFailed:
- return CanvasStyle();
- default:
- ASSERT_NOT_REACHED();
- return CanvasStyle();
- }
+ if (isCurrentColorString(colorString))
+ return CurrentColor { std::nullopt };
+
+ Color color = parseColor(colorString, document);
+ if (!color.isValid())
+ return { };
+
+ return color;
}
-CanvasStyle CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha)
+CanvasStyle CanvasStyle::createFromStringWithOverrideAlpha(const String& colorString, float alpha)
{
- RGBA32 rgba;
- ColorParseResult parseResult = parseColor(rgba, color);
- switch (parseResult) {
- case ParsedRGBA:
- return CanvasStyle(colorWithOverrideAlpha(rgba, alpha));
- case ParsedCurrentColor:
- return CanvasStyle(CurrentColorWithOverrideAlpha, alpha);
- case ParseFailed:
- return CanvasStyle();
- default:
- ASSERT_NOT_REACHED();
- return CanvasStyle();
- }
+ if (isCurrentColorString(colorString))
+ return CurrentColor { alpha };
+
+ Color color = parseColor(colorString);
+ if (!color.isValid())
+ return { };
+
+ return Color { colorWithOverrideAlpha(color.rgb(), alpha) };
}
bool CanvasStyle::isEquivalentColor(const CanvasStyle& other) const
{
- if (m_type != other.m_type)
- return false;
+ if (WTF::holds_alternative<Color>(m_style) && WTF::holds_alternative<Color>(other.m_style))
+ return WTF::get<Color>(m_style) == WTF::get<Color>(other.m_style);
- switch (m_type) {
- case RGBA:
- return m_rgba == other.m_rgba;
- case CMYKA:
- return m_cmyka->c == other.m_cmyka->c
- && m_cmyka->m == other.m_cmyka->m
- && m_cmyka->y == other.m_cmyka->y
- && m_cmyka->k == other.m_cmyka->k
- && m_cmyka->a == other.m_cmyka->a;
- case Gradient:
- case ImagePattern:
- case CurrentColor:
- case CurrentColorWithOverrideAlpha:
- return false;
- case Invalid:
- break;
+ if (WTF::holds_alternative<CMYKAColor>(m_style) && WTF::holds_alternative<CMYKAColor>(other.m_style)) {
+ auto& a = WTF::get<CMYKAColor>(m_style);
+ auto& b = WTF::get<CMYKAColor>(other.m_style);
+ return a.c == b.c && a.m == b.m && a.y == b.y && a.k == b.k && a.a == b.a;
}
- ASSERT_NOT_REACHED();
return false;
}
bool CanvasStyle::isEquivalentRGBA(float r, float g, float b, float a) const
{
- if (m_type != RGBA)
- return false;
-
- return m_rgba == makeRGBA32FromFloats(r, g, b, a);
+ return WTF::holds_alternative<Color>(m_style) && WTF::get<Color>(m_style) == Color { r, g, b, a };
}
bool CanvasStyle::isEquivalentCMYKA(float c, float m, float y, float k, float a) const
{
- if (m_type != CMYKA)
+ if (!WTF::holds_alternative<CMYKAColor>(m_style))
return false;
- return c == m_cmyka->c
- && m == m_cmyka->m
- && y == m_cmyka->y
- && k == m_cmyka->k
- && a == m_cmyka->a;
-}
-
-CanvasStyle::CanvasStyle(const CanvasStyle& other)
-{
- memcpy(this, &other, sizeof(CanvasStyle));
- if (m_type == Gradient)
- m_gradient->ref();
- else if (m_type == ImagePattern)
- m_pattern->ref();
- else if (m_type == CMYKA)
- m_cmyka = new CMYKAValues(other.m_cmyka->rgba, other.m_cmyka->c, other.m_cmyka->m, other.m_cmyka->y, other.m_cmyka->k, other.m_cmyka->a);
-}
-
-CanvasStyle& CanvasStyle::operator=(const CanvasStyle& other)
-{
- if (this != &other) {
- this->~CanvasStyle();
- new (this) CanvasStyle(other);
- }
- return *this;
+ auto& channels = WTF::get<CMYKAColor>(m_style);
+ return c == channels.c && m == channels.m && y == channels.y && k == channels.k && a == channels.a;
}
-void CanvasStyle::applyStrokeColor(GraphicsContext* context) const
+void CanvasStyle::applyStrokeColor(GraphicsContext& context) const
{
- if (!context)
- return;
- switch (m_type) {
- case RGBA:
- context->setStrokeColor(m_rgba, ColorSpaceDeviceRGB);
- break;
- case CMYKA: {
- // FIXME: Do this through platform-independent GraphicsContext API.
- // We'll need a fancier Color abstraction to support CMYKA correctly
+ WTF::switchOn(m_style,
+ [&context] (const Color& color) {
+ context.setStrokeColor(color);
+ },
+ [&context] (const CMYKAColor& color) {
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CMYKA correctly
#if USE(CG)
- CGContextSetCMYKStrokeColor(context->platformContext(), m_cmyka->c, m_cmyka->m, m_cmyka->y, m_cmyka->k, m_cmyka->a);
+ CGContextSetCMYKStrokeColor(context.platformContext(), color.c, color.m, color.y, color.k, color.a);
#else
- context->setStrokeColor(m_cmyka->rgba, ColorSpaceDeviceRGB);
+ context.setStrokeColor(color.color);
#endif
- break;
- }
- case Gradient:
- context->setStrokeGradient(canvasGradient()->gradient());
- break;
- case ImagePattern:
- context->setStrokePattern(canvasPattern()->pattern());
- break;
- case CurrentColor:
- case CurrentColorWithOverrideAlpha:
- case Invalid:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-void CanvasStyle::applyFillColor(GraphicsContext* context) const
-{
- if (!context)
- return;
- switch (m_type) {
- case RGBA:
- context->setFillColor(m_rgba, ColorSpaceDeviceRGB);
- break;
- case CMYKA: {
- // FIXME: Do this through platform-independent GraphicsContext API.
- // We'll need a fancier Color abstraction to support CMYKA correctly
+ },
+ [&context] (const RefPtr<CanvasGradient>& gradient) {
+ context.setStrokeGradient(gradient->gradient());
+ },
+ [&context] (const RefPtr<CanvasPattern>& pattern) {
+ context.setStrokePattern(pattern->pattern());
+ },
+ [] (const CurrentColor&) {
+ ASSERT_NOT_REACHED();
+ },
+ [] (const Invalid&) {
+ ASSERT_NOT_REACHED();
+ }
+ );
+}
+
+void CanvasStyle::applyFillColor(GraphicsContext& context) const
+{
+ WTF::switchOn(m_style,
+ [&context] (const Color& color) {
+ context.setFillColor(color);
+ },
+ [&context] (const CMYKAColor& color) {
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CMYKA correctly
#if USE(CG)
- CGContextSetCMYKFillColor(context->platformContext(), m_cmyka->c, m_cmyka->m, m_cmyka->y, m_cmyka->k, m_cmyka->a);
+ CGContextSetCMYKFillColor(context.platformContext(), color.c, color.m, color.y, color.k, color.a);
#else
- context->setFillColor(m_cmyka->rgba, ColorSpaceDeviceRGB);
+ context.setFillColor(color.color);
#endif
- break;
- }
- case Gradient:
- context->setFillGradient(canvasGradient()->gradient());
- break;
- case ImagePattern:
- context->setFillPattern(canvasPattern()->pattern());
- break;
- case CurrentColor:
- case CurrentColorWithOverrideAlpha:
- case Invalid:
- ASSERT_NOT_REACHED();
- break;
- }
+ },
+ [&context] (const RefPtr<CanvasGradient>& gradient) {
+ context.setFillGradient(gradient->gradient());
+ },
+ [&context] (const RefPtr<CanvasPattern>& pattern) {
+ context.setFillPattern(pattern->pattern());
+ },
+ [] (const CurrentColor&) {
+ ASSERT_NOT_REACHED();
+ },
+ [] (const Invalid&) {
+ ASSERT_NOT_REACHED();
+ }
+ );
}
}
diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h
index a5d3e5166..d78030ac9 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.h
+++ b/Source/WebCore/html/canvas/CanvasStyle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,136 +24,102 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CanvasStyle_h
-#define CanvasStyle_h
+#pragma once
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
#include "Color.h"
-#include <wtf/Assertions.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/Variant.h>
namespace WebCore {
- class CanvasGradient;
- class CanvasPattern;
- class Document;
- class GraphicsContext;
- class HTMLCanvasElement;
-
- class CanvasStyle {
- public:
- CanvasStyle();
- explicit CanvasStyle(RGBA32);
- CanvasStyle(float grayLevel, float alpha);
- CanvasStyle(float r, float g, float b, float alpha);
- CanvasStyle(float c, float m, float y, float k, float alpha);
- explicit CanvasStyle(PassRefPtr<CanvasGradient>);
- explicit CanvasStyle(PassRefPtr<CanvasPattern>);
- ~CanvasStyle();
-
- static CanvasStyle createFromString(const String& color, Document* = 0);
- static CanvasStyle createFromStringWithOverrideAlpha(const String& color, float alpha);
-
- bool isValid() const { return m_type != Invalid; }
- bool isCurrentColor() const { return m_type == CurrentColor || m_type == CurrentColorWithOverrideAlpha; }
- bool hasOverrideAlpha() const { return m_type == CurrentColorWithOverrideAlpha; }
- float overrideAlpha() const { ASSERT(m_type == CurrentColorWithOverrideAlpha); return m_overrideAlpha; }
-
- String color() const;
- CanvasGradient* canvasGradient() const;
- CanvasPattern* canvasPattern() const;
-
- void applyFillColor(GraphicsContext*) const;
- void applyStrokeColor(GraphicsContext*) const;
-
- bool isEquivalentColor(const CanvasStyle&) const;
- bool isEquivalentRGBA(float r, float g, float b, float a) const;
- bool isEquivalentCMYKA(float c, float m, float y, float k, float a) const;
-
- CanvasStyle(const CanvasStyle&);
- CanvasStyle& operator=(const CanvasStyle&);
- CanvasStyle(CanvasStyle&&);
- CanvasStyle& operator=(CanvasStyle&&);
-
- private:
- enum Type { RGBA, CMYKA, Gradient, ImagePattern, CurrentColor, CurrentColorWithOverrideAlpha, Invalid };
- struct CMYKAValues {
- WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(CMYKAValues);
- public:
- CMYKAValues() : rgba(0), c(0), m(0), y(0), k(0), a(0) { }
- CMYKAValues(RGBA32 rgba, float cyan, float magenta, float yellow, float black, float alpha) : rgba(rgba), c(cyan), m(magenta), y(yellow), k(black), a(alpha) { }
- RGBA32 rgba;
- float c;
- float m;
- float y;
- float k;
- float a;
- };
-
- enum ConstructCurrentColorTag { ConstructCurrentColor };
- CanvasStyle(ConstructCurrentColorTag) : m_type(CurrentColor) { }
- CanvasStyle(Type type, float overrideAlpha)
- : m_overrideAlpha(overrideAlpha)
- , m_type(type)
+class Document;
+class GraphicsContext;
+class HTMLCanvasElement;
+
+class CanvasStyle {
+public:
+ CanvasStyle();
+ CanvasStyle(Color);
+ CanvasStyle(float grayLevel, float alpha);
+ CanvasStyle(float r, float g, float b, float alpha);
+ CanvasStyle(float c, float m, float y, float k, float alpha);
+ CanvasStyle(CanvasGradient&);
+ CanvasStyle(CanvasPattern&);
+
+ static CanvasStyle createFromString(const String& color, Document* = nullptr);
+ static CanvasStyle createFromStringWithOverrideAlpha(const String& color, float alpha);
+
+ bool isValid() const { return !WTF::holds_alternative<Invalid>(m_style); }
+ bool isCurrentColor() const { return WTF::holds_alternative<CurrentColor>(m_style); }
+ bool hasOverrideAlpha() const { return isCurrentColor() && WTF::get<CurrentColor>(m_style).overrideAlpha; }
+ float overrideAlpha() const { return WTF::get<CurrentColor>(m_style).overrideAlpha.value(); }
+
+ String color() const;
+ CanvasGradient* canvasGradient() const;
+ CanvasPattern* canvasPattern() const;
+
+ void applyFillColor(GraphicsContext&) const;
+ void applyStrokeColor(GraphicsContext&) const;
+
+ bool isEquivalentColor(const CanvasStyle&) const;
+ bool isEquivalentRGBA(float red, float green, float blue, float alpha) const;
+ bool isEquivalentCMYKA(float cyan, float magenta, float yellow, float black, float alpha) const;
+
+private:
+ struct Invalid { };
+
+ struct CMYKAColor {
+ CMYKAColor() = default;
+
+ CMYKAColor(Color color, float cyan, float magenta, float yellow, float black, float alpha)
+ : color(color), c(cyan), m(magenta), y(yellow), k(black), a(alpha)
{
}
- union {
- RGBA32 m_rgba;
- float m_overrideAlpha;
- CanvasGradient* m_gradient;
- CanvasPattern* m_pattern;
- CMYKAValues* m_cmyka;
- };
- Type m_type;
+ Color color;
+ float c { 0 };
+ float m { 0 };
+ float y { 0 };
+ float k { 0 };
+ float a { 0 };
};
- RGBA32 currentColor(HTMLCanvasElement*);
- bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement*);
-
- inline CanvasStyle::CanvasStyle()
- : m_type(Invalid)
- {
- }
-
- inline CanvasGradient* CanvasStyle::canvasGradient() const
- {
- if (m_type == Gradient)
- return m_gradient;
- return 0;
- }
-
- inline CanvasPattern* CanvasStyle::canvasPattern() const
- {
- if (m_type == ImagePattern)
- return m_pattern;
- return 0;
- }
-
- inline String CanvasStyle::color() const
- {
- ASSERT(m_type == RGBA || m_type == CMYKA);
- if (m_type == RGBA)
- return Color(m_rgba).serialized();
- return Color(m_cmyka->rgba).serialized();
- }
-
- inline CanvasStyle::CanvasStyle(CanvasStyle&& other)
- {
- memcpy(this, &other, sizeof(CanvasStyle));
- other.m_type = Invalid;
- }
-
- inline CanvasStyle& CanvasStyle::operator=(CanvasStyle&& other)
- {
- if (this != &other) {
- memcpy(this, &other, sizeof(CanvasStyle));
- other.m_type = Invalid;
- }
- return *this;
- }
+ struct CurrentColor {
+ std::optional<float> overrideAlpha;
+ };
-} // namespace WebCore
+ CanvasStyle(CurrentColor);
+
+ Variant<Invalid, Color, CMYKAColor, RefPtr<CanvasGradient>, RefPtr<CanvasPattern>, CurrentColor> m_style;
+};
+
+Color currentColor(HTMLCanvasElement*);
+Color parseColorOrCurrentColor(const String& colorString, HTMLCanvasElement*);
+
+inline CanvasStyle::CanvasStyle()
+ : m_style(Invalid { })
+{
+}
-#endif
+inline CanvasGradient* CanvasStyle::canvasGradient() const
+{
+ if (!WTF::holds_alternative<RefPtr<CanvasGradient>>(m_style))
+ return nullptr;
+ return WTF::get<RefPtr<CanvasGradient>>(m_style).get();
+}
+
+inline CanvasPattern* CanvasStyle::canvasPattern() const
+{
+ if (!WTF::holds_alternative<RefPtr<CanvasPattern>>(m_style))
+ return nullptr;
+ return WTF::get<RefPtr<CanvasPattern>>(m_style).get();
+}
+
+inline String CanvasStyle::color() const
+{
+ auto& color = WTF::holds_alternative<Color>(m_style) ? WTF::get<Color>(m_style) : WTF::get<CMYKAColor>(m_style).color;
+ return color.serialized();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/DOMPath.cpp b/Source/WebCore/html/canvas/DOMPath.cpp
new file mode 100644
index 000000000..d51b78ada
--- /dev/null
+++ b/Source/WebCore/html/canvas/DOMPath.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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.
+ */
+
+#include "config.h"
+#include "DOMPath.h"
+
+namespace WebCore {
+
+DOMPath::~DOMPath()
+{
+}
+
+}
diff --git a/Source/WebCore/html/canvas/DOMPath.h b/Source/WebCore/html/canvas/DOMPath.h
index 6358e4602..0bbff134f 100644
--- a/Source/WebCore/html/canvas/DOMPath.h
+++ b/Source/WebCore/html/canvas/DOMPath.h
@@ -25,46 +25,49 @@
* SUCH DAMAGE.
*/
-#ifndef DOMPath_h
-#define DOMPath_h
+#pragma once
-#if ENABLE(CANVAS_PATH)
-
-#include "CanvasPathMethods.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-
-#if ENABLE(SVG)
+#include "CanvasPath.h"
+#include "SVGMatrix.h"
#include "SVGPathUtilities.h"
-#endif
+#include <wtf/RefCounted.h>
namespace WebCore {
-class DOMPath : public RefCounted<DOMPath>, public CanvasPathMethods {
+class WEBCORE_EXPORT DOMPath final : public RefCounted<DOMPath>, public CanvasPath {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<DOMPath> create() { return adoptRef(new DOMPath); }
- static PassRefPtr<DOMPath> create(const Path& path) { return adoptRef(new DOMPath(path)); }
- static PassRefPtr<DOMPath> create(const DOMPath* path) { return create(path->path()); }
+ virtual ~DOMPath();
-#if ENABLE(SVG)
- static PassRefPtr<DOMPath> create(const String& pathData)
+ static Ref<DOMPath> create() { return adoptRef(*new DOMPath); }
+ static Ref<DOMPath> create(const Path& path) { return adoptRef(*new DOMPath(path)); }
+ static Ref<DOMPath> create(const DOMPath& path) { return create(path.path()); }
+
+ static Ref<DOMPath> create(const String& pathData)
{
Path path;
buildPathFromString(pathData, path);
return create(path);
}
+
+#if ENABLE(CANVAS_PATH)
+ void addPath(const DOMPath* path) { addPath(path, AffineTransform()); }
+ void addPath(const DOMPath* path, SVGMatrix& matrix) { addPath(path, matrix.propertyReference()); }
+ void addPath(const DOMPath* path, const AffineTransform& transform)
+ {
+ if (!path || !transform.isInvertible())
+ return;
+ m_path.addPath(path->path(), transform);
+ }
#endif
const Path& path() const { return m_path; }
private:
DOMPath() { }
- DOMPath(const Path& path) : CanvasPathMethods(path) { }
+ DOMPath(const Path& path)
+ : CanvasPath(path)
+ { }
};
-}
-
-#endif
-
-#endif
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/DOMPath.idl b/Source/WebCore/html/canvas/DOMPath.idl
index 0c262c681..40bd2ba5c 100644
--- a/Source/WebCore/html/canvas/DOMPath.idl
+++ b/Source/WebCore/html/canvas/DOMPath.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
* Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,42 +29,14 @@
[
Constructor,
Constructor(DOMPath path),
-#if defined(ENABLE_SVG) && ENABLE_SVG
Constructor(DOMString text),
-#endif
- Conditional=CANVAS_PATH,
- InterfaceName=Path,
+ ExportMacro=WEBCORE_EXPORT,
+ InterfaceName=Path2D,
] interface DOMPath {
-
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- void closePath();
- void moveTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void lineTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void quadraticCurveTo([Default=Undefined] optional float cpx,
- [Default=Undefined] optional float cpy,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void bezierCurveTo([Default=Undefined] optional float cp1x,
- [Default=Undefined] optional float cp1y,
- [Default=Undefined] optional float cp2x,
- [Default=Undefined] optional float cp2y,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- [RaisesException] void arcTo([Default=Undefined] optional float x1,
- [Default=Undefined] optional float y1,
- [Default=Undefined] optional float x2,
- [Default=Undefined] optional float y2,
- [Default=Undefined] optional float radius);
- void rect([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float width,
- [Default=Undefined] optional float height);
- [RaisesException] void arc([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float radius,
- [Default=Undefined] optional float startAngle,
- [Default=Undefined] optional float endAngle,
- [Default=Undefined] optional boolean anticlockwise);
+ // FIXME: This should be:
+ // [Conditional=CANVAS_PATH] void addPath(DOMPath path, optional SVGMatrix transform);
+ [Conditional=CANVAS_PATH] void addPath(DOMPath? path);
+ [Conditional=CANVAS_PATH] void addPath(DOMPath? path, SVGMatrix transform);
};
+
+DOMPath implements CanvasPath;
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.cpp b/Source/WebCore/html/canvas/EXTBlendMinMax.cpp
new file mode 100644
index 000000000..762a5d9f6
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTBlendMinMax.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "EXTBlendMinMax.h"
+
+namespace WebCore {
+
+EXTBlendMinMax::EXTBlendMinMax(WebGLRenderingContextBase& context)
+ : WebGLExtension(context)
+{
+}
+
+EXTBlendMinMax::~EXTBlendMinMax()
+{
+}
+
+WebGLExtension::ExtensionName EXTBlendMinMax::getName() const
+{
+ return EXTBlendMinMaxName;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.h b/Source/WebCore/html/canvas/EXTBlendMinMax.h
new file mode 100644
index 000000000..59596844e
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTBlendMinMax.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#pragma once
+
+#include "WebGLExtension.h"
+
+namespace WebCore {
+
+class EXTBlendMinMax final : public WebGLExtension {
+public:
+ explicit EXTBlendMinMax(WebGLRenderingContextBase&);
+ virtual ~EXTBlendMinMax();
+
+ ExtensionName getName() const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.idl b/Source/WebCore/html/canvas/EXTBlendMinMax.idl
new file mode 100644
index 000000000..c1a8c19a0
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTBlendMinMax.idl
@@ -0,0 +1,33 @@
+/*
+* Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+*/
+
+[
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext,
+ NoInterfaceObject,
+] interface EXTBlendMinMax {
+ const unsigned long MIN_EXT = 0x8007;
+ const unsigned long MAX_EXT = 0x8008;
+};
diff --git a/Source/WebCore/html/canvas/EXTDrawBuffers.idl b/Source/WebCore/html/canvas/EXTDrawBuffers.idl
deleted file mode 100644
index 864e5504e..000000000
--- a/Source/WebCore/html/canvas/EXTDrawBuffers.idl
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
- */
-
-typedef unsigned long GLenum;
-
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants,
-] interface EXTDrawBuffers {
- const GLenum COLOR_ATTACHMENT0_EXT = 0x8CE0;
- const GLenum COLOR_ATTACHMENT1_EXT = 0x8CE1;
- const GLenum COLOR_ATTACHMENT2_EXT = 0x8CE2;
- const GLenum COLOR_ATTACHMENT3_EXT = 0x8CE3;
- const GLenum COLOR_ATTACHMENT4_EXT = 0x8CE4;
- const GLenum COLOR_ATTACHMENT5_EXT = 0x8CE5;
- const GLenum COLOR_ATTACHMENT6_EXT = 0x8CE6;
- const GLenum COLOR_ATTACHMENT7_EXT = 0x8CE7;
- const GLenum COLOR_ATTACHMENT8_EXT = 0x8CE8;
- const GLenum COLOR_ATTACHMENT9_EXT = 0x8CE9;
- const GLenum COLOR_ATTACHMENT10_EXT = 0x8CEA;
- const GLenum COLOR_ATTACHMENT11_EXT = 0x8CEB;
- const GLenum COLOR_ATTACHMENT12_EXT = 0x8CEC;
- const GLenum COLOR_ATTACHMENT13_EXT = 0x8CED;
- const GLenum COLOR_ATTACHMENT14_EXT = 0x8CEE;
- const GLenum COLOR_ATTACHMENT15_EXT = 0x8CEF;
-
- const GLenum DRAW_BUFFER0_EXT = 0x8825;
- const GLenum DRAW_BUFFER1_EXT = 0x8826;
- const GLenum DRAW_BUFFER2_EXT = 0x8827;
- const GLenum DRAW_BUFFER3_EXT = 0x8828;
- const GLenum DRAW_BUFFER4_EXT = 0x8829;
- const GLenum DRAW_BUFFER5_EXT = 0x882A;
- const GLenum DRAW_BUFFER6_EXT = 0x882B;
- const GLenum DRAW_BUFFER7_EXT = 0x882C;
- const GLenum DRAW_BUFFER8_EXT = 0x882D;
- const GLenum DRAW_BUFFER9_EXT = 0x882E;
- const GLenum DRAW_BUFFER10_EXT = 0x882F;
- const GLenum DRAW_BUFFER11_EXT = 0x8830;
- const GLenum DRAW_BUFFER12_EXT = 0x8831;
- const GLenum DRAW_BUFFER13_EXT = 0x8832;
- const GLenum DRAW_BUFFER14_EXT = 0x8833;
- const GLenum DRAW_BUFFER15_EXT = 0x8834;
-
- const GLenum MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF;
- const GLenum MAX_DRAW_BUFFERS_EXT = 0x8824;
-
- void drawBuffersEXT(sequence<GLenum> buffers);
-};
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.cpp b/Source/WebCore/html/canvas/EXTFragDepth.cpp
new file mode 100644
index 000000000..626309c83
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTFragDepth.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "EXTFragDepth.h"
+
+namespace WebCore {
+
+EXTFragDepth::EXTFragDepth(WebGLRenderingContextBase& context)
+ : WebGLExtension(context)
+{
+}
+
+EXTFragDepth::~EXTFragDepth()
+{
+}
+
+WebGLExtension::ExtensionName EXTFragDepth::getName() const
+{
+ return EXTFragDepthName;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.h b/Source/WebCore/html/canvas/EXTFragDepth.h
new file mode 100644
index 000000000..5e8a4f9c2
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTFragDepth.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#pragma once
+
+#include "WebGLExtension.h"
+
+namespace WebCore {
+
+class EXTFragDepth final : public WebGLExtension {
+public:
+ explicit EXTFragDepth(WebGLRenderingContextBase&);
+ virtual ~EXTFragDepth();
+
+ ExtensionName getName() const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.idl b/Source/WebCore/html/canvas/EXTFragDepth.idl
new file mode 100644
index 000000000..5edc4aa30
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTFragDepth.idl
@@ -0,0 +1,31 @@
+/*
+* Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+*/
+
+[
+ NoInterfaceObject,
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext
+] interface EXTFragDepth {
+};
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp b/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp
new file mode 100644
index 000000000..46e406a43
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "EXTShaderTextureLOD.h"
+
+namespace WebCore {
+
+EXTShaderTextureLOD::EXTShaderTextureLOD(WebGLRenderingContextBase& context)
+ : WebGLExtension(context)
+{
+}
+
+EXTShaderTextureLOD::~EXTShaderTextureLOD()
+{
+}
+
+WebGLExtension::ExtensionName EXTShaderTextureLOD::getName() const
+{
+ return EXTShaderTextureLODName;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.h b/Source/WebCore/html/canvas/EXTShaderTextureLOD.h
new file mode 100644
index 000000000..47c192f20
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTShaderTextureLOD.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#pragma once
+
+#include "WebGLExtension.h"
+
+namespace WebCore {
+
+class EXTShaderTextureLOD final : public WebGLExtension {
+public:
+ explicit EXTShaderTextureLOD(WebGLRenderingContextBase&);
+ virtual ~EXTShaderTextureLOD();
+
+ ExtensionName getName() const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.idl b/Source/WebCore/html/canvas/EXTShaderTextureLOD.idl
new file mode 100644
index 000000000..3baa298a3
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTShaderTextureLOD.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+[
+ NoInterfaceObject,
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext
+] interface EXTShaderTextureLOD {
+};
diff --git a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
index 8ae249456..0bd3dfa2b 100644
--- a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
+++ b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContext* context)
+EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -45,11 +45,6 @@ WebGLExtension::ExtensionName EXTTextureFilterAnisotropic::getName() const
return EXTTextureFilterAnisotropicName;
}
-OwnPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new EXTTextureFilterAnisotropic(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
index 5e76ebb01..4197d5fbb 100644
--- a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
+++ b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
@@ -23,25 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef EXTTextureFilterAnisotropic_h
-#define EXTTextureFilterAnisotropic_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class EXTTextureFilterAnisotropic : public WebGLExtension {
+class EXTTextureFilterAnisotropic final : public WebGLExtension {
public:
- static OwnPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContext*);
-
+ explicit EXTTextureFilterAnisotropic(WebGLRenderingContextBase&);
virtual ~EXTTextureFilterAnisotropic();
- virtual ExtensionName getName() const override;
-private:
- EXTTextureFilterAnisotropic(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // EXTTextureFilterAnisotropic_h
diff --git a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.idl b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.idl
index 45ac89515..9002231c5 100644
--- a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.idl
+++ b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.idl
@@ -24,11 +24,10 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface EXTTextureFilterAnisotropic {
- const unsigned int TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
- const unsigned int MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
+ const unsigned long TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
+ const unsigned long MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
};
diff --git a/Source/WebCore/html/canvas/EXTsRGB.cpp b/Source/WebCore/html/canvas/EXTsRGB.cpp
new file mode 100644
index 000000000..e4edf51c7
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTsRGB.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "EXTsRGB.h"
+
+namespace WebCore {
+
+EXTsRGB::EXTsRGB(WebGLRenderingContextBase& context)
+ : WebGLExtension(context)
+{
+}
+
+EXTsRGB::~EXTsRGB()
+{
+}
+
+WebGLExtension::ExtensionName EXTsRGB::getName() const
+{
+ return EXTsRGBName;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTsRGB.h b/Source/WebCore/html/canvas/EXTsRGB.h
new file mode 100644
index 000000000..4a69cba75
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTsRGB.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#pragma once
+
+#include "WebGLExtension.h"
+
+namespace WebCore {
+
+class EXTsRGB final : public WebGLExtension {
+public:
+ explicit EXTsRGB(WebGLRenderingContextBase&);
+ virtual ~EXTsRGB();
+
+ ExtensionName getName() const override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/EXTsRGB.idl b/Source/WebCore/html/canvas/EXTsRGB.idl
new file mode 100644
index 000000000..cb0da3e9e
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTsRGB.idl
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+*/
+
+[
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext,
+ NoInterfaceObject,
+] interface EXTsRGB {
+ const unsigned long SRGB_EXT = 0x8C40;
+ const unsigned long SRGB_ALPHA_EXT = 0x8C42;
+ const unsigned long SRGB8_ALPHA8_EXT = 0x8C43;
+ const unsigned long FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210;
+};
diff --git a/Source/WebCore/html/canvas/OESElementIndexUint.cpp b/Source/WebCore/html/canvas/OESElementIndexUint.cpp
index 66024153a..101c5f10d 100644
--- a/Source/WebCore/html/canvas/OESElementIndexUint.cpp
+++ b/Source/WebCore/html/canvas/OESElementIndexUint.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESElementIndexUint::OESElementIndexUint(WebGLRenderingContext* context)
+OESElementIndexUint::OESElementIndexUint(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -45,11 +45,6 @@ WebGLExtension::ExtensionName OESElementIndexUint::getName() const
return OESElementIndexUintName;
}
-OwnPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESElementIndexUint(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESElementIndexUint.h b/Source/WebCore/html/canvas/OESElementIndexUint.h
index 83ce56a8d..460321d44 100644
--- a/Source/WebCore/html/canvas/OESElementIndexUint.h
+++ b/Source/WebCore/html/canvas/OESElementIndexUint.h
@@ -23,25 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESElementIndexUint_h
-#define OESElementIndexUint_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESElementIndexUint : public WebGLExtension {
+class OESElementIndexUint final : public WebGLExtension {
public:
- static OwnPtr<OESElementIndexUint> create(WebGLRenderingContext*);
-
+ explicit OESElementIndexUint(WebGLRenderingContextBase&);
virtual ~OESElementIndexUint();
- virtual ExtensionName getName() const override;
-private:
- OESElementIndexUint(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESElementIndexUint_h
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
index 0f2c876c7..dcbb819e3 100644
--- a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -45,11 +45,6 @@ WebGLExtension::ExtensionName OESStandardDerivatives::getName() const
return OESStandardDerivativesName;
}
-OwnPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESStandardDerivatives(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.h b/Source/WebCore/html/canvas/OESStandardDerivatives.h
index a21dfd89c..ccfc88406 100644
--- a/Source/WebCore/html/canvas/OESStandardDerivatives.h
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.h
@@ -23,25 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESStandardDerivatives_h
-#define OESStandardDerivatives_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESStandardDerivatives : public WebGLExtension {
+class OESStandardDerivatives final : public WebGLExtension {
public:
- static OwnPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
-
+ explicit OESStandardDerivatives(WebGLRenderingContextBase&);
virtual ~OESStandardDerivatives();
- virtual ExtensionName getName() const override;
-private:
- OESStandardDerivatives(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESStandardDerivatives_h
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.idl b/Source/WebCore/html/canvas/OESStandardDerivatives.idl
index 850260bfe..d9d99838b 100644
--- a/Source/WebCore/html/canvas/OESStandardDerivatives.idl
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.idl
@@ -24,10 +24,10 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface OESStandardDerivatives {
- const unsigned int FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+ const unsigned long FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
};
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.cpp b/Source/WebCore/html/canvas/OESTextureFloat.cpp
index 223136c42..60d2f7b50 100644
--- a/Source/WebCore/html/canvas/OESTextureFloat.cpp
+++ b/Source/WebCore/html/canvas/OESTextureFloat.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
+OESTextureFloat::OESTextureFloat(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -45,11 +45,6 @@ WebGLExtension::ExtensionName OESTextureFloat::getName() const
return OESTextureFloatName;
}
-OwnPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESTextureFloat(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.h b/Source/WebCore/html/canvas/OESTextureFloat.h
index 6c67ea11b..e7c0715dd 100644
--- a/Source/WebCore/html/canvas/OESTextureFloat.h
+++ b/Source/WebCore/html/canvas/OESTextureFloat.h
@@ -23,25 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESTextureFloat_h
-#define OESTextureFloat_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureFloat : public WebGLExtension {
+class OESTextureFloat final : public WebGLExtension {
public:
- static OwnPtr<OESTextureFloat> create(WebGLRenderingContext*);
-
+ OESTextureFloat(WebGLRenderingContextBase&);
virtual ~OESTextureFloat();
- virtual ExtensionName getName() const override;
-private:
- OESTextureFloat(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESTextureFloat_h
diff --git a/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp b/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
index d93491608..fce917908 100644
--- a/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
+++ b/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContext* context)
+OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -44,11 +44,6 @@ WebGLExtension::ExtensionName OESTextureFloatLinear::getName() const
return OESTextureFloatLinearName;
}
-OwnPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESTextureFloatLinear(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureFloatLinear.h b/Source/WebCore/html/canvas/OESTextureFloatLinear.h
index 3e9fe87cc..93dd13460 100644
--- a/Source/WebCore/html/canvas/OESTextureFloatLinear.h
+++ b/Source/WebCore/html/canvas/OESTextureFloatLinear.h
@@ -23,25 +23,18 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESTextureFloatLinear_h
-#define OESTextureFloatLinear_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureFloatLinear : public WebGLExtension {
+class OESTextureFloatLinear final : public WebGLExtension {
public:
- static OwnPtr<OESTextureFloatLinear> create(WebGLRenderingContext*);
-
+ explicit OESTextureFloatLinear(WebGLRenderingContextBase&);
virtual ~OESTextureFloatLinear();
- virtual ExtensionName getName() const override;
-private:
- OESTextureFloatLinear(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESTextureFloat_h
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp b/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
index fd2e25bd2..f1f7496dd 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContext* context)
+OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -45,11 +45,6 @@ WebGLExtension::ExtensionName OESTextureHalfFloat::getName() const
return OESTextureHalfFloatName;
}
-OwnPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESTextureHalfFloat(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloat.h b/Source/WebCore/html/canvas/OESTextureHalfFloat.h
index c8ab9feb1..b3f676dd7 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloat.h
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloat.h
@@ -23,25 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESTextureHalfFloat_h
-#define OESTextureHalfFloat_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureHalfFloat : public WebGLExtension {
+class OESTextureHalfFloat final : public WebGLExtension {
public:
- static OwnPtr<OESTextureHalfFloat> create(WebGLRenderingContext*);
-
+ OESTextureHalfFloat(WebGLRenderingContextBase&);
virtual ~OESTextureHalfFloat();
- virtual ExtensionName getName() const override;
-private:
- OESTextureHalfFloat(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESTextureHalfFloat_h
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
index e2ec8b250..359e30016 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContext* context)
+OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -44,11 +44,6 @@ WebGLExtension::ExtensionName OESTextureHalfFloatLinear::getName() const
return OESTextureHalfFloatLinearName;
}
-OwnPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new OESTextureHalfFloatLinear(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
index 073b48a9f..4810a112b 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
@@ -23,25 +23,18 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESTextureHalfFloatLinear_h
-#define OESTextureHalfFloatLinear_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureHalfFloatLinear : public WebGLExtension {
+class OESTextureHalfFloatLinear final : public WebGLExtension {
public:
- static OwnPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContext*);
-
+ OESTextureHalfFloatLinear(WebGLRenderingContextBase&);
virtual ~OESTextureHalfFloatLinear();
- virtual ExtensionName getName() const override;
-private:
- OESTextureHalfFloatLinear(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // OESTextureHalfFloatLinear_h
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
index 36ab832d9..111bc3be6 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,90 +24,72 @@
*/
#include "config.h"
+#include "OESVertexArrayObject.h"
#if ENABLE(WEBGL)
-#include "OESVertexArrayObject.h"
-
#include "Extensions3D.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
-OESVertexArrayObject::~OESVertexArrayObject()
-{
-}
-
WebGLExtension::ExtensionName OESVertexArrayObject::getName() const
{
return OESVertexArrayObjectName;
}
-OwnPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+RefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
{
- return adoptPtr(new OESVertexArrayObject(context));
-}
+ if (m_context.isContextLost())
+ return nullptr;
-PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
-{
- if (m_context->isContextLost())
- return 0;
-
- RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
- m_context->addContextObject(o.get());
- return o.release();
+ auto object = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::Type::User);
+ m_context.addContextObject(object.get());
+ return WTFMove(object);
}
void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
{
- if (!arrayObject || m_context->isContextLost())
+ if (!arrayObject || m_context.isContextLost())
return;
-
- if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
- m_context->setBoundVertexArrayObject(0);
- arrayObject->deleteObject(m_context->graphicsContext3D());
+ if (!arrayObject->isDefaultObject() && arrayObject == static_cast<WebGLRenderingContext&>(m_context).m_boundVertexArrayObject)
+ static_cast<WebGLRenderingContext&>(m_context).setBoundVertexArrayObject(nullptr);
+
+ arrayObject->deleteObject(m_context.graphicsContext3D());
}
GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
{
- if (!arrayObject || m_context->isContextLost())
- return 0;
-
- if (!arrayObject->hasEverBeenBound())
- return 0;
-
- Extensions3D* extensions = m_context->graphicsContext3D()->getExtensions();
- return extensions->isVertexArrayOES(arrayObject->object());
+ return arrayObject && !m_context.isContextLost() && arrayObject->hasEverBeenBound()
+ && m_context.graphicsContext3D()->getExtensions().isVertexArrayOES(arrayObject->object());
}
-void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject, ExceptionCode& ec)
+void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
{
- UNUSED_PARAM(ec);
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return;
-
- if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) {
- m_context->graphicsContext3D()->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+
+ if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(nullptr, context()))) {
+ m_context.graphicsContext3D()->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
-
- Extensions3D* extensions = m_context->graphicsContext3D()->getExtensions();
+
+ auto& extensions = m_context.graphicsContext3D()->getExtensions();
+ auto& context = downcast<WebGLRenderingContext>(m_context);
if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
- extensions->bindVertexArrayOES(arrayObject->object());
-
+ extensions.bindVertexArrayOES(arrayObject->object());
arrayObject->setHasEverBeenBound();
- m_context->setBoundVertexArrayObject(arrayObject);
+ context.setBoundVertexArrayObject(arrayObject);
} else {
- extensions->bindVertexArrayOES(0);
- m_context->setBoundVertexArrayObject(0);
+ extensions.bindVertexArrayOES(0);
+ context.setBoundVertexArrayObject(nullptr);
}
-
- m_context->cleanupAfterGraphicsCall(false);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.h b/Source/WebCore/html/canvas/OESVertexArrayObject.h
index b9f859929..0654954c1 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.h
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,36 +23,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef OESVertexArrayObject_h
-#define OESVertexArrayObject_h
+#pragma once
#include "GraphicsTypes3D.h"
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLVertexArrayObjectOES;
-typedef int ExceptionCode;
-
-class OESVertexArrayObject : public WebGLExtension {
+class OESVertexArrayObject final : public WebGLExtension {
public:
- static OwnPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
+ explicit OESVertexArrayObject(WebGLRenderingContextBase&);
- virtual ~OESVertexArrayObject();
- virtual ExtensionName getName() const override;
-
- PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
+ RefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
GC3Dboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
- void bindVertexArrayOES(WebGLVertexArrayObjectOES*, ExceptionCode&);
+ void bindVertexArrayOES(WebGLVertexArrayObjectOES*);
private:
- OESVertexArrayObject(WebGLRenderingContext*);
+ ExtensionName getName() const final;
};
} // namespace WebCore
-
-#endif // OESVertexArrayObject_h
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.idl b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
index 53f475d94..62bdd0456 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.idl
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,15 +24,15 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext,
DoNotCheckConstants,
+ GenerateIsReachable=ImplWebGLRenderingContext,
+ NoInterfaceObject,
] interface OESVertexArrayObject {
- const unsigned int VERTEX_ARRAY_BINDING_OES = 0x85B5;
-
- [StrictTypeChecking] WebGLVertexArrayObjectOES createVertexArrayOES();
- [StrictTypeChecking] void deleteVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking] boolean isVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking, RaisesException] void bindVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
+ const unsigned long VERTEX_ARRAY_BINDING_OES = 0x85B5;
+
+ WebGLVertexArrayObjectOES createVertexArrayOES();
+ void deleteVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
+ boolean isVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
+ void bindVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
};
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp
new file mode 100644
index 000000000..92eefac0c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp
@@ -0,0 +1,1830 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#include "config.h"
+#include "WebGL2RenderingContext.h"
+
+#if ENABLE(WEBGL2)
+
+#include "CachedImage.h"
+#include "EXTTextureFilterAnisotropic.h"
+#include "Extensions3D.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageData.h"
+#include "OESTextureFloat.h"
+#include "OESTextureFloatLinear.h"
+#include "OESTextureHalfFloat.h"
+#include "OESTextureHalfFloatLinear.h"
+#include "RenderBox.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLCompressedTextureATC.h"
+#include "WebGLCompressedTexturePVRTC.h"
+#include "WebGLCompressedTextureS3TC.h"
+#include "WebGLDebugRendererInfo.h"
+#include "WebGLDebugShaders.h"
+#include "WebGLDepthTexture.h"
+#include "WebGLLoseContext.h"
+#include "WebGLQuery.h"
+#include "WebGLSampler.h"
+#include "WebGLSync.h"
+#include "WebGLTransformFeedback.h"
+#include "WebGLVertexArrayObject.h"
+#include <JavaScriptCore/GenericTypedArrayViewInlines.h>
+#include <JavaScriptCore/JSGenericTypedArrayViewInlines.h>
+
+namespace WebCore {
+
+WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement& passedCanvas, GraphicsContext3DAttributes attributes)
+ : WebGLRenderingContextBase(passedCanvas, attributes)
+{
+}
+
+WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement& passedCanvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes)
+ : WebGLRenderingContextBase(passedCanvas, WTFMove(context), attributes)
+{
+ initializeShaderExtensions();
+ initializeVertexArrayObjects();
+}
+
+void WebGL2RenderingContext::initializeVertexArrayObjects()
+{
+ m_defaultVertexArrayObject = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::Default);
+ addContextObject(*m_defaultVertexArrayObject);
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+ if (!isGLES2Compliant())
+ initVertexAttrib0();
+}
+
+void WebGL2RenderingContext::initializeShaderExtensions()
+{
+ m_context->getExtensions().ensureEnabled("GL_OES_standard_derivatives");
+ m_context->getExtensions().ensureEnabled("GL_EXT_draw_buffers");
+ m_context->getExtensions().ensureEnabled("GL_EXT_shader_texture_lod");
+ m_context->getExtensions().ensureEnabled("GL_EXT_frag_depth");
+}
+
+inline static std::optional<unsigned> arrayBufferViewElementSize(const ArrayBufferView& data)
+{
+ switch (data.getType()) {
+ case JSC::NotTypedArray:
+ case JSC::TypeDataView:
+ return std::nullopt;
+ case JSC::TypeInt8:
+ case JSC::TypeUint8:
+ case JSC::TypeUint8Clamped:
+ case JSC::TypeInt16:
+ case JSC::TypeUint16:
+ case JSC::TypeInt32:
+ case JSC::TypeUint32:
+ case JSC::TypeFloat32:
+ case JSC::TypeFloat64:
+ return elementSize(data.getType());
+ }
+}
+
+void WebGL2RenderingContext::bufferData(GC3Denum target, const ArrayBufferView& data, GC3Denum usage, GC3Duint srcOffset, GC3Duint length)
+{
+ auto optionalElementSize = arrayBufferViewElementSize(data);
+ if (!optionalElementSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferData", "Invalid type of Array Buffer View");
+ return;
+ }
+ auto elementSize = optionalElementSize.value();
+ Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize);
+
+ Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset);
+ Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize;
+ Checked<GC3Duint, RecordOverflow> checkedlength(length);
+ Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize;
+
+ if (checkedByteSrcOffset.hasOverflowed()
+ || checkedByteLength.hasOverflowed()
+ || checkedByteSrcOffset.unsafeGet() > data.byteLength()
+ || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "srcOffset or length is out of bounds");
+ return;
+ }
+
+ auto slice = Uint8Array::create(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet());
+ if (!slice) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferData", "Could not create intermediate ArrayBufferView");
+ return;
+ }
+ WebGLRenderingContextBase::bufferData(target, BufferDataSource(slice.get()), usage);
+}
+
+void WebGL2RenderingContext::bufferSubData(GC3Denum target, long long offset, const ArrayBufferView& data, GC3Duint srcOffset, GC3Duint length)
+{
+ auto optionalElementSize = arrayBufferViewElementSize(data);
+ if (!optionalElementSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferSubData", "Invalid type of Array Buffer View");
+ return;
+ }
+ auto elementSize = optionalElementSize.value();
+ Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize);
+
+ Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset);
+ Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize;
+ Checked<GC3Duint, RecordOverflow> checkedlength(length);
+ Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize;
+
+ if (checkedByteSrcOffset.hasOverflowed()
+ || checkedByteLength.hasOverflowed()
+ || checkedByteSrcOffset.unsafeGet() > data.byteLength()
+ || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "srcOffset or length is out of bounds");
+ return;
+ }
+
+ auto slice = Uint8Array::create(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet());
+ if (!slice) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferSubData", "Could not create intermediate ArrayBufferView");
+ return;
+ }
+
+ WebGLRenderingContextBase::bufferSubData(target, offset, BufferDataSource(slice.get()));
+}
+
+void WebGL2RenderingContext::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size)
+{
+ if (isContextLostOrPending())
+ return;
+ if ((readTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && writeTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ || (writeTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && readTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyBufferSubData", "Either both targets need to be ELEMENT_ARRAY_BUFFER or neither should be ELEMENT_ARRAY_BUFFER.");
+ return;
+ }
+ if (readOffset < 0 || writeOffset < 0 || size < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "offset < 0");
+ return;
+ }
+ WebGLBuffer* readBuffer = validateBufferDataParameters("copyBufferSubData", readTarget, GraphicsContext3D::STATIC_DRAW);
+ WebGLBuffer* writeBuffer = validateBufferDataParameters("copyBufferSubData", writeTarget, GraphicsContext3D::STATIC_DRAW);
+ if (!readBuffer || !writeBuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "Invalid readTarget or writeTarget");
+ return;
+ }
+
+ Checked<GC3Dintptr, RecordOverflow> checkedReadOffset(readOffset);
+ Checked<GC3Dintptr, RecordOverflow> checkedWriteOffset(writeOffset);
+ Checked<GC3Dsizeiptr, RecordOverflow> checkedSize(size);
+ if (checkedReadOffset.hasOverflowed() || checkedWriteOffset.hasOverflowed() || checkedSize.hasOverflowed()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "Offset or size is too big");
+ return;
+ }
+
+ if (!writeBuffer->associateCopyBufferSubData(*readBuffer, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet())) {
+ this->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "offset out of range");
+ return;
+ }
+
+ m_context->moveErrorsToSyntheticErrorList();
+#if PLATFORM(COCOA)
+ m_context->copyBufferSubData(readTarget, writeTarget, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet());
+#endif
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does.
+ writeBuffer->disassociateBufferData();
+ }
+}
+
+void WebGL2RenderingContext::getBufferSubData(GC3Denum target, long long srcByteOffset, RefPtr<ArrayBufferView>&& dstData, GC3Duint dstOffset, GC3Duint length)
+{
+ if (isContextLostOrPending())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "No WebGLBuffer is bound to target");
+ return;
+ }
+
+ // FIXME: Implement "If target is TRANSFORM_FEEDBACK_BUFFER, and any transform feedback object is currently active, an INVALID_OPERATION error is generated."
+
+ if (!dstData) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Null dstData");
+ return;
+ }
+
+ auto optionalElementSize = arrayBufferViewElementSize(*dstData);
+ if (!optionalElementSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Invalid type of Array Buffer View");
+ return;
+ }
+ auto elementSize = optionalElementSize.value();
+ auto dstDataLength = dstData->byteLength() / elementSize;
+
+ if (dstOffset > dstDataLength) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "dstOffset is larger than the length of the destination buffer.");
+ return;
+ }
+
+ GC3Duint copyLength = length ? length : dstDataLength - dstOffset;
+
+ Checked<GC3Duint, RecordOverflow> checkedDstOffset(dstOffset);
+ Checked<GC3Duint, RecordOverflow> checkedCopyLength(copyLength);
+ auto checkedDestinationEnd = checkedDstOffset + checkedCopyLength;
+ if (checkedDestinationEnd.hasOverflowed()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "dstOffset + copyLength is too high");
+ return;
+ }
+
+ if (checkedDestinationEnd.unsafeGet() > dstDataLength) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "end of written destination is past the end of the buffer");
+ return;
+ }
+
+ if (srcByteOffset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "srcByteOffset is less than 0");
+ return;
+ }
+
+ Checked<GC3Dintptr, RecordOverflow> checkedSrcByteOffset(srcByteOffset);
+ Checked<GC3Dintptr, RecordOverflow> checkedCopyLengthPtr(copyLength);
+ Checked<GC3Dintptr, RecordOverflow> checkedElementSize(elementSize);
+ auto checkedSourceEnd = checkedSrcByteOffset + checkedCopyLengthPtr * checkedElementSize;
+ if (checkedSourceEnd.hasOverflowed() || checkedSourceEnd.unsafeGet() > buffer->byteLength()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Parameters would read outside the bounds of the source buffer");
+ return;
+ }
+
+ m_context->moveErrorsToSyntheticErrorList();
+#if PLATFORM(COCOA)
+ // FIXME: Coalesce multiple getBufferSubData() calls to use a single map() call
+ void* ptr = m_context->mapBufferRange(target, checkedSrcByteOffset.unsafeGet(), static_cast<GC3Dsizeiptr>(checkedCopyLengthPtr.unsafeGet() * checkedElementSize.unsafeGet()), GraphicsContext3D::MAP_READ_BIT);
+ memcpy(static_cast<char*>(dstData->baseAddress()) + dstData->byteOffset() + dstOffset * elementSize, ptr, copyLength * elementSize);
+ bool success = m_context->unmapBuffer(target);
+ ASSERT_UNUSED(success, success);
+#endif
+ m_context->moveErrorsToSyntheticErrorList();
+}
+
+void WebGL2RenderingContext::blitFramebuffer(GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dbitfield, GC3Denum)
+{
+}
+
+void WebGL2RenderingContext::framebufferTextureLayer(GC3Denum, GC3Denum, GC3Duint, GC3Dint, GC3Dint)
+{
+}
+
+WebGLAny WebGL2RenderingContext::getInternalformatParameter(GC3Denum, GC3Denum, GC3Denum)
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::invalidateFramebuffer(GC3Denum, const Vector<GC3Denum>&)
+{
+}
+
+void WebGL2RenderingContext::invalidateSubFramebuffer(GC3Denum, const Vector<GC3Denum>&, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
+{
+}
+
+void WebGL2RenderingContext::readBuffer(GC3Denum)
+{
+}
+
+void WebGL2RenderingContext::renderbufferStorageMultisample(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei)
+{
+}
+
+bool WebGL2RenderingContext::validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName)
+{
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "texture dimensions are larger than the maximum texture size");
+ return false;
+ }
+
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ if (width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ } else if (target != GraphicsContext3D::TEXTURE_2D) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (levels < 0 || levels > m_maxTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "number of levels is out of bounds");
+ return false;
+ }
+
+ switch (internalFormat) {
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA32I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "Unknown internalFormat");
+ return false;
+ }
+
+ return true;
+}
+
+void WebGL2RenderingContext::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+
+ auto* texture = validateTextureBinding("texStorage2D", target, false);
+ if (!texture)
+ return;
+
+ if (!validateTexStorageFuncParameters(target, levels, internalFormat, width, height, "texStorage2D"))
+ return;
+
+ if (!validateNPOTTextureLevel(width, height, levels, "texStorage2D"))
+ return;
+
+ if (texture->immutable()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texStorage2D", "texStorage2D already called on this texture");
+ return;
+ }
+ texture->setImmutable();
+
+ m_context->texStorage2D(target, levels, internalFormat, width, height);
+
+ {
+ GC3Denum format;
+ GC3Denum type;
+ if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(internalFormat, format, type)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texStorage2D", "Texture has unknown internal format");
+ return;
+ }
+
+ GC3Dsizei levelWidth = width;
+ GC3Dsizei levelHeight = height;
+
+ unsigned size;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "texStorage2D", "bad dimensions");
+ return;
+ }
+
+ Vector<char> data(size);
+ memset(data.data(), 0, size);
+
+ for (GC3Dsizei level = 0; level < levels; ++level) {
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ } else
+ m_context->texSubImage2D(target, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ levelWidth = std::max(1, levelWidth / 2);
+ levelHeight = std::max(1, levelHeight / 2);
+ }
+ }
+
+ for (GC3Dsizei level = 0; level < levels; ++level) {
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ } else
+ texture->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ }
+}
+
+void WebGL2RenderingContext::texStorage3D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei)
+{
+}
+
+void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&)
+{
+}
+
+void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&)
+{
+}
+
+void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Denum, GC3Denum, TexImageSource&&)
+{
+}
+
+void WebGL2RenderingContext::copyTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
+{
+}
+
+void WebGL2RenderingContext::compressedTexImage3D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Dsizei, RefPtr<ArrayBufferView>&&)
+{
+}
+
+void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Dsizei, RefPtr<ArrayBufferView>&&)
+{
+}
+
+GC3Dint WebGL2RenderingContext::getFragDataLocation(WebGLProgram*, const String&)
+{
+ return 0;
+}
+
+void WebGL2RenderingContext::uniform1ui(WebGLUniformLocation*, GC3Duint)
+{
+}
+
+void WebGL2RenderingContext::uniform2ui(WebGLUniformLocation*, GC3Duint, GC3Duint)
+{
+}
+
+void WebGL2RenderingContext::uniform3ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint)
+{
+}
+
+void WebGL2RenderingContext::uniform4ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
+{
+}
+
+void WebGL2RenderingContext::uniform1uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniform2uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniform3uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniform4uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix2x3fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix3x2fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix2x4fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix4x2fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix3x4fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::uniformMatrix4x3fv(WebGLUniformLocation*, GC3Dboolean, RefPtr<Float32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::vertexAttribI4i(GC3Duint, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
+{
+}
+
+void WebGL2RenderingContext::vertexAttribI4iv(GC3Duint, RefPtr<Int32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::vertexAttribI4ui(GC3Duint, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
+{
+}
+
+void WebGL2RenderingContext::vertexAttribI4uiv(GC3Duint, RefPtr<Uint32Array>&&)
+{
+}
+
+void WebGL2RenderingContext::vertexAttribIPointer(GC3Duint, GC3Dint, GC3Denum, GC3Dsizei, GC3Dint64)
+{
+}
+
+void WebGL2RenderingContext::clear(GC3Dbitfield mask)
+{
+ if (isContextLostOrPending())
+ return;
+ if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
+ return;
+ }
+ if (m_framebufferBinding && (mask & GraphicsContext3D::COLOR_BUFFER_BIT) && isIntegerFormat(m_framebufferBinding->getColorBufferFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clear", "cannot clear an integer buffer");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ return;
+ }
+ if (!clearIfComposited(mask))
+ m_context->clear(mask);
+ markContextChanged();
+}
+
+void WebGL2RenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ if (isContextLostOrPending())
+ return;
+
+ WebGLRenderingContextBase::vertexAttribDivisor(index, divisor);
+}
+
+void WebGL2RenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount)
+{
+ if (isContextLostOrPending())
+ return;
+
+ WebGLRenderingContextBase::drawArraysInstanced(mode, first, count, instanceCount);
+}
+
+void WebGL2RenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount)
+{
+ if (isContextLostOrPending())
+ return;
+
+ WebGLRenderingContextBase::drawElementsInstanced(mode, count, type, offset, instanceCount);
+}
+
+void WebGL2RenderingContext::drawRangeElements(GC3Denum, GC3Duint, GC3Duint, GC3Dsizei, GC3Denum, GC3Dint64)
+{
+}
+
+void WebGL2RenderingContext::drawBuffers(const Vector<GC3Denum>& buffers)
+{
+ if (isContextLost())
+ return;
+ GC3Dsizei n = buffers.size();
+ const GC3Denum* bufs = buffers.data();
+ if (!m_framebufferBinding) {
+ if (n != 1) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than one buffer");
+ return;
+ }
+ if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "BACK or NONE");
+ return;
+ }
+ // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
+ GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
+ graphicsContext3D()->getExtensions().drawBuffersEXT(1, &value);
+ setBackDrawBuffer(bufs[0]);
+ } else {
+ if (n > getMaxDrawBuffers()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than max draw buffers");
+ return;
+ }
+ for (GC3Dsizei i = 0; i < n; ++i) {
+ if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + i)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "COLOR_ATTACHMENTi or NONE");
+ return;
+ }
+ }
+ m_framebufferBinding->drawBuffers(buffers);
+ }
+}
+
+void WebGL2RenderingContext::clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Int32Array>&&)
+{
+ switch (buffer) {
+ case GraphicsContext3D::COLOR:
+ if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index out of range");
+ return;
+ }
+ // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::STENCIL:
+ if (drawbuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index must be 0");
+ return;
+ }
+ // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::DEPTH:
+ case GraphicsContext3D::DEPTH_STENCIL:
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferiv", "buffer argument must be COLOR or STENCIL");
+ break;
+ }
+}
+
+void WebGL2RenderingContext::clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Uint32Array>&&)
+{
+ switch (buffer) {
+ case GraphicsContext3D::COLOR:
+ if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferuiv", "buffer index out of range");
+ return;
+ }
+ // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::DEPTH:
+ case GraphicsContext3D::STENCIL:
+ case GraphicsContext3D::DEPTH_STENCIL:
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferuiv", "buffer argument must be COLOR");
+ break;
+ }
+}
+
+void WebGL2RenderingContext::clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Float32Array>&&)
+{
+ switch (buffer) {
+ case GraphicsContext3D::COLOR:
+ if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index out of range");
+ return;
+ }
+ // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::DEPTH:
+ if (drawbuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
+ return;
+ }
+ // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::STENCIL:
+ case GraphicsContext3D::DEPTH_STENCIL:
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be COLOR OR DEPTH");
+ break;
+ }
+}
+
+void WebGL2RenderingContext::clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat, GC3Dint)
+{
+ switch (buffer) {
+ case GraphicsContext3D::DEPTH_STENCIL:
+ if (drawbuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
+ return;
+ }
+ // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h
+ break;
+ case GraphicsContext3D::COLOR:
+ case GraphicsContext3D::DEPTH:
+ case GraphicsContext3D::STENCIL:
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be DEPTH_STENCIL");
+ break;
+ }
+}
+
+RefPtr<WebGLQuery> WebGL2RenderingContext::createQuery()
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::deleteQuery(WebGLQuery*)
+{
+}
+
+GC3Dboolean WebGL2RenderingContext::isQuery(WebGLQuery*)
+{
+ return false;
+}
+
+void WebGL2RenderingContext::beginQuery(GC3Denum, WebGLQuery*)
+{
+}
+
+void WebGL2RenderingContext::endQuery(GC3Denum)
+{
+}
+
+RefPtr<WebGLQuery> WebGL2RenderingContext::getQuery(GC3Denum, GC3Denum)
+{
+ return nullptr;
+}
+
+WebGLAny WebGL2RenderingContext::getQueryParameter(WebGLQuery*, GC3Denum)
+{
+ return nullptr;
+}
+
+RefPtr<WebGLSampler> WebGL2RenderingContext::createSampler()
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::deleteSampler(WebGLSampler*)
+{
+}
+
+GC3Dboolean WebGL2RenderingContext::isSampler(WebGLSampler*)
+{
+ return false;
+}
+
+void WebGL2RenderingContext::bindSampler(GC3Duint, WebGLSampler*)
+{
+}
+
+void WebGL2RenderingContext::samplerParameteri(WebGLSampler*, GC3Denum, GC3Dint)
+{
+}
+
+void WebGL2RenderingContext::samplerParameterf(WebGLSampler*, GC3Denum, GC3Dfloat)
+{
+}
+
+WebGLAny WebGL2RenderingContext::getSamplerParameter(WebGLSampler*, GC3Denum)
+{
+ return nullptr;
+}
+
+RefPtr<WebGLSync> WebGL2RenderingContext::fenceSync(GC3Denum, GC3Dbitfield)
+{
+ return nullptr;
+}
+
+GC3Dboolean WebGL2RenderingContext::isSync(WebGLSync*)
+{
+ return false;
+}
+
+void WebGL2RenderingContext::deleteSync(WebGLSync*)
+{
+}
+
+GC3Denum WebGL2RenderingContext::clientWaitSync(WebGLSync*, GC3Dbitfield, GC3Duint64)
+{
+ return 0;
+}
+
+void WebGL2RenderingContext::waitSync(WebGLSync*, GC3Dbitfield, GC3Duint64)
+{
+}
+
+WebGLAny WebGL2RenderingContext::getSyncParameter(WebGLSync*, GC3Denum)
+{
+ return nullptr;
+}
+
+RefPtr<WebGLTransformFeedback> WebGL2RenderingContext::createTransformFeedback()
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::deleteTransformFeedback(WebGLTransformFeedback*)
+{
+}
+
+GC3Dboolean WebGL2RenderingContext::isTransformFeedback(WebGLTransformFeedback*)
+{
+ return false;
+}
+
+void WebGL2RenderingContext::bindTransformFeedback(GC3Denum, WebGLTransformFeedback*)
+{
+}
+
+void WebGL2RenderingContext::beginTransformFeedback(GC3Denum)
+{
+}
+
+void WebGL2RenderingContext::endTransformFeedback()
+{
+}
+
+void WebGL2RenderingContext::transformFeedbackVaryings(WebGLProgram*, const Vector<String>&, GC3Denum)
+{
+}
+
+RefPtr<WebGLActiveInfo> WebGL2RenderingContext::getTransformFeedbackVarying(WebGLProgram*, GC3Duint)
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::pauseTransformFeedback()
+{
+}
+
+void WebGL2RenderingContext::resumeTransformFeedback()
+{
+}
+
+void WebGL2RenderingContext::bindBufferBase(GC3Denum, GC3Duint, WebGLBuffer*)
+{
+}
+
+void WebGL2RenderingContext::bindBufferRange(GC3Denum, GC3Duint, WebGLBuffer*, GC3Dint64, GC3Dint64)
+{
+}
+
+WebGLAny WebGL2RenderingContext::getIndexedParameter(GC3Denum target, GC3Duint)
+{
+ switch (target) {
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_START:
+ case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
+ case GraphicsContext3D::UNIFORM_BUFFER_SIZE:
+ case GraphicsContext3D::UNIFORM_BUFFER_START:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "parameter name not yet supported");
+ return nullptr;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+Uint32Array* WebGL2RenderingContext::getUniformIndices(WebGLProgram*, const Vector<String>&)
+{
+ return nullptr;
+}
+
+Int32Array* WebGL2RenderingContext::getActiveUniforms(WebGLProgram*, RefPtr<Uint32Array>&&, GC3Denum)
+{
+ return nullptr;
+}
+
+GC3Duint WebGL2RenderingContext::getUniformBlockIndex(WebGLProgram*, const String&)
+{
+ return 0;
+}
+
+WebGLAny WebGL2RenderingContext::getActiveUniformBlockParameter(WebGLProgram*, GC3Duint, GC3Denum)
+{
+ return nullptr;
+}
+
+WebGLAny WebGL2RenderingContext::getActiveUniformBlockName(WebGLProgram*, GC3Duint)
+{
+ return nullptr;
+}
+
+void WebGL2RenderingContext::uniformBlockBinding(WebGLProgram*, GC3Duint, GC3Duint)
+{
+}
+
+RefPtr<WebGLVertexArrayObject> WebGL2RenderingContext::createVertexArray()
+{
+ if (isContextLost())
+ return nullptr;
+
+ auto object = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::User);
+ addContextObject(object.get());
+ return WTFMove(object);
+}
+
+void WebGL2RenderingContext::deleteVertexArray(WebGLVertexArrayObject* arrayObject)
+{
+ if (!arrayObject || isContextLost())
+ return;
+
+ if (arrayObject->isDeleted())
+ return;
+
+ if (!arrayObject->isDefaultObject() && arrayObject == m_boundVertexArrayObject)
+ setBoundVertexArrayObject(nullptr);
+
+ arrayObject->deleteObject(graphicsContext3D());
+}
+
+GC3Dboolean WebGL2RenderingContext::isVertexArray(WebGLVertexArrayObject* arrayObject)
+{
+ if (!arrayObject || isContextLost())
+ return false;
+
+ if (!arrayObject->hasEverBeenBound() || !arrayObject->validate(0, *this))
+ return false;
+
+ return m_context->isVertexArray(arrayObject->object());
+}
+
+void WebGL2RenderingContext::bindVertexArray(WebGLVertexArrayObject* arrayObject)
+{
+ if (isContextLost())
+ return;
+
+ if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, *this) || !m_contextObjects.contains(arrayObject))) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
+ m_context->bindVertexArray(arrayObject->object());
+
+ arrayObject->setHasEverBeenBound();
+ setBoundVertexArrayObject(arrayObject);
+ } else {
+ m_context->bindVertexArray(m_defaultVertexArrayObject->object());
+ setBoundVertexArrayObject(m_defaultVertexArrayObject.get());
+ }
+}
+
+WebGLExtension* WebGL2RenderingContext::getExtension(const String& name)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+
+ if (equalIgnoringASCIICase(name, "EXT_texture_filter_anisotropic") || equalIgnoringASCIICase(name, "WEBKIT_EXT_texture_filter_anisotropic")) {
+ if (!m_extTextureFilterAnisotropic) {
+ m_extTextureFilterAnisotropic = enableSupportedExtension("GL_EXT_texture_filter_anisotropic")
+ ? std::make_unique<EXTTextureFilterAnisotropic>(*this) : nullptr;
+ }
+ return m_extTextureFilterAnisotropic.get();
+ }
+ if (equalIgnoringASCIICase(name, "OES_texture_float")) {
+ if (!m_oesTextureFloat) {
+ m_oesTextureFloat = enableSupportedExtension("GL_OES_texture_float")
+ ? std::make_unique<OESTextureFloat>(*this) : nullptr;
+ }
+ return m_oesTextureFloat.get();
+ }
+ if (equalIgnoringASCIICase(name, "OES_texture_float_linear")) {
+ if (!m_oesTextureFloatLinear) {
+ m_oesTextureFloatLinear = enableSupportedExtension("GL_OES_texture_float_linear")
+ ? std::make_unique<OESTextureFloatLinear>(*this) : nullptr;
+ }
+ return m_oesTextureFloatLinear.get();
+ }
+ if (equalIgnoringASCIICase(name, "OES_texture_half_float")) {
+ if (!m_oesTextureHalfFloat) {
+ m_oesTextureHalfFloat = enableSupportedExtension("GL_OES_texture_half_float")
+ ? std::make_unique<OESTextureHalfFloat>(*this) : nullptr;
+ }
+ return m_oesTextureHalfFloat.get();
+ }
+ if (equalIgnoringASCIICase(name, "OES_texture_half_float_linear")) {
+ if (!m_oesTextureHalfFloatLinear) {
+ m_oesTextureHalfFloatLinear = enableSupportedExtension("GL_OES_texture_half_float_linear")
+ ? std::make_unique<OESTextureHalfFloatLinear>(*this) : nullptr;
+ }
+ return m_oesTextureHalfFloatLinear.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_lose_context")) {
+ if (!m_webglLoseContext)
+ m_webglLoseContext = std::make_unique<WebGLLoseContext>(*this);
+ return m_webglLoseContext.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_atc")) {
+ if (!m_webglCompressedTextureATC) {
+ if (WebGLCompressedTextureATC::supported(*this))
+ m_webglCompressedTextureATC = std::make_unique<WebGLCompressedTextureATC>(*this);
+ }
+ return m_webglCompressedTextureATC.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) {
+ if (!m_webglCompressedTexturePVRTC) {
+ m_webglCompressedTexturePVRTC = WebGLCompressedTexturePVRTC::supported(*this)
+ ? std::make_unique<WebGLCompressedTexturePVRTC>(*this) : nullptr;
+ }
+ return m_webglCompressedTexturePVRTC.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_compressed_texture_s3tc")) {
+ if (!m_webglCompressedTextureS3TC) {
+ m_webglCompressedTextureS3TC = WebGLCompressedTextureS3TC::supported(*this)
+ ? std::make_unique<WebGLCompressedTextureS3TC>(*this) : nullptr;
+ }
+ return m_webglCompressedTextureS3TC.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_depth_texture")) {
+ if (!m_webglDepthTexture) {
+ m_webglDepthTexture = WebGLDepthTexture::supported(*graphicsContext3D())
+ ? std::make_unique<WebGLDepthTexture>(*this) : nullptr;
+ }
+ return m_webglDepthTexture.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_debug_renderer_info")) {
+ if (!m_webglDebugRendererInfo)
+ m_webglDebugRendererInfo = std::make_unique<WebGLDebugRendererInfo>(*this);
+ return m_webglDebugRendererInfo.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_debug_shaders")) {
+ if (!m_webglDebugShaders) {
+ m_webglDebugShaders = m_context->getExtensions().supports(ASCIILiteral { "GL_ANGLE_translated_shader_source" })
+ ? std::make_unique<WebGLDebugShaders>(*this) : nullptr;
+ }
+ return m_webglDebugShaders.get();
+ }
+
+ return nullptr;
+}
+
+std::optional<Vector<String>> WebGL2RenderingContext::getSupportedExtensions()
+{
+ if (isContextLost())
+ return std::nullopt;
+
+ Vector<String> result;
+
+ if (m_isPendingPolicyResolution)
+ return result;
+
+ auto& extensions = m_context->getExtensions();
+ if (extensions.supports(ASCIILiteral { "GL_OES_texture_float" }))
+ result.append(ASCIILiteral { "OES_texture_float" });
+ if (extensions.supports(ASCIILiteral { "GL_OES_texture_float_linear" }))
+ result.append(ASCIILiteral { "OES_texture_float_linear" });
+ if (extensions.supports(ASCIILiteral { "GL_OES_texture_half_float" }))
+ result.append(ASCIILiteral { "OES_texture_half_float" });
+ if (extensions.supports(ASCIILiteral { "GL_OES_texture_half_float_linear" }))
+ result.append(ASCIILiteral { "OES_texture_half_float_linear" });
+ if (extensions.supports(ASCIILiteral { "GL_EXT_texture_filter_anisotropic" }))
+ result.append(ASCIILiteral { "WEBKIT_EXT_texture_filter_anisotropic" });
+ if (WebGLCompressedTextureATC::supported(*this))
+ result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_atc" });
+ if (WebGLCompressedTexturePVRTC::supported(*this))
+ result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_pvrtc" });
+ if (WebGLCompressedTextureS3TC::supported(*this))
+ result.append(ASCIILiteral { "WEBGL_compressed_texture_s3tc" });
+ if (WebGLDepthTexture::supported(*graphicsContext3D()))
+ result.append(ASCIILiteral { "WEBGL_depth_texture" });
+ result.append(ASCIILiteral { "WEBGL_lose_context" });
+ if (extensions.supports(ASCIILiteral { "GL_ANGLE_translated_shader_source" }))
+ result.append(ASCIILiteral { "WEBGL_debug_shaders" });
+ result.append(ASCIILiteral { "WEBGL_debug_renderer_info" });
+
+ return result;
+}
+
+WebGLAny WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
+{
+ if (isContextLostOrPending() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ return nullptr;
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+ return nullptr;
+ }
+
+ auto* object = m_framebufferBinding->getAttachmentObject(attachment);
+ if (!object) {
+ if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return static_cast<unsigned>(GraphicsContext3D::NONE);
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL specifies INVALID_OPERATION.
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+ return nullptr;
+ }
+
+ if (object->isTexture()) {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return static_cast<unsigned>(GraphicsContext3D::TEXTURE);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return makeRefPtr(reinterpret_cast<WebGLTexture&>(*object));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: {
+ GC3Dint value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return value;
+ }
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+ return nullptr;
+ }
+ } else {
+ ASSERT(object->isRenderbuffer());
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return static_cast<unsigned>(GraphicsContext3D::RENDERBUFFER);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return makeRefPtr(reinterpret_cast<WebGLRenderbuffer&>(*object));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : {
+ auto& renderBuffer = reinterpret_cast<WebGLRenderbuffer&>(*object);
+ auto format = renderBuffer.getInternalFormat();
+ if (format == GraphicsContext3D::SRGB8_ALPHA8
+ || format == GraphicsContext3D::COMPRESSED_SRGB8_ETC2
+ || format == GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+ || format == GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) {
+ return static_cast<unsigned>(GraphicsContext3D::SRGB);
+ }
+ return static_cast<unsigned>(GraphicsContext3D::LINEAR);
+ }
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+ return nullptr;
+ }
+ }
+}
+
+bool WebGL2RenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
+{
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ return true;
+ default:
+ if (attachment >= GraphicsContext3D::COLOR_ATTACHMENT0 && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
+ return true;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
+ return false;
+ }
+}
+
+GC3Dint WebGL2RenderingContext::getMaxDrawBuffers()
+{
+ if (!m_maxDrawBuffers)
+ m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxDrawBuffers);
+ return m_maxDrawBuffers;
+}
+
+GC3Dint WebGL2RenderingContext::getMaxColorAttachments()
+{
+ // DrawBuffers requires MAX_COLOR_ATTACHMENTS == MAX_DRAW_BUFFERS
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxColorAttachments);
+ return m_maxColorAttachments;
+}
+
+void WebGL2RenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
+ return;
+ }
+ if (!validateSize("renderbufferStorage", width, height))
+ return;
+ switch (internalformat) {
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::RGBA32I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::STENCIL_INDEX8:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ m_context->renderbufferStorage(target, internalformat, width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ m_renderbufferBinding->setIsValid(true);
+ m_renderbufferBinding->setSize(width, height);
+ break;
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ if (!isDepthStencilSupported()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ m_context->renderbufferStorage(target, internalformat, width, height);
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setIsValid(isDepthStencilSupported());
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ applyStencilTest();
+}
+
+void WebGL2RenderingContext::hint(GC3Denum target, GC3Denum mode)
+{
+ if (isContextLostOrPending())
+ return;
+ bool isValid = false;
+ switch (target) {
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
+ isValid = true;
+ break;
+ }
+ if (!isValid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
+ return;
+ }
+ m_context->hint(target, mode);
+}
+
+GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
+{
+ // Handles sized, unsized, and compressed internal formats.
+ switch (internalformat) {
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::COMPRESSED_R11_EAC:
+ case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
+ return GraphicsContext3D::RED;
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::COMPRESSED_RG11_EAC:
+ case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
+ return GraphicsContext3D::RG;
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
+ case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
+ return GraphicsContext3D::RGB;
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA32I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
+ case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return GraphicsContext3D::RGBA;
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ return GraphicsContext3D::DEPTH_COMPONENT;
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ return GraphicsContext3D::DEPTH_STENCIL;
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::ALPHA:
+ return internalformat;
+ default:
+ ASSERT_NOT_REACHED();
+ return GraphicsContext3D::NONE;
+ }
+}
+
+bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat)
+{
+ // FIXME: baseInternalFormatFromInternalFormat() never returns any of these enums.
+ // Because of that, this function erroneously always returns false!
+ switch (baseInternalFormatFromInternalFormat(internalformat)) {
+ case GraphicsContext3D::RED_INTEGER:
+ case GraphicsContext3D::RG_INTEGER:
+ case GraphicsContext3D::RGB_INTEGER:
+ case GraphicsContext3D::RGBA_INTEGER:
+ return true;
+ }
+ return false;
+}
+
+WebGLAny WebGL2RenderingContext::getParameter(GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ switch (pname) {
+ case GraphicsContext3D::ACTIVE_TEXTURE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALPHA_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::ARRAY_BUFFER_BINDING:
+ return m_boundArrayBuffer;
+ case GraphicsContext3D::BLEND:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::BLEND_COLOR:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::BLEND_DST_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_DST_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLUE_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::COLOR_CLEAR_VALUE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::COLOR_WRITEMASK:
+ return getBooleanArrayParameter(pname);
+ case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
+ return Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size());
+ case GraphicsContext3D::CULL_FACE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::CULL_FACE_MODE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::CURRENT_PROGRAM:
+ return m_currentProgram;
+ case GraphicsContext3D::DEPTH_BITS:
+ if (!m_framebufferBinding && !m_attributes.depth)
+ return 0;
+ return getIntParameter(pname);
+ case GraphicsContext3D::DEPTH_CLEAR_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::DEPTH_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::DEPTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::DEPTH_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::DEPTH_WRITEMASK:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::DITHER:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
+ return makeRefPtr(m_boundVertexArrayObject->getElementArrayBuffer());
+ case GraphicsContext3D::FRAMEBUFFER_BINDING:
+ return m_framebufferBinding;
+ case GraphicsContext3D::FRONT_FACE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::GREEN_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::LINE_WIDTH:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VARYING_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VIEWPORT_DIMS:
+ return getWebGLIntArrayParameter(pname);
+ case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::PACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_FILL:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_UNITS:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::RED_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::RENDERBUFFER_BINDING:
+ return m_renderbufferBinding;
+ case GraphicsContext3D::RENDERER:
+ return String { ASCIILiteral { "WebKit WebGL" } };
+ case GraphicsContext3D::SAMPLE_BUFFERS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::SAMPLES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::SCISSOR_BOX:
+ return getWebGLIntArrayParameter(pname);
+ case GraphicsContext3D::SCISSOR_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
+ return "WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")";
+ case GraphicsContext3D::STENCIL_BACK_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_REF:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BITS:
+ if (!m_framebufferBinding && !m_attributes.stencil)
+ return 0;
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_CLEAR_VALUE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_REF:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::STENCIL_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::SUBPIXEL_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::TEXTURE_BINDING_2D:
+ return m_textureUnits[m_activeTextureUnit].texture2DBinding;
+ case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
+ return m_textureUnits[m_activeTextureUnit].textureCubeMapBinding;
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
+ return m_unpackFlipY;
+ case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ return m_unpackPremultiplyAlpha;
+ case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ return m_unpackColorspaceConversion;
+ case GraphicsContext3D::VENDOR:
+ return String { ASCIILiteral { "WebKit" } };
+ case GraphicsContext3D::VERSION:
+ return "WebGL 2.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")";
+ case GraphicsContext3D::VIEWPORT:
+ return getWebGLIntArrayParameter(pname);
+ case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return m_context->getString(GraphicsContext3D::RENDERER);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return nullptr;
+ case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return m_context->getString(GraphicsContext3D::VENDOR);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return nullptr;
+ case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (m_extTextureFilterAnisotropic)
+ return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return nullptr;
+ case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_3D_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_ARRAY_TEXTURE_LAYERS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_COLOR_ATTACHMENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+ return getInt64Parameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_UNIFORM_BLOCKS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+ return getInt64Parameter(pname);
+ case GraphicsContext3D::MAX_DRAW_BUFFERS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_ELEMENT_INDEX:
+ return getInt64Parameter(pname);
+ case GraphicsContext3D::MAX_ELEMENTS_INDICES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_ELEMENTS_VERTICES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_BLOCKS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_PROGRAM_TEXEL_OFFSET:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_SAMPLES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_SERVER_WAIT_TIMEOUT:
+ return getInt64Parameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_LOD_BIAS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_UNIFORM_BLOCK_SIZE:
+ return getInt64Parameter(pname);
+ case GraphicsContext3D::MAX_UNIFORM_BUFFER_BINDINGS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VARYING_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_OUTPUT_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_UNIFORM_BLOCKS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_UNIFORM_COMPONENTS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MIN_PROGRAM_TEXEL_OFFSET:
+ return getIntParameter(pname);
+ case GraphicsContext3D::PACK_ROW_LENGTH:
+ return getIntParameter(pname);
+ case GraphicsContext3D::PACK_SKIP_PIXELS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::PACK_SKIP_ROWS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_IMAGE_HEIGHT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_ROW_LENGTH:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_SKIP_IMAGES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_SKIP_PIXELS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_SKIP_ROWS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::RASTERIZER_DISCARD:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_ACTIVE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_PAUSED:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::VERTEX_ARRAY_BINDING:
+ if (m_boundVertexArrayObject->isDefaultObject())
+ return nullptr;
+ return makeRefPtr(static_cast<WebGLVertexArrayObject&>(*m_boundVertexArrayObject));
+ case GraphicsContext3D::DRAW_BUFFER0:
+ case GraphicsContext3D::DRAW_BUFFER1:
+ case GraphicsContext3D::DRAW_BUFFER2:
+ case GraphicsContext3D::DRAW_BUFFER3:
+ case GraphicsContext3D::DRAW_BUFFER4:
+ case GraphicsContext3D::DRAW_BUFFER5:
+ case GraphicsContext3D::DRAW_BUFFER6:
+ case GraphicsContext3D::DRAW_BUFFER7:
+ case GraphicsContext3D::DRAW_BUFFER8:
+ case GraphicsContext3D::DRAW_BUFFER9:
+ case GraphicsContext3D::DRAW_BUFFER10:
+ case GraphicsContext3D::DRAW_BUFFER11:
+ case GraphicsContext3D::DRAW_BUFFER12:
+ case GraphicsContext3D::DRAW_BUFFER13:
+ case GraphicsContext3D::DRAW_BUFFER14:
+ case GraphicsContext3D::DRAW_BUFFER15:
+ if (m_framebufferBinding)
+ return m_framebufferBinding->getDrawBuffer(pname);
+ return m_backDrawBuffer; // emulated backbuffer
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER_BINDING:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER_BINDING:
+ case GraphicsContext3D::READ_BUFFER:
+ case GraphicsContext3D::SAMPLER_BINDING:
+ case GraphicsContext3D::TEXTURE_BINDING_2D_ARRAY:
+ case GraphicsContext3D::TEXTURE_BINDING_3D:
+ case GraphicsContext3D::READ_FRAMEBUFFER_BINDING:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "parameter name not yet supported");
+ return nullptr;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+bool WebGL2RenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
+{
+ // Performs conservative validation by caching a maximum index of
+ // the given type per element array buffer. If all of the bound
+ // array buffers have enough elements to satisfy that maximum
+ // index, skips the expensive per-draw-call iteration in
+ // validateIndexArrayPrecise.
+
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ return false;
+
+ GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
+ // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+ if (!numElements)
+ return false;
+ auto* buffer = elementArrayBuffer->elementArrayBuffer();
+ ASSERT(buffer);
+
+ std::optional<unsigned> maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
+ if (!maxIndex) {
+ // Compute the maximum index in the entire buffer for the given type of index.
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE: {
+ const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
+ break;
+ }
+ case GraphicsContext3D::UNSIGNED_SHORT: {
+ numElements /= sizeof(GC3Dushort);
+ const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
+ break;
+ }
+ case GraphicsContext3D::UNSIGNED_INT: {
+ numElements /= sizeof(GC3Duint);
+ const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
+ break;
+ }
+ default:
+ return false;
+ }
+ if (maxIndex)
+ elementArrayBuffer->setCachedMaxIndex(type, maxIndex.value());
+ }
+
+ if (!maxIndex)
+ return false;
+
+ // The number of required elements is one more than the maximum
+ // index that will be accessed.
+ numElementsRequired = maxIndex.value() + 1;
+
+ // Check for overflow.
+ return numElementsRequired > 0;
+}
+
+bool WebGL2RenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
+{
+ switch (mode) {
+ case GraphicsContext3D::FUNC_ADD:
+ case GraphicsContext3D::FUNC_SUBTRACT:
+ case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+ case GraphicsContext3D::MIN:
+ case GraphicsContext3D::MAX:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ }
+}
+
+bool WebGL2RenderingContext::validateCapability(const char* functionName, GC3Denum cap)
+{
+ switch (cap) {
+ case GraphicsContext3D::BLEND:
+ case GraphicsContext3D::CULL_FACE:
+ case GraphicsContext3D::DEPTH_TEST:
+ case GraphicsContext3D::DITHER:
+ case GraphicsContext3D::POLYGON_OFFSET_FILL:
+ case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
+ case GraphicsContext3D::SAMPLE_COVERAGE:
+ case GraphicsContext3D::SCISSOR_TEST:
+ case GraphicsContext3D::STENCIL_TEST:
+ case GraphicsContext3D::RASTERIZER_DISCARD:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability");
+ return false;
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.h b/Source/WebCore/html/canvas/WebGL2RenderingContext.h
new file mode 100644
index 000000000..720b13269
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGL2RenderingContext.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGL2)
+
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+class WebGLQuery;
+class WebGLSampler;
+class WebGLSync;
+class WebGLTransformFeedback;
+class WebGLVertexArrayObject;
+
+class WebGL2RenderingContext final : public WebGLRenderingContextBase {
+public:
+ WebGL2RenderingContext(HTMLCanvasElement&, WebGLContextAttributes);
+ WebGL2RenderingContext(HTMLCanvasElement&, Ref<GraphicsContext3D>&&, WebGLContextAttributes);
+
+ // Buffer objects
+ using WebGLRenderingContextBase::bufferData;
+ using WebGLRenderingContextBase::bufferSubData;
+ void bufferData(GC3Denum target, const ArrayBufferView& data, GC3Denum usage, GC3Duint srcOffset, GC3Duint length);
+ void bufferSubData(GC3Denum target, long long offset, const ArrayBufferView& data, GC3Duint srcOffset, GC3Duint length);
+ void copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size);
+ void getBufferSubData(GC3Denum target, long long srcByteOffset, RefPtr<ArrayBufferView>&& dstData, GC3Duint dstOffset = 0, GC3Duint length = 0);
+
+ // Framebuffer objects
+ WebGLAny getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname) final;
+ void blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter);
+ void framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer);
+ WebGLAny getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname);
+ void invalidateFramebuffer(GC3Denum target, const Vector<GC3Denum>& attachments);
+ void invalidateSubFramebuffer(GC3Denum target, const Vector<GC3Denum>& attachments, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+ void readBuffer(GC3Denum src);
+
+ // Renderbuffer objects
+ void renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
+
+ // Texture objects
+ void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height);
+ void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
+ void texImage3D(GC3Denum target, GC3Dint level, GC3Dint internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels);
+
+ void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels);
+ using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
+ void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, TexImageSource&&);
+
+ void copyTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+ void compressedTexImage3D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Dsizei imageSize, RefPtr<ArrayBufferView>&& data);
+ void compressedTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Dsizei imageSize, RefPtr<ArrayBufferView>&& data);
+
+ // Programs and shaders
+ GC3Dint getFragDataLocation(WebGLProgram*, const String& name);
+
+ // Uniforms and attributes
+ void uniform1ui(WebGLUniformLocation*, GC3Duint v0);
+ void uniform2ui(WebGLUniformLocation*, GC3Duint v0, GC3Duint v1);
+ void uniform3ui(WebGLUniformLocation*, GC3Duint v0, GC3Duint v1, GC3Duint v2);
+ void uniform4ui(WebGLUniformLocation*, GC3Duint v0, GC3Duint v1, GC3Duint v2, GC3Duint v3);
+ void uniform1uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&& value);
+ void uniform2uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&& value);
+ void uniform3uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&& value);
+ void uniform4uiv(WebGLUniformLocation*, RefPtr<Uint32Array>&& value);
+ void uniformMatrix2x3fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void uniformMatrix3x2fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void uniformMatrix2x4fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void uniformMatrix4x2fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void uniformMatrix3x4fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void uniformMatrix4x3fv(WebGLUniformLocation*, GC3Dboolean transpose, RefPtr<Float32Array>&& value);
+ void vertexAttribI4i(GC3Duint index, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
+ void vertexAttribI4iv(GC3Duint index, RefPtr<Int32Array>&& v);
+ void vertexAttribI4ui(GC3Duint index, GC3Duint x, GC3Duint y, GC3Duint z, GC3Duint w);
+ void vertexAttribI4uiv(GC3Duint index, RefPtr<Uint32Array>&& v);
+ void vertexAttribIPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dsizei stride, GC3Dint64 offset);
+
+ // Writing to the drawing buffer
+ void clear(GC3Dbitfield mask) final;
+ void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+ void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount);
+ void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount);
+ void drawRangeElements(GC3Denum mode, GC3Duint start, GC3Duint end, GC3Dsizei count, GC3Denum type, GC3Dint64 offset);
+
+ // Multiple render targets
+ void drawBuffers(const Vector<GC3Denum>& buffers);
+ void clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Int32Array>&& value);
+ void clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Uint32Array>&& value);
+ void clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, RefPtr<Float32Array>&& value);
+ void clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat depth, GC3Dint stencil);
+
+ // Query objects
+ RefPtr<WebGLQuery> createQuery();
+ void deleteQuery(WebGLQuery*);
+ GC3Dboolean isQuery(WebGLQuery*);
+ void beginQuery(GC3Denum target, WebGLQuery*);
+ void endQuery(GC3Denum target);
+ RefPtr<WebGLQuery> getQuery(GC3Denum target, GC3Denum pname);
+ WebGLAny getQueryParameter(WebGLQuery*, GC3Denum pname);
+
+ // Sampler objects
+ RefPtr<WebGLSampler> createSampler();
+ void deleteSampler(WebGLSampler*);
+ GC3Dboolean isSampler(WebGLSampler*);
+ void bindSampler(GC3Duint unit, WebGLSampler*);
+ void samplerParameteri(WebGLSampler*, GC3Denum pname, GC3Dint param);
+ void samplerParameterf(WebGLSampler*, GC3Denum pname, GC3Dfloat param);
+ WebGLAny getSamplerParameter(WebGLSampler*, GC3Denum pname);
+
+ // Sync objects
+ RefPtr<WebGLSync> fenceSync(GC3Denum condition, GC3Dbitfield flags);
+ GC3Dboolean isSync(WebGLSync*);
+ void deleteSync(WebGLSync*);
+ GC3Denum clientWaitSync(WebGLSync*, GC3Dbitfield flags, GC3Duint64 timeout);
+ void waitSync(WebGLSync*, GC3Dbitfield flags, GC3Duint64 timeout);
+ WebGLAny getSyncParameter(WebGLSync*, GC3Denum pname);
+
+ // Transform feedback
+ RefPtr<WebGLTransformFeedback> createTransformFeedback();
+ void deleteTransformFeedback(WebGLTransformFeedback* id);
+ GC3Dboolean isTransformFeedback(WebGLTransformFeedback* id);
+ void bindTransformFeedback(GC3Denum target, WebGLTransformFeedback* id);
+ void beginTransformFeedback(GC3Denum primitiveMode);
+ void endTransformFeedback();
+ void transformFeedbackVaryings(WebGLProgram*, const Vector<String>& varyings, GC3Denum bufferMode);
+ RefPtr<WebGLActiveInfo> getTransformFeedbackVarying(WebGLProgram*, GC3Duint index);
+ void pauseTransformFeedback();
+ void resumeTransformFeedback();
+
+ // Uniform buffer objects and transform feedback buffers
+ void bindBufferBase(GC3Denum target, GC3Duint index, WebGLBuffer*);
+ void bindBufferRange(GC3Denum target, GC3Duint index, WebGLBuffer*, GC3Dint64 offset, GC3Dint64 size);
+ WebGLAny getIndexedParameter(GC3Denum target, GC3Duint index);
+ Uint32Array* getUniformIndices(WebGLProgram*, const Vector<String>& uniformNames);
+ Int32Array* getActiveUniforms(WebGLProgram*, RefPtr<Uint32Array>&& uniformIndices, GC3Denum pname);
+ GC3Duint getUniformBlockIndex(WebGLProgram*, const String& uniformBlockName);
+ WebGLAny getActiveUniformBlockParameter(WebGLProgram*, GC3Duint uniformBlockIndex, GC3Denum pname);
+ WebGLAny getActiveUniformBlockName(WebGLProgram*, GC3Duint uniformBlockIndex);
+ void uniformBlockBinding(WebGLProgram*, GC3Duint uniformBlockIndex, GC3Duint uniformBlockBinding);
+
+ // Vertex array objects
+ RefPtr<WebGLVertexArrayObject> createVertexArray();
+ void deleteVertexArray(WebGLVertexArrayObject* vertexArray);
+ GC3Dboolean isVertexArray(WebGLVertexArrayObject* vertexArray);
+ void bindVertexArray(WebGLVertexArrayObject* vertexArray);
+
+private:
+ bool isWebGL2() const final { return true; }
+
+ // Extensions
+ WebGLExtension* getExtension(const String&) final;
+ std::optional<Vector<String>> getSupportedExtensions() final;
+ WebGLAny getParameter(GC3Denum pname) final;
+
+ void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) final;
+ void hint(GC3Denum target, GC3Denum mode) final;
+
+ void initializeVertexArrayObjects() final;
+ GC3Dint getMaxDrawBuffers() final;
+ GC3Dint getMaxColorAttachments() final;
+ bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) final;
+ bool validateBlendEquation(const char* functionName, GC3Denum mode) final;
+ bool validateCapability(const char* functionName, GC3Denum cap) final;
+ bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) final;
+
+ GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
+ bool isIntegerFormat(GC3Denum internalformat);
+ void initializeShaderExtensions();
+
+ bool validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName);
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::WebGL2RenderingContext, isWebGL2())
+
+#endif // WEBGL2
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.idl b/Source/WebCore/html/canvas/WebGL2RenderingContext.idl
new file mode 100644
index 000000000..15c2f4ed5
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGL2RenderingContext.idl
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+typedef unsigned long GLenum;
+typedef boolean GLboolean;
+typedef unsigned long GLbitfield;
+typedef byte GLbyte;
+typedef short GLshort;
+typedef long GLint;
+typedef long GLsizei;
+typedef long long GLintptr;
+typedef long long GLsizeiptr;
+typedef long long GLint64;
+typedef octet GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned long GLuint;
+typedef unsigned long long GLuint64;
+typedef unrestricted float GLfloat;
+typedef unrestricted float GLclampf;
+typedef (ArrayBuffer or ArrayBufferView) BufferDataSource;
+
+// FIXME: Should allow ImageBitmap too.
+typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
+
+[
+ Conditional=WEBGL2,
+ EnabledAtRuntime=WebGL2,
+ JSCustomMarkFunction,
+ JSGenerateToJSObject,
+ DoNotCheckConstants,
+] interface WebGL2RenderingContext : WebGLRenderingContextBase {
+ const GLenum READ_BUFFER = 0x0C02;
+ const GLenum UNPACK_ROW_LENGTH = 0x0CF2;
+ const GLenum UNPACK_SKIP_ROWS = 0x0CF3;
+ const GLenum UNPACK_SKIP_PIXELS = 0x0CF4;
+ const GLenum PACK_ROW_LENGTH = 0x0D02;
+ const GLenum PACK_SKIP_ROWS = 0x0D03;
+ const GLenum PACK_SKIP_PIXELS = 0x0D04;
+ const GLenum COLOR = 0x1800;
+ const GLenum DEPTH = 0x1801;
+ const GLenum STENCIL = 0x1802;
+ const GLenum RED = 0x1903;
+ const GLenum RGB8 = 0x8051;
+ const GLenum RGBA8 = 0x8058;
+ const GLenum RGB10_A2 = 0x8059;
+ const GLenum TEXTURE_BINDING_3D = 0x806A;
+ const GLenum UNPACK_SKIP_IMAGES = 0x806D;
+ const GLenum UNPACK_IMAGE_HEIGHT = 0x806E;
+ const GLenum TEXTURE_3D = 0x806F;
+ const GLenum TEXTURE_WRAP_R = 0x8072;
+ const GLenum MAX_3D_TEXTURE_SIZE = 0x8073;
+ const GLenum UNSIGNED_INT_2_10_10_10_REV = 0x8368;
+ const GLenum MAX_ELEMENTS_VERTICES = 0x80E8;
+ const GLenum MAX_ELEMENTS_INDICES = 0x80E9;
+ const GLenum TEXTURE_MIN_LOD = 0x813A;
+ const GLenum TEXTURE_MAX_LOD = 0x813B;
+ const GLenum TEXTURE_BASE_LEVEL = 0x813C;
+ const GLenum TEXTURE_MAX_LEVEL = 0x813D;
+ const GLenum MIN = 0x8007;
+ const GLenum MAX = 0x8008;
+ const GLenum DEPTH_COMPONENT24 = 0x81A6;
+ const GLenum MAX_TEXTURE_LOD_BIAS = 0x84FD;
+ const GLenum TEXTURE_COMPARE_MODE = 0x884C;
+ const GLenum TEXTURE_COMPARE_FUNC = 0x884D;
+ const GLenum CURRENT_QUERY = 0x8865;
+ const GLenum QUERY_RESULT = 0x8866;
+ const GLenum QUERY_RESULT_AVAILABLE = 0x8867;
+ const GLenum STREAM_READ = 0x88E1;
+ const GLenum STREAM_COPY = 0x88E2;
+ const GLenum STATIC_READ = 0x88E5;
+ const GLenum STATIC_COPY = 0x88E6;
+ const GLenum DYNAMIC_READ = 0x88E9;
+ const GLenum DYNAMIC_COPY = 0x88EA;
+ const GLenum MAX_DRAW_BUFFERS = 0x8824;
+ const GLenum DRAW_BUFFER0 = 0x8825;
+ const GLenum DRAW_BUFFER1 = 0x8826;
+ const GLenum DRAW_BUFFER2 = 0x8827;
+ const GLenum DRAW_BUFFER3 = 0x8828;
+ const GLenum DRAW_BUFFER4 = 0x8829;
+ const GLenum DRAW_BUFFER5 = 0x882A;
+ const GLenum DRAW_BUFFER6 = 0x882B;
+ const GLenum DRAW_BUFFER7 = 0x882C;
+ const GLenum DRAW_BUFFER8 = 0x882D;
+ const GLenum DRAW_BUFFER9 = 0x882E;
+ const GLenum DRAW_BUFFER10 = 0x882F;
+ const GLenum DRAW_BUFFER11 = 0x8830;
+ const GLenum DRAW_BUFFER12 = 0x8831;
+ const GLenum DRAW_BUFFER13 = 0x8832;
+ const GLenum DRAW_BUFFER14 = 0x8833;
+ const GLenum DRAW_BUFFER15 = 0x8834;
+ const GLenum MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49;
+ const GLenum MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A;
+ const GLenum SAMPLER_3D = 0x8B5F;
+ const GLenum SAMPLER_2D_SHADOW = 0x8B62;
+ const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B;
+ const GLenum PIXEL_PACK_BUFFER = 0x88EB;
+ const GLenum PIXEL_UNPACK_BUFFER = 0x88EC;
+ const GLenum PIXEL_PACK_BUFFER_BINDING = 0x88ED;
+ const GLenum PIXEL_UNPACK_BUFFER_BINDING = 0x88EF;
+ const GLenum FLOAT_MAT2x3 = 0x8B65;
+ const GLenum FLOAT_MAT2x4 = 0x8B66;
+ const GLenum FLOAT_MAT3x2 = 0x8B67;
+ const GLenum FLOAT_MAT3x4 = 0x8B68;
+ const GLenum FLOAT_MAT4x2 = 0x8B69;
+ const GLenum FLOAT_MAT4x3 = 0x8B6A;
+ const GLenum SRGB = 0x8C40;
+ const GLenum SRGB8 = 0x8C41;
+ const GLenum SRGB8_ALPHA8 = 0x8C43;
+ const GLenum COMPARE_REF_TO_TEXTURE = 0x884E;
+ const GLenum RGBA32F = 0x8814;
+ const GLenum RGB32F = 0x8815;
+ const GLenum RGBA16F = 0x881A;
+ const GLenum RGB16F = 0x881B;
+ const GLenum VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD;
+ const GLenum MAX_ARRAY_TEXTURE_LAYERS = 0x88FF;
+ const GLenum MIN_PROGRAM_TEXEL_OFFSET = 0x8904;
+ const GLenum MAX_PROGRAM_TEXEL_OFFSET = 0x8905;
+ const GLenum MAX_VARYING_COMPONENTS = 0x8B4B;
+ const GLenum TEXTURE_2D_ARRAY = 0x8C1A;
+ const GLenum TEXTURE_BINDING_2D_ARRAY = 0x8C1D;
+ const GLenum R11F_G11F_B10F = 0x8C3A;
+ const GLenum UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;
+ const GLenum RGB9_E5 = 0x8C3D;
+ const GLenum UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;
+ const GLenum TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F;
+ const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80;
+ const GLenum TRANSFORM_FEEDBACK_VARYINGS = 0x8C83;
+ const GLenum TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84;
+ const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
+ const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88;
+ const GLenum RASTERIZER_DISCARD = 0x8C89;
+ const GLenum MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
+ const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
+ const GLenum INTERLEAVED_ATTRIBS = 0x8C8C;
+ const GLenum SEPARATE_ATTRIBS = 0x8C8D;
+ const GLenum TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
+ const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F;
+ const GLenum RGBA32UI = 0x8D70;
+ const GLenum RGB32UI = 0x8D71;
+ const GLenum RGBA16UI = 0x8D76;
+ const GLenum RGB16UI = 0x8D77;
+ const GLenum RGBA8UI = 0x8D7C;
+ const GLenum RGB8UI = 0x8D7D;
+ const GLenum RGBA32I = 0x8D82;
+ const GLenum RGB32I = 0x8D83;
+ const GLenum RGBA16I = 0x8D88;
+ const GLenum RGB16I = 0x8D89;
+ const GLenum RGBA8I = 0x8D8E;
+ const GLenum RGB8I = 0x8D8F;
+ const GLenum RED_INTEGER = 0x8D94;
+ const GLenum RGB_INTEGER = 0x8D98;
+ const GLenum RGBA_INTEGER = 0x8D99;
+ const GLenum SAMPLER_2D_ARRAY = 0x8DC1;
+ const GLenum SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;
+ const GLenum SAMPLER_CUBE_SHADOW = 0x8DC5;
+ const GLenum UNSIGNED_INT_VEC2 = 0x8DC6;
+ const GLenum UNSIGNED_INT_VEC3 = 0x8DC7;
+ const GLenum UNSIGNED_INT_VEC4 = 0x8DC8;
+ const GLenum INT_SAMPLER_2D = 0x8DCA;
+ const GLenum INT_SAMPLER_3D = 0x8DCB;
+ const GLenum INT_SAMPLER_CUBE = 0x8DCC;
+ const GLenum INT_SAMPLER_2D_ARRAY = 0x8DCF;
+ const GLenum UNSIGNED_INT_SAMPLER_2D = 0x8DD2;
+ const GLenum UNSIGNED_INT_SAMPLER_3D = 0x8DD3;
+ const GLenum UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;
+ const GLenum UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;
+ const GLenum DEPTH_COMPONENT32F = 0x8CAC;
+ const GLenum DEPTH32F_STENCIL8 = 0x8CAD;
+ const GLenum FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;
+ const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210;
+ const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211;
+ const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212;
+ const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213;
+ const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214;
+ const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215;
+ const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216;
+ const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217;
+ const GLenum FRAMEBUFFER_DEFAULT = 0x8218;
+ const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
+ const GLenum DEPTH_STENCIL = 0x84F9;
+ const GLenum UNSIGNED_INT_24_8 = 0x84FA;
+ const GLenum DEPTH24_STENCIL8 = 0x88F0;
+ const GLenum UNSIGNED_NORMALIZED = 0x8C17;
+ const GLenum DRAW_FRAMEBUFFER_BINDING = 0x8CA6; /* Same as FRAMEBUFFER_BINDING */
+ const GLenum READ_FRAMEBUFFER = 0x8CA8;
+ const GLenum DRAW_FRAMEBUFFER = 0x8CA9;
+ const GLenum READ_FRAMEBUFFER_BINDING = 0x8CAA;
+ const GLenum RENDERBUFFER_SAMPLES = 0x8CAB;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4;
+ const GLenum MAX_COLOR_ATTACHMENTS = 0x8CDF;
+ const GLenum COLOR_ATTACHMENT1 = 0x8CE1;
+ const GLenum COLOR_ATTACHMENT2 = 0x8CE2;
+ const GLenum COLOR_ATTACHMENT3 = 0x8CE3;
+ const GLenum COLOR_ATTACHMENT4 = 0x8CE4;
+ const GLenum COLOR_ATTACHMENT5 = 0x8CE5;
+ const GLenum COLOR_ATTACHMENT6 = 0x8CE6;
+ const GLenum COLOR_ATTACHMENT7 = 0x8CE7;
+ const GLenum COLOR_ATTACHMENT8 = 0x8CE8;
+ const GLenum COLOR_ATTACHMENT9 = 0x8CE9;
+ const GLenum COLOR_ATTACHMENT10 = 0x8CEA;
+ const GLenum COLOR_ATTACHMENT11 = 0x8CEB;
+ const GLenum COLOR_ATTACHMENT12 = 0x8CEC;
+ const GLenum COLOR_ATTACHMENT13 = 0x8CED;
+ const GLenum COLOR_ATTACHMENT14 = 0x8CEE;
+ const GLenum COLOR_ATTACHMENT15 = 0x8CEF;
+ const GLenum FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56;
+ const GLenum MAX_SAMPLES = 0x8D57;
+ const GLenum HALF_FLOAT = 0x140B;
+ const GLenum RG = 0x8227;
+ const GLenum RG_INTEGER = 0x8228;
+ const GLenum R8 = 0x8229;
+ const GLenum RG8 = 0x822B;
+ const GLenum R16F = 0x822D;
+ const GLenum R32F = 0x822E;
+ const GLenum RG16F = 0x822F;
+ const GLenum RG32F = 0x8230;
+ const GLenum R8I = 0x8231;
+ const GLenum R8UI = 0x8232;
+ const GLenum R16I = 0x8233;
+ const GLenum R16UI = 0x8234;
+ const GLenum R32I = 0x8235;
+ const GLenum R32UI = 0x8236;
+ const GLenum RG8I = 0x8237;
+ const GLenum RG8UI = 0x8238;
+ const GLenum RG16I = 0x8239;
+ const GLenum RG16UI = 0x823A;
+ const GLenum RG32I = 0x823B;
+ const GLenum RG32UI = 0x823C;
+ const GLenum VERTEX_ARRAY_BINDING = 0x85B5;
+ const GLenum R8_SNORM = 0x8F94;
+ const GLenum RG8_SNORM = 0x8F95;
+ const GLenum RGB8_SNORM = 0x8F96;
+ const GLenum RGBA8_SNORM = 0x8F97;
+ const GLenum SIGNED_NORMALIZED = 0x8F9C;
+ const GLenum PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69;
+ const GLenum COPY_READ_BUFFER = 0x8F36;
+ const GLenum COPY_WRITE_BUFFER = 0x8F37;
+ const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; /* Same as COPY_READ_BUFFER */
+ const GLenum COPY_WRITE_BUFFER_BINDING = 0x8F37; /* Same as COPY_WRITE_BUFFER */
+ const GLenum UNIFORM_BUFFER = 0x8A11;
+ const GLenum UNIFORM_BUFFER_BINDING = 0x8A28;
+ const GLenum UNIFORM_BUFFER_START = 0x8A29;
+ const GLenum UNIFORM_BUFFER_SIZE = 0x8A2A;
+ const GLenum MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B;
+ const GLenum MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D;
+ const GLenum MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E;
+ const GLenum MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F;
+ const GLenum MAX_UNIFORM_BLOCK_SIZE = 0x8A30;
+ const GLenum MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31;
+ const GLenum MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33;
+ const GLenum UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34;
+ const GLenum ACTIVE_UNIFORM_BLOCKS = 0x8A36;
+ const GLenum UNIFORM_TYPE = 0x8A37;
+ const GLenum UNIFORM_SIZE = 0x8A38;
+ const GLenum UNIFORM_BLOCK_INDEX = 0x8A3A;
+ const GLenum UNIFORM_OFFSET = 0x8A3B;
+ const GLenum UNIFORM_ARRAY_STRIDE = 0x8A3C;
+ const GLenum UNIFORM_MATRIX_STRIDE = 0x8A3D;
+ const GLenum UNIFORM_IS_ROW_MAJOR = 0x8A3E;
+ const GLenum UNIFORM_BLOCK_BINDING = 0x8A3F;
+ const GLenum UNIFORM_BLOCK_DATA_SIZE = 0x8A40;
+ const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42;
+ const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43;
+ const GLenum UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44;
+ const GLenum UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
+ const GLenum INVALID_INDEX = 0xFFFFFFFF;
+ const GLenum MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122;
+ const GLenum MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125;
+ const GLenum MAX_SERVER_WAIT_TIMEOUT = 0x9111;
+ const GLenum OBJECT_TYPE = 0x9112;
+ const GLenum SYNC_CONDITION = 0x9113;
+ const GLenum SYNC_STATUS = 0x9114;
+ const GLenum SYNC_FLAGS = 0x9115;
+ const GLenum SYNC_FENCE = 0x9116;
+ const GLenum SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
+ const GLenum UNSIGNALED = 0x9118;
+ const GLenum SIGNALED = 0x9119;
+ const GLenum ALREADY_SIGNALED = 0x911A;
+ const GLenum TIMEOUT_EXPIRED = 0x911B;
+ const GLenum CONDITION_SATISFIED = 0x911C;
+ const GLenum WAIT_FAILED = 0x911D;
+ const GLenum SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
+ const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
+ const GLenum ANY_SAMPLES_PASSED = 0x8C2F;
+ const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
+ const GLenum SAMPLER_BINDING = 0x8919;
+ const GLenum RGB10_A2UI = 0x906F;
+ const GLenum TEXTURE_SWIZZLE_R = 0x8E42;
+ const GLenum TEXTURE_SWIZZLE_G = 0x8E43;
+ const GLenum TEXTURE_SWIZZLE_B = 0x8E44;
+ const GLenum TEXTURE_SWIZZLE_A = 0x8E45;
+ const GLenum GREEN = 0x1904;
+ const GLenum BLUE = 0x1905;
+ const GLenum INT_2_10_10_10_REV = 0x8D9F;
+ const GLenum TRANSFORM_FEEDBACK = 0x8E22;
+ const GLenum TRANSFORM_FEEDBACK_PAUSED = 0x8E23;
+ const GLenum TRANSFORM_FEEDBACK_ACTIVE = 0x8E24;
+ const GLenum TRANSFORM_FEEDBACK_BINDING = 0x8E25;
+ const GLenum COMPRESSED_R11_EAC = 0x9270;
+ const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271;
+ const GLenum COMPRESSED_RG11_EAC = 0x9272;
+ const GLenum COMPRESSED_SIGNED_RG11_EAC = 0x9273;
+ const GLenum COMPRESSED_RGB8_ETC2 = 0x9274;
+ const GLenum COMPRESSED_SRGB8_ETC2 = 0x9275;
+ const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
+ const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
+ const GLenum COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
+ const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
+ const GLenum TEXTURE_IMMUTABLE_FORMAT = 0x912F;
+ const GLenum MAX_ELEMENT_INDEX = 0x8D6B;
+ const GLenum NUM_SAMPLE_COUNTS = 0x9380;
+ const GLenum TEXTURE_IMMUTABLE_LEVELS = 0x82DF;
+ const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
+
+ const GLuint64 TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFF;
+
+ /* Buffer objects */
+ // WebGL1:
+ void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ void bufferData(GLenum target, BufferDataSource? srcData, GLenum usage);
+ void bufferSubData(GLenum target, GLintptr dstByteOffset, BufferDataSource? srcData);
+ // WebGL2:
+ void bufferData(GLenum target, ArrayBufferView data, GLenum usage, GLuint srcOffset, optional GLuint length = 0);
+ void bufferSubData(GLenum target, GLintptr dstByteOffset, ArrayBufferView srcData, GLuint srcOffset, optional GLuint length = 0);
+
+ void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ // MapBufferRange, in particular its read-only and write-only modes,
+ // can not be exposed safely to JavaScript. GetBufferSubData
+ // replaces it for the purpose of fetching data back from the GPU.
+ void getBufferSubData(GLenum target, GLintptr srcByteOffset, ArrayBufferView dstData, optional GLuint dstOffset = 0, optional GLuint length = 0);
+
+ /* Framebuffer objects */
+ void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ void framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ [OverrideIDLType=IDLWebGLAny] any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
+ void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
+ void invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ void readBuffer(GLenum src);
+
+ /* Renderbuffer objects */
+ void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+ /* Texture objects */
+ void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
+
+ void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ArrayBufferView? pixels);
+ void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, TexImageSource source);
+
+ void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, ArrayBufferView? data);
+ void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, ArrayBufferView? data);
+
+ /* Programs and shaders */
+ GLint getFragDataLocation(WebGLProgram? program, DOMString name);
+
+ /* Uniforms and attributes */
+ void uniform1ui(WebGLUniformLocation? location, GLuint v0);
+ void uniform2ui(WebGLUniformLocation? location, GLuint v0, GLuint v1);
+ void uniform3ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2);
+ void uniform4ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void uniform1uiv(WebGLUniformLocation? location, Uint32Array? value);
+ void uniform2uiv(WebGLUniformLocation? location, Uint32Array? value);
+ void uniform3uiv(WebGLUniformLocation? location, Uint32Array? value);
+ void uniform4uiv(WebGLUniformLocation? location, Uint32Array? value);
+ void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array? value);
+ void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ void vertexAttribI4iv(GLuint index, Int32Array? v);
+ void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void vertexAttribI4uiv(GLuint index, Uint32Array? v);
+ void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+
+ /* Writing to the drawing buffer */
+ void vertexAttribDivisor(GLuint index, GLuint divisor);
+ void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+ void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount);
+ void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset);
+
+ /* Multiple Render Targets */
+ void drawBuffers(sequence<GLenum> buffers);
+ void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32Array? value);
+ void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32Array? value);
+ void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32Array? value);
+ void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+
+ /* Query Objects */
+ WebGLQuery createQuery();
+ void deleteQuery(WebGLQuery? query);
+ GLboolean isQuery(WebGLQuery? query);
+ void beginQuery(GLenum target, WebGLQuery? query);
+ void endQuery(GLenum target);
+ WebGLQuery getQuery(GLenum target, GLenum pname);
+ [OverrideIDLType=IDLWebGLAny] any getQueryParameter(WebGLQuery? query, GLenum pname);
+
+ /* Sampler Objects */
+ WebGLSampler createSampler();
+ void deleteSampler(WebGLSampler? sampler);
+ GLboolean isSampler(WebGLSampler? sampler);
+ void bindSampler(GLuint unit, WebGLSampler? sampler);
+ void samplerParameteri(WebGLSampler? sampler, GLenum pname, GLint param);
+ void samplerParameterf(WebGLSampler? sampler, GLenum pname, GLfloat param);
+ [OverrideIDLType=IDLWebGLAny] any getSamplerParameter(WebGLSampler? sampler, GLenum pname);
+
+ /* Sync objects */
+ WebGLSync fenceSync(GLenum condition, GLbitfield flags);
+ GLboolean isSync(WebGLSync? sync);
+ void deleteSync(WebGLSync? sync);
+ GLenum clientWaitSync(WebGLSync? sync, GLbitfield flags, GLuint64 timeout);
+ void waitSync(WebGLSync? sync, GLbitfield flags, GLuint64 timeout);
+ [OverrideIDLType=IDLWebGLAny] any getSyncParameter(WebGLSync? sync, GLenum pname);
+
+ /* Transform Feedback */
+ WebGLTransformFeedback createTransformFeedback();
+ void deleteTransformFeedback(WebGLTransformFeedback? id);
+ GLboolean isTransformFeedback(WebGLTransformFeedback? id);
+ void bindTransformFeedback(GLenum target, WebGLTransformFeedback? id);
+ void beginTransformFeedback(GLenum primitiveMode);
+ void endTransformFeedback();
+ void transformFeedbackVaryings(WebGLProgram? program, sequence<DOMString> varyings, GLenum bufferMode);
+ WebGLActiveInfo getTransformFeedbackVarying(WebGLProgram? program, GLuint index);
+ void pauseTransformFeedback();
+ void resumeTransformFeedback();
+
+ /* Uniform Buffer Objects and Transform Feedback Buffers */
+ void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
+ void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size);
+ [OverrideIDLType=IDLWebGLAny] any getIndexedParameter(GLenum target, GLuint index);
+ Uint32Array getUniformIndices(WebGLProgram? program, sequence<DOMString> uniformNames);
+ Int32Array getActiveUniforms(WebGLProgram? program, Uint32Array? uniformIndices, GLenum pname);
+ GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName);
+ [OverrideIDLType=IDLWebGLAny] any getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
+ [OverrideIDLType=IDLWebGLAny] any getActiveUniformBlockName(WebGLProgram? program, GLuint uniformBlockIndex);
+ void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+ /* Vertex Array Objects */
+ WebGLVertexArrayObject createVertexArray();
+ void deleteVertexArray(WebGLVertexArrayObject? vertexArray);
+ GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray);
+ void bindVertexArray(WebGLVertexArrayObject? vertexArray);
+};
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.h b/Source/WebCore/html/canvas/WebGLActiveInfo.h
index 0938a2366..843cb73a2 100644
--- a/Source/WebCore/html/canvas/WebGLActiveInfo.h
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.h
@@ -23,11 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLActiveInfo_h
-#define WebGLActiveInfo_h
+#pragma once
#include "GraphicsContext3D.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
@@ -35,9 +33,9 @@ namespace WebCore {
class WebGLActiveInfo : public RefCounted<WebGLActiveInfo> {
public:
- static PassRefPtr<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
+ static Ref<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
{
- return adoptRef(new WebGLActiveInfo(name, type, size));
+ return adoptRef(*new WebGLActiveInfo(name, type, size));
}
String name() const { return m_name; }
GC3Denum type() const { return m_type; }
@@ -58,6 +56,4 @@ private:
GC3Dint m_size;
};
-}
-
-#endif // WebGLActiveInfo_h
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLAny.cpp b/Source/WebCore/html/canvas/WebGLAny.cpp
new file mode 100644
index 000000000..75ce05139
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLAny.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 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 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 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.
+ */
+
+#include "config.h"
+#include "WebGLAny.h"
+
+#if ENABLE(WEBGL)
+
+#include "JSDOMConvert.h"
+#include "JSWebGLBuffer.h"
+#include "JSWebGLFramebuffer.h"
+#include "JSWebGLProgram.h"
+#include "JSWebGLRenderbuffer.h"
+#include "JSWebGLTexture.h"
+#include "JSWebGLVertexArrayObjectOES.h"
+#include <wtf/Variant.h>
+
+#if ENABLE(WEBGL2)
+#include "JSWebGLVertexArrayObject.h"
+#endif
+
+namespace WebCore {
+
+using namespace JSC;
+
+// FIXME: This should use the IDLUnion JSConverter.
+JSValue convertToJSValue(ExecState& state, JSDOMGlobalObject& globalObject, const WebGLAny& any)
+{
+ return WTF::switchOn(any,
+ [] (std::nullptr_t) {
+ return jsNull();
+ },
+ [] (bool value) {
+ return jsBoolean(value);
+ },
+ [] (int value) {
+ return jsNumber(value);
+ },
+ [] (unsigned value) {
+ return jsNumber(value);
+ },
+ [] (long long value) {
+ return jsNumber(value);
+ },
+ [] (float value) {
+ return jsNumber(value);
+ },
+ [&] (const String& value) {
+ return jsStringWithCache(&state, value);
+ },
+ [&] (const Vector<bool>& values) {
+ MarkedArgumentBuffer list;
+ for (auto& value : values)
+ list.append(jsBoolean(value));
+ return constructArray(&state, 0, &globalObject, list);
+ },
+ [&] (const RefPtr<Float32Array>& array) {
+ return toJS(&state, &globalObject, array.get());
+ },
+ [&] (const RefPtr<Int32Array>& array) {
+ return toJS(&state, &globalObject, array.get());
+ },
+ [&] (const RefPtr<Uint8Array>& array) {
+ return toJS(&state, &globalObject, array.get());
+ },
+ [&] (const RefPtr<Uint32Array>& array) {
+ return toJS(&state, &globalObject, array.get());
+ },
+ [&] (const RefPtr<WebGLBuffer>& buffer) {
+ return toJS(&state, &globalObject, buffer.get());
+ },
+ [&] (const RefPtr<WebGLFramebuffer>& buffer) {
+ return toJS(&state, &globalObject, buffer.get());
+ },
+ [&] (const RefPtr<WebGLProgram>& program) {
+ return toJS(&state, &globalObject, program.get());
+ },
+ [&] (const RefPtr<WebGLRenderbuffer>& buffer) {
+ return toJS(&state, &globalObject, buffer.get());
+ },
+ [&] (const RefPtr<WebGLTexture>& texture) {
+ return toJS(&state, &globalObject, texture.get());
+ },
+ [&] (const RefPtr<WebGLVertexArrayObjectOES>& array) {
+ return toJS(&state, &globalObject, array.get());
+ }
+#if ENABLE(WEBGL2)
+ ,
+ [&] (const RefPtr<WebGLVertexArrayObject>& array) {
+ return toJS(&state, &globalObject, array.get());
+ }
+#endif
+ );
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/canvas/WebGLAny.h b/Source/WebCore/html/canvas/WebGLAny.h
new file mode 100644
index 000000000..c773b080b
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLAny.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 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 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 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGL)
+
+#include <runtime/Float32Array.h>
+#include <runtime/Int32Array.h>
+#include <runtime/Uint32Array.h>
+#include <runtime/Uint8Array.h>
+
+namespace JSC {
+class ExecState;
+class JSValue;
+}
+
+namespace WebCore {
+
+class JSDOMGlobalObject;
+class WebGLBuffer;
+class WebGLFramebuffer;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLTexture;
+class WebGLVertexArrayObject;
+class WebGLVertexArrayObjectOES;
+
+using WebGLAny = Variant<
+ std::nullptr_t,
+ bool,
+ int,
+ unsigned,
+ long long,
+ float,
+ String,
+ Vector<bool>,
+ RefPtr<Float32Array>,
+ RefPtr<Int32Array>,
+ RefPtr<Uint32Array>,
+ RefPtr<Uint8Array>,
+ RefPtr<WebGLBuffer>,
+ RefPtr<WebGLFramebuffer>,
+ RefPtr<WebGLProgram>,
+ RefPtr<WebGLRenderbuffer>,
+ RefPtr<WebGLTexture>,
+ RefPtr<WebGLVertexArrayObjectOES>
+#if ENABLE(WEBGL2)
+ , RefPtr<WebGLVertexArrayObject>
+#endif
+>;
+
+JSC::JSValue convertToJSValue(JSC::ExecState&, JSDOMGlobalObject&, const WebGLAny&);
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
index 3421e979c..bc914a4a7 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,28 +24,24 @@
*/
#include "config.h"
+#include "WebGLBuffer.h"
#if ENABLE(WEBGL)
-#include "WebGLBuffer.h"
-
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+Ref<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLBuffer(ctx));
+ return adoptRef(*new WebGLBuffer(ctx));
}
-WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase& ctx)
: WebGLSharedObject(ctx)
- , m_target(0)
- , m_byteLength(0)
- , m_nextAvailableCacheEntry(0)
{
- setObject(ctx->graphicsContext3D()->createBuffer());
+ setObject(ctx.graphicsContext3D()->createBuffer());
clearCachedMaxIndices();
}
@@ -56,7 +52,7 @@ WebGLBuffer::~WebGLBuffer()
void WebGLBuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- context3d->deleteBuffer(object);
+ context3d->deleteBuffer(object);
}
bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLength)
@@ -69,7 +65,7 @@ bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLen
m_byteLength = byteLength;
clearCachedMaxIndices();
if (byteLength) {
- m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1);
+ m_elementArrayBuffer = ArrayBuffer::tryCreate(byteLength, 1);
if (!m_elementArrayBuffer) {
m_byteLength = 0;
return false;
@@ -81,19 +77,31 @@ bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLen
memcpy(m_elementArrayBuffer->data(), data, byteLength);
}
} else
- m_elementArrayBuffer = 0;
+ m_elementArrayBuffer = nullptr;
return true;
case GraphicsContext3D::ARRAY_BUFFER:
m_byteLength = byteLength;
return true;
default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ m_byteLength = byteLength;
+ return true;
+ }
+#endif
return false;
}
}
bool WebGLBuffer::associateBufferData(GC3Dsizeiptr size)
{
- return associateBufferDataImpl(0, size);
+ return associateBufferDataImpl(nullptr, size);
}
bool WebGLBuffer::associateBufferData(ArrayBuffer* array)
@@ -135,6 +143,17 @@ bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, const void* data
case GraphicsContext3D::ARRAY_BUFFER:
return true;
default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ return true;
+ }
+#endif
return false;
}
}
@@ -153,39 +172,104 @@ bool WebGLBuffer::associateBufferSubData(GC3Dintptr offset, ArrayBufferView* arr
return associateBufferSubDataImpl(offset, array->baseAddress(), array->byteLength());
}
+bool WebGLBuffer::associateCopyBufferSubData(const WebGLBuffer& readBuffer, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr size)
+{
+ if (readOffset < 0 || writeOffset < 0 || size < 0)
+ return false;
+
+ if (size) {
+ Checked<GC3Dintptr, RecordOverflow> checkedReadBufferOffset(readOffset);
+ Checked<GC3Dsizeiptr, RecordOverflow> checkedDataLength(size);
+ Checked<GC3Dintptr, RecordOverflow> checkedReadBufferMax = checkedReadBufferOffset + checkedDataLength;
+ if (checkedReadBufferMax.hasOverflowed() || readOffset > readBuffer.byteLength() || checkedReadBufferMax.unsafeGet() > readBuffer.byteLength())
+ return false;
+
+ Checked<GC3Dintptr, RecordOverflow> checkedWriteBufferOffset(writeOffset);
+ Checked<GC3Dintptr, RecordOverflow> checkedWriteBufferMax = checkedWriteBufferOffset + checkedDataLength;
+ if (checkedWriteBufferMax.hasOverflowed() || writeOffset > m_byteLength || checkedWriteBufferMax.unsafeGet() > m_byteLength)
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ clearCachedMaxIndices();
+ if (size) {
+ if (!m_elementArrayBuffer)
+ return false;
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + writeOffset, static_cast<const unsigned char*>(readBuffer.elementArrayBuffer()->data()) + readOffset, size);
+ }
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ return true;
+ default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ return true;
+ }
+#endif
+ return false;
+ }
+}
+
+void WebGLBuffer::disassociateBufferData()
+{
+ m_byteLength = 0;
+ clearCachedMaxIndices();
+}
+
GC3Dsizeiptr WebGLBuffer::byteLength() const
{
return m_byteLength;
}
-int WebGLBuffer::getCachedMaxIndex(GC3Denum type)
+std::optional<unsigned> WebGLBuffer::getCachedMaxIndex(GC3Denum type)
{
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_maxIndexCache); ++i)
- if (m_maxIndexCache[i].type == type)
- return m_maxIndexCache[i].maxIndex;
- return -1;
+ for (auto& cache : m_maxIndexCache) {
+ if (cache.type == type)
+ return cache.maxIndex;
+ }
+ return std::nullopt;
}
-void WebGLBuffer::setCachedMaxIndex(GC3Denum type, int value)
+void WebGLBuffer::setCachedMaxIndex(GC3Denum type, unsigned value)
{
- size_t numEntries = WTF_ARRAY_LENGTH(m_maxIndexCache);
- for (size_t i = 0; i < numEntries; ++i)
- if (m_maxIndexCache[i].type == type) {
- m_maxIndexCache[i].maxIndex = value;
+ for (auto& cache : m_maxIndexCache) {
+ if (cache.type == type) {
+ cache.maxIndex = value;
return;
}
+ }
m_maxIndexCache[m_nextAvailableCacheEntry].type = type;
m_maxIndexCache[m_nextAvailableCacheEntry].maxIndex = value;
- m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % numEntries;
+ m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % WTF_ARRAY_LENGTH(m_maxIndexCache);
}
-void WebGLBuffer::setTarget(GC3Denum target)
+void WebGLBuffer::setTarget(GC3Denum target, bool forWebGL2)
{
// In WebGL, a buffer is bound to one target in its lifetime
if (m_target)
return;
if (target == GraphicsContext3D::ARRAY_BUFFER || target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
m_target = target;
+ else if (forWebGL2) {
+#if ENABLE(WEBGL2)
+ switch (target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ m_target = target;
+ }
+#endif
+ }
}
void WebGLBuffer::clearCachedMaxIndices()
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h
index 3451bb68c..7b9ea55f0 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.h
+++ b/Source/WebCore/html/canvas/WebGLBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,11 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLBuffer_h
-#define WebGLBuffer_h
+#pragma once
#include "WebGLSharedObject.h"
-
#include <wtf/Forward.h>
namespace JSC {
@@ -37,44 +35,43 @@ class ArrayBufferView;
namespace WebCore {
-class WebGLBuffer : public WebGLSharedObject {
+class WebGLBuffer final : public WebGLSharedObject {
public:
+ static Ref<WebGLBuffer> create(WebGLRenderingContextBase&);
virtual ~WebGLBuffer();
- static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
-
bool associateBufferData(GC3Dsizeiptr size);
bool associateBufferData(JSC::ArrayBuffer*);
bool associateBufferData(JSC::ArrayBufferView*);
bool associateBufferSubData(GC3Dintptr offset, JSC::ArrayBuffer*);
bool associateBufferSubData(GC3Dintptr offset, JSC::ArrayBufferView*);
+ bool associateCopyBufferSubData(const WebGLBuffer& readBuffer, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr);
+
+ void disassociateBufferData();
GC3Dsizeiptr byteLength() const;
const JSC::ArrayBuffer* elementArrayBuffer() const { return m_elementArrayBuffer.get(); }
- // Gets the cached max index for the given type. Returns -1 if
- // none has been set.
- int getCachedMaxIndex(GC3Denum type);
+ // Gets the cached max index for the given type if one has been set.
+ std::optional<unsigned> getCachedMaxIndex(GC3Denum type);
// Sets the cached max index for the given type.
- void setCachedMaxIndex(GC3Denum type, int value);
+ void setCachedMaxIndex(GC3Denum type, unsigned value);
GC3Denum getTarget() const { return m_target; }
- void setTarget(GC3Denum);
+ void setTarget(GC3Denum, bool forWebGL2);
bool hasEverBeenBound() const { return object() && m_target; }
protected:
- WebGLBuffer(WebGLRenderingContext*);
+ WebGLBuffer(WebGLRenderingContextBase&);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
private:
- virtual bool isBuffer() const override { return true; }
-
- GC3Denum m_target;
+ GC3Denum m_target { 0 };
RefPtr<JSC::ArrayBuffer> m_elementArrayBuffer;
- GC3Dsizeiptr m_byteLength;
+ GC3Dsizeiptr m_byteLength { 0 };
// Optimization for index validation. For each type of index
// (i.e., UNSIGNED_SHORT), cache the maximum index in the
@@ -85,13 +82,12 @@ private:
// that size.
struct MaxIndexCacheEntry {
GC3Denum type;
- int maxIndex;
+ unsigned maxIndex;
};
// OpenGL ES 2.0 only has two valid index types (UNSIGNED_BYTE
- // and UNSIGNED_SHORT), but might as well leave open the
- // possibility of adding others.
+ // and UNSIGNED_SHORT) plus one extension (UNSIGNED_INT).
MaxIndexCacheEntry m_maxIndexCache[4];
- unsigned int m_nextAvailableCacheEntry;
+ unsigned m_nextAvailableCacheEntry { 0 };
// Clears all of the cached max indices.
void clearCachedMaxIndices();
@@ -103,5 +99,3 @@ private:
};
} // namespace WebCore
-
-#endif // WebGLBuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.idl b/Source/WebCore/html/canvas/WebGLBuffer.idl
index f43cd6353..6e2ab9c57 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLBuffer.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
index 71881ba09..eef19d375 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
@@ -33,12 +33,12 @@
namespace WebCore {
-WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContext* context)
+WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGB_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGB_AMD);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
}
WebGLCompressedTextureATC::~WebGLCompressedTextureATC()
@@ -50,15 +50,9 @@ WebGLExtension::ExtensionName WebGLCompressedTextureATC::getName() const
return WebGLCompressedTextureATCName;
}
-OwnPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContext* context)
+bool WebGLCompressedTextureATC::supported(WebGLRenderingContextBase& context)
{
- return adoptPtr(new WebGLCompressedTextureATC(context));
-}
-
-bool WebGLCompressedTextureATC::supported(WebGLRenderingContext* context)
-{
- Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return extensions->supports("GL_AMD_compressed_ATC_texture");
+ return context.graphicsContext3D()->getExtensions().supports("GL_AMD_compressed_ATC_texture");
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
index 6a8d89d5d..e5b0560d3 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
@@ -23,29 +23,22 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLCompressedTextureATC_h
-#define WebGLCompressedTextureATC_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureATC : public WebGLExtension {
+class WebGLCompressedTextureATC final : public WebGLExtension {
public:
- static OwnPtr<WebGLCompressedTextureATC> create(WebGLRenderingContext*);
-
- static bool supported(WebGLRenderingContext*);
-
+ explicit WebGLCompressedTextureATC(WebGLRenderingContextBase&);
virtual ~WebGLCompressedTextureATC();
- virtual ExtensionName getName() const override;
-private:
- WebGLCompressedTextureATC(WebGLRenderingContext*);
+ static bool supported(WebGLRenderingContextBase&);
+
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // WebGLCompressedTextureATC_h
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.idl b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.idl
index ff415a756..ffd8d22e0 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.idl
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.idl
@@ -24,13 +24,12 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface WebGLCompressedTextureATC {
- /* Compressed Texture Formats */
- const unsigned int COMPRESSED_RGB_ATC_WEBGL = 0x8C92;
- const unsigned int COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93;
- const unsigned int COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
+ const unsigned long COMPRESSED_RGB_ATC_WEBGL = 0x8C92;
+ const unsigned long COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93;
+ const unsigned long COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
};
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
index d05d4178b..14b66f5fc 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
@@ -30,17 +30,17 @@
#include "WebGLCompressedTexturePVRTC.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContext* context)
+WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
}
WebGLCompressedTexturePVRTC::~WebGLCompressedTexturePVRTC()
@@ -52,15 +52,9 @@ WebGLExtension::ExtensionName WebGLCompressedTexturePVRTC::getName() const
return WebGLCompressedTexturePVRTCName;
}
-OwnPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContext* context)
+bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContextBase& context)
{
- return adoptPtr(new WebGLCompressedTexturePVRTC(context));
-}
-
-bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContext* context)
-{
- Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return extensions->supports("GL_IMG_texture_compression_pvrtc");
+ return context.graphicsContext3D()->getExtensions().supports("GL_IMG_texture_compression_pvrtc");
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
index f20e2d25d..515e6e11f 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
@@ -23,27 +23,19 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLCompressedTexturePVRTC_h
-#define WebGLCompressedTexturePVRTC_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLCompressedTexturePVRTC : public WebGLExtension {
+class WebGLCompressedTexturePVRTC final : public WebGLExtension {
public:
- static OwnPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContext*);
-
- static bool supported(WebGLRenderingContext*);
-
+ explicit WebGLCompressedTexturePVRTC(WebGLRenderingContextBase&);
virtual ~WebGLCompressedTexturePVRTC();
- virtual ExtensionName getName() const override;
-private:
- WebGLCompressedTexturePVRTC(WebGLRenderingContext*);
+ static bool supported(WebGLRenderingContextBase&);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // WebGLCompressedTexturePVRTC_h
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.idl b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.idl
index 5b61a20a2..2cfbf3131 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.idl
+++ b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.idl
@@ -24,14 +24,13 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface WebGLCompressedTexturePVRTC {
- /* Compressed Texture Formats */
- const unsigned int COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
- const unsigned int COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
- const unsigned int COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
- const unsigned int COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
+ const unsigned long COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+ const unsigned long COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
+ const unsigned long COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+ const unsigned long COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
};
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
index bcf1a3267..40b7f53a8 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
@@ -30,17 +30,17 @@
#include "WebGLCompressedTextureS3TC.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContext* context)
+WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
WebGLCompressedTextureS3TC::~WebGLCompressedTextureS3TC()
@@ -52,18 +52,11 @@ WebGLExtension::ExtensionName WebGLCompressedTextureS3TC::getName() const
return WebGLCompressedTextureS3TCName;
}
-OwnPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContext* context)
+bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase& context)
{
- return adoptPtr(new WebGLCompressedTextureS3TC(context));
-}
-
-bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context)
-{
- Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return extensions->supports("GL_EXT_texture_compression_s3tc")
- || (extensions->supports("GL_EXT_texture_compression_dxt1")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt3")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt5"));
+ auto& extensions = context.graphicsContext3D()->getExtensions();
+ return extensions.supports("GL_EXT_texture_compression_s3tc")
+ || extensions.supports("GL_EXT_texture_compression_dxt1");
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
index c6c9edb45..251e592f7 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
@@ -23,29 +23,22 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLCompressedTextureS3TC_h
-#define WebGLCompressedTextureS3TC_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureS3TC : public WebGLExtension {
+class WebGLCompressedTextureS3TC final : public WebGLExtension {
public:
- static OwnPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContext*);
-
- static bool supported(WebGLRenderingContext*);
-
+ explicit WebGLCompressedTextureS3TC(WebGLRenderingContextBase&);
virtual ~WebGLCompressedTextureS3TC();
- virtual ExtensionName getName() const override;
-private:
- WebGLCompressedTextureS3TC(WebGLRenderingContext*);
+ static bool supported(WebGLRenderingContextBase&);
+
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // WebGLCompressedTextureS3TC_h
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.idl b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.idl
index e77303bde..f9718b839 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.idl
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.idl
@@ -24,14 +24,13 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface WebGLCompressedTextureS3TC {
- /* Compressed Texture Formats */
- const unsigned int COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
- const unsigned int COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
- const unsigned int COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
- const unsigned int COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
+ const unsigned long COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
+ const unsigned long COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
+ const unsigned long COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
+ const unsigned long COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
};
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
deleted file mode 100644
index e36e04ef0..000000000
--- a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2010, Google 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:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-
-#include "WebGLContextAttributes.h"
-
-namespace WebCore {
-
-PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
-{
- return adoptRef(new WebGLContextAttributes());
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
-{
- return adoptRef(new WebGLContextAttributes(attributes));
-}
-
-WebGLContextAttributes::WebGLContextAttributes()
- : CanvasContextAttributes()
-{
-}
-
-WebGLContextAttributes::WebGLContextAttributes(GraphicsContext3D::Attributes attributes)
- : CanvasContextAttributes()
- , m_attrs(attributes)
-{
-}
-
-WebGLContextAttributes::~WebGLContextAttributes()
-{
-}
-
-bool WebGLContextAttributes::alpha() const
-{
- return m_attrs.alpha;
-}
-
-void WebGLContextAttributes::setAlpha(bool alpha)
-{
- m_attrs.alpha = alpha;
-}
-
-bool WebGLContextAttributes::depth() const
-{
- return m_attrs.depth;
-}
-
-void WebGLContextAttributes::setDepth(bool depth)
-{
- m_attrs.depth = depth;
-}
-
-bool WebGLContextAttributes::stencil() const
-{
- return m_attrs.stencil;
-}
-
-void WebGLContextAttributes::setStencil(bool stencil)
-{
- m_attrs.stencil = stencil;
-}
-
-bool WebGLContextAttributes::antialias() const
-{
- return m_attrs.antialias;
-}
-
-void WebGLContextAttributes::setAntialias(bool antialias)
-{
- m_attrs.antialias = antialias;
-}
-
-bool WebGLContextAttributes::premultipliedAlpha() const
-{
- return m_attrs.premultipliedAlpha;
-}
-
-void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha)
-{
- m_attrs.premultipliedAlpha = premultipliedAlpha;
-}
-
-bool WebGLContextAttributes::preserveDrawingBuffer() const
-{
- return m_attrs.preserveDrawingBuffer;
-}
-
-void WebGLContextAttributes::setPreserveDrawingBuffer(bool preserveDrawingBuffer)
-{
- m_attrs.preserveDrawingBuffer = preserveDrawingBuffer;
-}
-
-GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const
-{
- return m_attrs;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.h b/Source/WebCore/html/canvas/WebGLContextAttributes.h
index 5391a2b7d..a36dc9b07 100644
--- a/Source/WebCore/html/canvas/WebGLContextAttributes.h
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (c) 2016 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
@@ -24,64 +25,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLContextAttributes_h
-#define WebGLContextAttributes_h
+#pragma once
-#include "CanvasContextAttributes.h"
-#include "GraphicsContext3D.h"
-#include <wtf/PassRefPtr.h>
+#include "GraphicsContext3DAttributes.h"
namespace WebCore {
-class WebGLContextAttributes : public CanvasContextAttributes {
- public:
- virtual ~WebGLContextAttributes();
-
- // Create a new attributes object
- static PassRefPtr<WebGLContextAttributes> create();
-
- // Create a new attributes object initialized with preexisting attributes
- static PassRefPtr<WebGLContextAttributes> create(GraphicsContext3D::Attributes attributes);
-
- // Whether or not the drawing buffer has an alpha channel; default=true
- bool alpha() const;
- void setAlpha(bool alpha);
-
- // Whether or not the drawing buffer has a depth buffer; default=true
- bool depth() const;
- void setDepth(bool depth);
-
- // Whether or not the drawing buffer has a stencil buffer; default=true
- bool stencil() const;
- void setStencil(bool stencil);
-
- // Whether or not the drawing buffer is antialiased; default=true
- bool antialias() const;
- void setAntialias(bool antialias);
-
- // Whether or not to treat the values in the drawing buffer as
- // though their alpha channel has already been multiplied into the
- // color channels; default=true
- bool premultipliedAlpha() const;
- void setPremultipliedAlpha(bool premultipliedAlpha);
-
- // Whether or not to preserve the drawing buffer after presentation to the
- // screen; default=false
- bool preserveDrawingBuffer() const;
- void setPreserveDrawingBuffer(bool);
-
- // Fetches a copy of the attributes stored in this object in a
- // form that can be used to initialize a GraphicsContext3D.
- GraphicsContext3D::Attributes attributes() const;
-
- protected:
- WebGLContextAttributes();
- WebGLContextAttributes(GraphicsContext3D::Attributes attributes);
-
- private:
- GraphicsContext3D::Attributes m_attrs;
-};
+using WebGLPowerPreference = GraphicsContext3DPowerPreference;
+using WebGLContextAttributes = GraphicsContext3DAttributes;
} // namespace WebCore
-
-#endif // WebGLContextAttributes_h
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.idl b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
index 41bf10234..3be5ac599 100644
--- a/Source/WebCore/html/canvas/WebGLContextAttributes.idl
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -24,14 +25,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+typedef boolean GLboolean;
+
+enum WebGLPowerPreference {
+ "default",
+ "low-power",
+ "high-performance"
+};
+
[
- NoInterfaceObject,
Conditional=WEBGL,
-] interface WebGLContextAttributes {
- attribute boolean alpha;
- attribute boolean depth;
- attribute boolean stencil;
- attribute boolean antialias;
- attribute boolean premultipliedAlpha;
- attribute boolean preserveDrawingBuffer;
+ JSGenerateToJSObject
+] dictionary WebGLContextAttributes {
+ GLboolean alpha = true;
+ GLboolean depth = true;
+ GLboolean stencil = false;
+ GLboolean antialias = true;
+ GLboolean premultipliedAlpha = true;
+ GLboolean preserveDrawingBuffer = false;
+ WebGLPowerPreference powerPreference = "default";
+ GLboolean failIfMajorPerformanceCaveat = false;
};
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.cpp b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
index 8e97fe349..13a12ee15 100644
--- a/Source/WebCore/html/canvas/WebGLContextEvent.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
@@ -26,28 +26,18 @@
#include "config.h"
#include "WebGLContextEvent.h"
-#include "EventNames.h"
-
#if ENABLE(WEBGL)
namespace WebCore {
-WebGLContextEventInit::WebGLContextEventInit()
-{
-}
-
-WebGLContextEvent::WebGLContextEvent()
-{
-}
-
WebGLContextEvent::WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
: Event(type, canBubble, cancelable)
, m_statusMessage(statusMessage)
{
}
-WebGLContextEvent::WebGLContextEvent(const AtomicString& type, const WebGLContextEventInit& initializer)
- : Event(type, initializer)
+WebGLContextEvent::WebGLContextEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
, m_statusMessage(initializer.statusMessage)
{
}
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.h b/Source/WebCore/html/canvas/WebGLContextEvent.h
index fa1ebfbc8..4ba1ba4d7 100644
--- a/Source/WebCore/html/canvas/WebGLContextEvent.h
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.h
@@ -23,47 +23,38 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLContextEvent_h
-#define WebGLContextEvent_h
+#pragma once
#include "Event.h"
namespace WebCore {
-struct WebGLContextEventInit : public EventInit {
- WebGLContextEventInit();
-
- String statusMessage;
-};
-
-class WebGLContextEvent : public Event {
+class WebGLContextEvent final : public Event {
public:
- static PassRefPtr<WebGLContextEvent> create()
- {
- return adoptRef(new WebGLContextEvent);
- }
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ static Ref<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
{
- return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ return adoptRef(*new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
}
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
+
+ struct Init : EventInit {
+ String statusMessage;
+ };
+
+ static Ref<WebGLContextEvent> create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted = IsTrusted::No)
{
- return adoptRef(new WebGLContextEvent(type, initializer));
+ return adoptRef(*new WebGLContextEvent(type, initializer, isTrusted));
}
virtual ~WebGLContextEvent();
const String& statusMessage() const { return m_statusMessage; }
- virtual EventInterface eventInterface() const override;
+ EventInterface eventInterface() const override;
private:
- WebGLContextEvent();
WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
- WebGLContextEvent(const AtomicString&, const WebGLContextEventInit&);
+ WebGLContextEvent(const AtomicString&, const Init&, IsTrusted);
String m_statusMessage;
};
} // namespace WebCore
-
-#endif // WebGLContextEvent_h
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.idl b/Source/WebCore/html/canvas/WebGLContextEvent.idl
index c3eba1029..3cd03b1c1 100644
--- a/Source/WebCore/html/canvas/WebGLContextEvent.idl
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.idl
@@ -25,8 +25,11 @@
[
Conditional=WEBGL,
- ConstructorTemplate=Event
+ Constructor(DOMString type, optional WebGLContextEventInit eventInit),
] interface WebGLContextEvent : Event {
- [InitializedByEventConstructor] readonly attribute DOMString statusMessage;
+ readonly attribute DOMString statusMessage;
};
+dictionary WebGLContextEventInit : EventInit {
+ DOMString statusMessage = "";
+};
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.cpp b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
index 6f182e22d..9ddef158c 100644
--- a/Source/WebCore/html/canvas/WebGLContextGroup.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,25 +24,19 @@
*/
#include "config.h"
+#include "WebGLContextGroup.h"
#if ENABLE(WEBGL)
-#include "WebGLContextGroup.h"
-
#include "GraphicsContext3D.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
#include "WebGLSharedObject.h"
namespace WebCore {
-PassRefPtr<WebGLContextGroup> WebGLContextGroup::create()
-{
- RefPtr<WebGLContextGroup> contextGroup = adoptRef(new WebGLContextGroup());
- return contextGroup.release();
-}
-
-WebGLContextGroup::WebGLContextGroup()
+Ref<WebGLContextGroup> WebGLContextGroup::create()
{
+ return adoptRef(*new WebGLContextGroup);
}
WebGLContextGroup::~WebGLContextGroup()
@@ -50,49 +44,46 @@ WebGLContextGroup::~WebGLContextGroup()
detachAndRemoveAllObjects();
}
-GraphicsContext3D* WebGLContextGroup::getAGraphicsContext3D()
+GraphicsContext3D& WebGLContextGroup::getAGraphicsContext3D()
{
ASSERT(!m_contexts.isEmpty());
- HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
- return (*it)->graphicsContext3D();
+ return *(*m_contexts.begin())->graphicsContext3D();
}
-void WebGLContextGroup::addContext(WebGLRenderingContext* context)
+void WebGLContextGroup::addContext(WebGLRenderingContextBase& context)
{
- m_contexts.add(context);
+ m_contexts.add(&context);
}
-void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
+void WebGLContextGroup::removeContext(WebGLRenderingContextBase& context)
{
// We must call detachAndRemoveAllObjects before removing the last context.
- if (m_contexts.size() == 1 && m_contexts.contains(context))
+ if (m_contexts.size() == 1 && m_contexts.contains(&context))
detachAndRemoveAllObjects();
- m_contexts.remove(context);
+ m_contexts.remove(&context);
}
-void WebGLContextGroup::removeObject(WebGLSharedObject* object)
+void WebGLContextGroup::removeObject(WebGLSharedObject& object)
{
- m_groupObjects.remove(object);
+ m_groupObjects.remove(&object);
}
-void WebGLContextGroup::addObject(WebGLSharedObject* object)
+void WebGLContextGroup::addObject(WebGLSharedObject& object)
{
- m_groupObjects.add(object);
+ m_groupObjects.add(&object);
}
void WebGLContextGroup::detachAndRemoveAllObjects()
{
- while (!m_groupObjects.isEmpty()) {
- HashSet<WebGLSharedObject*>::iterator it = m_groupObjects.begin();
- (*it)->detachContextGroup();
- }
+ while (!m_groupObjects.isEmpty())
+ (*m_groupObjects.begin())->detachContextGroup();
}
-void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContextBase::LostContextMode mode)
{
- for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
- (*it)->loseContextImpl(mode);
+ for (auto& context : m_contexts)
+ context->loseContextImpl(mode);
detachAndRemoveAllObjects();
}
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.h b/Source/WebCore/html/canvas/WebGLContextGroup.h
index aa7036ae6..11b737032 100644
--- a/Source/WebCore/html/canvas/WebGLContextGroup.h
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,49 +23,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLContextGroup_h
-#define WebGLContextGroup_h
+#pragma once
-#include <WebGLRenderingContext.h>
-#include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-class GraphicsContext3D;
-class WebGLExtension;
-class WebGLSharedObject;
-class WebGLRenderingContext;
-
-typedef int ExceptionCode;
-
class WebGLContextGroup : public RefCounted<WebGLContextGroup> {
public:
- static PassRefPtr<WebGLContextGroup> create();
- virtual ~WebGLContextGroup();
+ static Ref<WebGLContextGroup> create();
+ ~WebGLContextGroup();
- void addContext(WebGLRenderingContext*);
- void removeContext(WebGLRenderingContext*);
+ void addContext(WebGLRenderingContextBase&);
+ void removeContext(WebGLRenderingContextBase&);
- void addObject(WebGLSharedObject*);
- void removeObject(WebGLSharedObject*);
+ void addObject(WebGLSharedObject&);
+ void removeObject(WebGLSharedObject&);
- GraphicsContext3D* getAGraphicsContext3D();
+ GraphicsContext3D& getAGraphicsContext3D();
- void loseContextGroup(WebGLRenderingContext::LostContextMode);
+ void loseContextGroup(WebGLRenderingContextBase::LostContextMode);
- private:
- friend class WebGLObject;
-
- WebGLContextGroup();
+private:
+ WebGLContextGroup() = default;
void detachAndRemoveAllObjects();
- HashSet<WebGLRenderingContext*> m_contexts;
+ HashSet<WebGLRenderingContextBase*> m_contexts;
HashSet<WebGLSharedObject*> m_groupObjects;
};
} // namespace WebCore
-
-#endif // WebGLContextGroup_h
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.cpp b/Source/WebCore/html/canvas/WebGLContextObject.cpp
index 9b3ab0b9c..6a1c7ab29 100644
--- a/Source/WebCore/html/canvas/WebGLContextObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextObject.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,25 +24,23 @@
*/
#include "config.h"
+#include "WebGLContextObject.h"
#if ENABLE(WEBGL)
-#include "WebGLContextObject.h"
-
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
- : WebGLObject(context)
- , m_context(context)
+WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase& context)
+ : m_context(&context)
{
}
WebGLContextObject::~WebGLContextObject()
{
if (m_context)
- m_context->removeContextObject(this);
+ m_context->removeContextObject(*this);
}
void WebGLContextObject::detachContext()
@@ -50,14 +48,14 @@ void WebGLContextObject::detachContext()
detach();
if (m_context) {
deleteObject(m_context->graphicsContext3D());
- m_context->removeContextObject(this);
- m_context = 0;
+ m_context->removeContextObject(*this);
+ m_context = nullptr;
}
}
GraphicsContext3D* WebGLContextObject::getAGraphicsContext3D() const
{
- return m_context ? m_context->graphicsContext3D() : 0;
+ return m_context ? m_context->graphicsContext3D() : nullptr;
}
}
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.h b/Source/WebCore/html/canvas/WebGLContextObject.h
index e674b1c64..ebe0fc6c5 100644
--- a/Source/WebCore/html/canvas/WebGLContextObject.h
+++ b/Source/WebCore/html/canvas/WebGLContextObject.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,15 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLContextObject_h
-#define WebGLContextObject_h
+#pragma once
#include "WebGLObject.h"
namespace WebCore {
class GraphicsContext3D;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
// WebGLContextObject the base class for objects that are owned by a specific
// WebGLRenderingContext.
@@ -39,29 +38,27 @@ class WebGLContextObject : public WebGLObject {
public:
virtual ~WebGLContextObject();
- WebGLRenderingContext* context() const { return m_context; }
+ WebGLRenderingContextBase* context() const { return m_context; }
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const override
+ bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase& context) const override
{
- return context == m_context;
+ return &context == m_context;
}
void detachContext();
protected:
- WebGLContextObject(WebGLRenderingContext*);
+ WebGLContextObject(WebGLRenderingContextBase&);
- virtual bool hasGroupOrContext() const override
+ bool hasGroupOrContext() const override
{
return m_context;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const override;
+ GraphicsContext3D* getAGraphicsContext3D() const override;
private:
- WebGLRenderingContext* m_context;
+ WebGLRenderingContextBase* m_context;
};
} // namespace WebCore
-
-#endif // WebGLContextObject_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
index 2fe5f171d..9df7fbd51 100644
--- a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
@@ -29,11 +29,11 @@
#include "WebGLDebugRendererInfo.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -47,11 +47,6 @@ WebGLExtension::ExtensionName WebGLDebugRendererInfo::getName() const
return WebGLDebugRendererInfoName;
}
-OwnPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new WebGLDebugRendererInfo(context));
-}
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
index 4422f84de..3e5822d20 100644
--- a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
@@ -23,30 +23,23 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLDebugRendererInfo_h
-#define WebGLDebugRendererInfo_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLDebugRendererInfo : public WebGLExtension {
+class WebGLDebugRendererInfo final : public WebGLExtension {
public:
enum EnumType {
UNMASKED_VENDOR_WEBGL = 0x9245,
UNMASKED_RENDERER_WEBGL = 0x9246
};
- static OwnPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
-
+ explicit WebGLDebugRendererInfo(WebGLRenderingContextBase&);
virtual ~WebGLDebugRendererInfo();
- virtual ExtensionName getName() const override;
-private:
- WebGLDebugRendererInfo(WebGLRenderingContext*);
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // WebGLDebugRendererInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl
index a4f953841..c9292de61 100644
--- a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl
@@ -24,11 +24,11 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface WebGLDebugRendererInfo {
- const unsigned int UNMASKED_VENDOR_WEBGL = 0x9245;
- const unsigned int UNMASKED_RENDERER_WEBGL = 0x9246;
+ const unsigned long UNMASKED_VENDOR_WEBGL = 0x9245;
+ const unsigned long UNMASKED_RENDERER_WEBGL = 0x9246;
};
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
index 0c028265c..ed4281309 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
@@ -30,12 +30,12 @@
#include "WebGLDebugShaders.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
#include "WebGLShader.h"
namespace WebCore {
-WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -49,19 +49,13 @@ WebGLExtension::ExtensionName WebGLDebugShaders::getName() const
return WebGLDebugShadersName;
}
-OwnPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader)
{
- return adoptPtr(new WebGLDebugShaders(context));
-}
-
-String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return String();
- if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader))
- return "";
- return m_context->graphicsContext3D()->getExtensions()->getTranslatedShaderSourceANGLE(shader->object());
+ if (!m_context.validateWebGLObject("getTranslatedShaderSource", shader))
+ return emptyString();
+ return m_context.graphicsContext3D()->getExtensions().getTranslatedShaderSourceANGLE(shader->object());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.h b/Source/WebCore/html/canvas/WebGLDebugShaders.h
index 961f488ce..4b99f1aea 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.h
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.h
@@ -23,31 +23,22 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLDebugShaders_h
-#define WebGLDebugShaders_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
class WebGLShader;
-typedef int ExceptionCode;
-
-class WebGLDebugShaders : public WebGLExtension {
+class WebGLDebugShaders final : public WebGLExtension {
public:
- static OwnPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
-
+ explicit WebGLDebugShaders(WebGLRenderingContextBase&);
virtual ~WebGLDebugShaders();
- virtual ExtensionName getName() const override;
- String getTranslatedShaderSource(WebGLShader*, ExceptionCode&);
+ ExtensionName getName() const override;
-private:
- WebGLDebugShaders(WebGLRenderingContext*);
+ String getTranslatedShaderSource(WebGLShader*);
};
} // namespace WebCore
-
-#endif // WebGLDebugShaders_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.idl b/Source/WebCore/html/canvas/WebGLDebugShaders.idl
index 4b0e11311..97c5e36be 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.idl
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.idl
@@ -24,9 +24,9 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
GenerateIsReachable=ImplWebGLRenderingContext,
+ NoInterfaceObject,
] interface WebGLDebugShaders {
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getTranslatedShaderSource(WebGLShader shader);
+ DOMString? getTranslatedShaderSource(WebGLShader? shader); // FIXME: The return value and the parameter should not be nullable.
};
diff --git a/Source/WebCore/html/canvas/WebGLDepthTexture.cpp b/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
index 71a8da7d4..29f9b64e4 100644
--- a/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
+++ b/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContext* context)
+WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -47,17 +47,11 @@ WebGLExtension::ExtensionName WebGLDepthTexture::getName() const
return WebGLDepthTextureName;
}
-OwnPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContext* context)
+bool WebGLDepthTexture::supported(GraphicsContext3D& context)
{
- return adoptPtr(new WebGLDepthTexture(context));
-}
-
-bool WebGLDepthTexture::supported(GraphicsContext3D* context)
-{
- Extensions3D* extensions = context->getExtensions();
- return extensions->supports("GL_CHROMIUM_depth_texture")
- || extensions->supports("GL_OES_depth_texture")
- || extensions->supports("GL_ARB_depth_texture");
+ Extensions3D& extensions = context.getExtensions();
+ return extensions.supports("GL_OES_depth_texture")
+ || extensions.supports("GL_ARB_depth_texture");
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDepthTexture.h b/Source/WebCore/html/canvas/WebGLDepthTexture.h
index 8687c2543..16b3b60b4 100644
--- a/Source/WebCore/html/canvas/WebGLDepthTexture.h
+++ b/Source/WebCore/html/canvas/WebGLDepthTexture.h
@@ -23,27 +23,20 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLDepthTexture_h
-#define WebGLDepthTexture_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLDepthTexture : public WebGLExtension {
+class WebGLDepthTexture final : public WebGLExtension {
public:
- static OwnPtr<WebGLDepthTexture> create(WebGLRenderingContext*);
-
- static bool supported(GraphicsContext3D*);
-
+ explicit WebGLDepthTexture(WebGLRenderingContextBase&);
virtual ~WebGLDepthTexture();
- virtual ExtensionName getName() const override;
-private:
- WebGLDepthTexture(WebGLRenderingContext*);
+ static bool supported(GraphicsContext3D&);
+
+ ExtensionName getName() const override;
};
} // namespace WebCore
-
-#endif // WebGLDepthTexture_h
diff --git a/Source/WebCore/html/canvas/WebGLDepthTexture.idl b/Source/WebCore/html/canvas/WebGLDepthTexture.idl
index 60fcca36f..53954cea0 100644
--- a/Source/WebCore/html/canvas/WebGLDepthTexture.idl
+++ b/Source/WebCore/html/canvas/WebGLDepthTexture.idl
@@ -24,10 +24,10 @@
*/
[
- NoInterfaceObject,
Conditional=WEBGL,
+ DoNotCheckConstants,
GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants
+ NoInterfaceObject,
] interface WebGLDepthTexture {
- const unsigned int UNSIGNED_INT_24_8_WEBGL = 0x84FA;
+ const unsigned long UNSIGNED_INT_24_8_WEBGL = 0x84FA;
};
diff --git a/Source/WebCore/html/canvas/EXTDrawBuffers.cpp b/Source/WebCore/html/canvas/WebGLDrawBuffers.cpp
index 1a2bbf1a9..0891c02a9 100644
--- a/Source/WebCore/html/canvas/EXTDrawBuffers.cpp
+++ b/Source/WebCore/html/canvas/WebGLDrawBuffers.cpp
@@ -26,82 +26,70 @@
#include "config.h"
#if ENABLE(WEBGL)
-
-#include "EXTDrawBuffers.h"
+#include "WebGLDrawBuffers.h"
#include "Extensions3D.h"
namespace WebCore {
-EXTDrawBuffers::EXTDrawBuffers(WebGLRenderingContext* context)
+WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
-EXTDrawBuffers::~EXTDrawBuffers()
+WebGLDrawBuffers::~WebGLDrawBuffers()
{
}
-WebGLExtension::ExtensionName EXTDrawBuffers::getName() const
+WebGLExtension::ExtensionName WebGLDrawBuffers::getName() const
{
- return WebGLExtension::EXTDrawBuffersName;
+ return WebGLExtension::WebGLDrawBuffersName;
}
-OwnPtr<EXTDrawBuffers> EXTDrawBuffers::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new EXTDrawBuffers(context));
-}
-
-// static
-bool EXTDrawBuffers::supported(WebGLRenderingContext* context)
+bool WebGLDrawBuffers::supported(WebGLRenderingContextBase& context)
{
-#if OS(DARWIN)
- // https://bugs.webkit.org/show_bug.cgi?id=112486
- return false;
-#endif
- Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return (extensions->supports("GL_EXT_draw_buffers")
- && satisfiesWebGLRequirements(context));
+ return context.graphicsContext3D()->getExtensions().supports("GL_EXT_draw_buffers")
+ && satisfiesWebGLRequirements(context);
}
-void EXTDrawBuffers::drawBuffersEXT(const Vector<GC3Denum>& buffers)
+void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
{
- if (m_context->isContextLost())
+ if (m_context.isContextLost())
return;
GC3Dsizei n = buffers.size();
const GC3Denum* bufs = buffers.data();
- if (!m_context->m_framebufferBinding) {
+ if (!m_context.m_framebufferBinding) {
if (n != 1) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than one buffer");
+ m_context.synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersWEBGL", "more than one buffer");
return;
}
if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "BACK or NONE");
+ m_context.synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersWEBGL", "BACK or NONE");
return;
}
// Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
- m_context->graphicsContext3D()->getExtensions()->drawBuffersEXT(1, &value);
- m_context->setBackDrawBuffer(bufs[0]);
+ m_context.graphicsContext3D()->getExtensions().drawBuffersEXT(1, &value);
+ m_context.setBackDrawBuffer(bufs[0]);
} else {
- if (n > m_context->getMaxDrawBuffers()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than max draw buffers");
+ if (n > m_context.getMaxDrawBuffers()) {
+ m_context.synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersWEBGL", "more than max draw buffers");
return;
}
for (GC3Dsizei i = 0; i < n; ++i) {
if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "COLOR_ATTACHMENTi_EXT or NONE");
+ m_context.synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersWEBGL", "COLOR_ATTACHMENTi_EXT or NONE");
return;
}
}
- m_context->m_framebufferBinding->drawBuffers(buffers);
+ m_context.m_framebufferBinding->drawBuffers(buffers);
}
}
// static
-bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
+bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase& webglContext)
{
- GraphicsContext3D* context = webglContext->graphicsContext3D();
+ GraphicsContext3D* context = webglContext.graphicsContext3D();
// This is called after we make sure GL_EXT_draw_buffers is supported.
GC3Dint maxDrawBuffers = 0;
@@ -115,11 +103,10 @@ bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCont
context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fbo);
const unsigned char buffer[4] = { 0, 0, 0, 0 }; // textures are required to be initialized for other ports.
- bool supportsDepth = (context->getExtensions()->supports("GL_CHROMIUM_depth_texture")
- || context->getExtensions()->supports("GL_OES_depth_texture")
- || context->getExtensions()->supports("GL_ARB_depth_texture"));
- bool supportsDepthStencil = (context->getExtensions()->supports("GL_EXT_packed_depth_stencil")
- || context->getExtensions()->supports("GL_OES_packed_depth_stencil"));
+ bool supportsDepth = context->getExtensions().supports("GL_OES_depth_texture")
+ || context->getExtensions().supports("GL_ARB_depth_texture");
+ bool supportsDepthStencil = (context->getExtensions().supports("GL_EXT_packed_depth_stencil")
+ || context->getExtensions().supports("GL_OES_packed_depth_stencil"));
Platform3DObject depthStencil = 0;
if (supportsDepthStencil) {
depthStencil = context->createTexture();
@@ -166,15 +153,15 @@ bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCont
}
}
- webglContext->restoreCurrentFramebuffer();
+ webglContext.restoreCurrentFramebuffer();
context->deleteFramebuffer(fbo);
- webglContext->restoreCurrentTexture2D();
+ webglContext.restoreCurrentTexture2D();
if (supportsDepth)
context->deleteTexture(depth);
if (supportsDepthStencil)
context->deleteTexture(depthStencil);
- for (size_t i = 0; i < colors.size(); ++i)
- context->deleteTexture(colors[i]);
+ for (auto& color : colors)
+ context->deleteTexture(color);
return ok;
}
diff --git a/Source/WebCore/html/canvas/EXTDrawBuffers.h b/Source/WebCore/html/canvas/WebGLDrawBuffers.h
index b5963fb70..f69df9f63 100644
--- a/Source/WebCore/html/canvas/EXTDrawBuffers.h
+++ b/Source/WebCore/html/canvas/WebGLDrawBuffers.h
@@ -23,31 +23,25 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef EXTDrawBuffers_h
-#define EXTDrawBuffers_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class EXTDrawBuffers : public WebGLExtension {
+class WebGLDrawBuffers final : public WebGLExtension {
public:
- static OwnPtr<EXTDrawBuffers> create(WebGLRenderingContext*);
+ explicit WebGLDrawBuffers(WebGLRenderingContextBase&);
+ virtual ~WebGLDrawBuffers();
- static bool supported(WebGLRenderingContext*);
+ static bool supported(WebGLRenderingContextBase&);
- virtual ~EXTDrawBuffers();
- virtual ExtensionName getName() const override;
+ ExtensionName getName() const override;
- void drawBuffersEXT(const Vector<GC3Denum>& buffers);
+ void drawBuffersWEBGL(const Vector<GC3Denum>& buffers);
private:
- EXTDrawBuffers(WebGLRenderingContext*);
-
- static bool satisfiesWebGLRequirements(WebGLRenderingContext*);
+ static bool satisfiesWebGLRequirements(WebGLRenderingContextBase&);
};
} // namespace WebCore
-
-#endif // EXTDrawBuffers_h
diff --git a/Source/WebCore/html/canvas/WebGLDrawBuffers.idl b/Source/WebCore/html/canvas/WebGLDrawBuffers.idl
new file mode 100644
index 000000000..f8e783e84
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDrawBuffers.idl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+typedef unsigned long GLenum;
+
+[
+ NoInterfaceObject,
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext,
+ DoNotCheckConstants,
+] interface WebGLDrawBuffers {
+ const GLenum COLOR_ATTACHMENT0_WEBGL = 0x8CE0;
+ const GLenum COLOR_ATTACHMENT1_WEBGL = 0x8CE1;
+ const GLenum COLOR_ATTACHMENT2_WEBGL = 0x8CE2;
+ const GLenum COLOR_ATTACHMENT3_WEBGL = 0x8CE3;
+ const GLenum COLOR_ATTACHMENT4_WEBGL = 0x8CE4;
+ const GLenum COLOR_ATTACHMENT5_WEBGL = 0x8CE5;
+ const GLenum COLOR_ATTACHMENT6_WEBGL = 0x8CE6;
+ const GLenum COLOR_ATTACHMENT7_WEBGL = 0x8CE7;
+ const GLenum COLOR_ATTACHMENT8_WEBGL = 0x8CE8;
+ const GLenum COLOR_ATTACHMENT9_WEBGL = 0x8CE9;
+ const GLenum COLOR_ATTACHMENT10_WEBGL = 0x8CEA;
+ const GLenum COLOR_ATTACHMENT11_WEBGL = 0x8CEB;
+ const GLenum COLOR_ATTACHMENT12_WEBGL = 0x8CEC;
+ const GLenum COLOR_ATTACHMENT13_WEBGL = 0x8CED;
+ const GLenum COLOR_ATTACHMENT14_WEBGL = 0x8CEE;
+ const GLenum COLOR_ATTACHMENT15_WEBGL = 0x8CEF;
+
+ const GLenum DRAW_BUFFER0_WEBGL = 0x8825;
+ const GLenum DRAW_BUFFER1_WEBGL = 0x8826;
+ const GLenum DRAW_BUFFER2_WEBGL = 0x8827;
+ const GLenum DRAW_BUFFER3_WEBGL = 0x8828;
+ const GLenum DRAW_BUFFER4_WEBGL = 0x8829;
+ const GLenum DRAW_BUFFER5_WEBGL = 0x882A;
+ const GLenum DRAW_BUFFER6_WEBGL = 0x882B;
+ const GLenum DRAW_BUFFER7_WEBGL = 0x882C;
+ const GLenum DRAW_BUFFER8_WEBGL = 0x882D;
+ const GLenum DRAW_BUFFER9_WEBGL = 0x882E;
+ const GLenum DRAW_BUFFER10_WEBGL = 0x882F;
+ const GLenum DRAW_BUFFER11_WEBGL = 0x8830;
+ const GLenum DRAW_BUFFER12_WEBGL = 0x8831;
+ const GLenum DRAW_BUFFER13_WEBGL = 0x8832;
+ const GLenum DRAW_BUFFER14_WEBGL = 0x8833;
+ const GLenum DRAW_BUFFER15_WEBGL = 0x8834;
+
+ const GLenum MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF;
+ const GLenum MAX_DRAW_BUFFERS_WEBGL = 0x8824;
+
+ void drawBuffersWEBGL(sequence<GLenum> buffers);
+};
diff --git a/Source/WebCore/html/canvas/WebGLExtension.cpp b/Source/WebCore/html/canvas/WebGLExtension.cpp
index bf62eecec..c9f0a4251 100644
--- a/Source/WebCore/html/canvas/WebGLExtension.cpp
+++ b/Source/WebCore/html/canvas/WebGLExtension.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
+WebGLExtension::WebGLExtension(WebGLRenderingContextBase& context)
: m_context(context)
{
}
diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h
index e9100dba0..7f709b445 100644
--- a/Source/WebCore/html/canvas/WebGLExtension.h
+++ b/Source/WebCore/html/canvas/WebGLExtension.h
@@ -23,10 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLExtension_h
-#define WebGLExtension_h
+#pragma once
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
@@ -36,8 +35,11 @@ public:
// Extension names are needed to properly wrap instances in JavaScript objects.
enum ExtensionName {
WebGLLoseContextName,
- EXTDrawBuffersName,
+ EXTBlendMinMaxName,
+ EXTFragDepthName,
+ EXTShaderTextureLODName,
EXTTextureFilterAnisotropicName,
+ EXTsRGBName,
OESTextureFloatName,
OESTextureFloatLinearName,
OESTextureHalfFloatName,
@@ -48,24 +50,23 @@ public:
WebGLDebugShadersName,
WebGLCompressedTextureS3TCName,
WebGLDepthTextureName,
+ WebGLDrawBuffersName,
OESElementIndexUintName,
WebGLCompressedTextureATCName,
WebGLCompressedTexturePVRTCName,
ANGLEInstancedArraysName,
};
- void ref() { m_context->ref(); }
- void deref() { m_context->deref(); }
- WebGLRenderingContext* context() { return m_context; }
+ void ref() { m_context.ref(); }
+ void deref() { m_context.deref(); }
+ WebGLRenderingContextBase& context() { return m_context; }
virtual ~WebGLExtension();
virtual ExtensionName getName() const = 0;
protected:
- WebGLExtension(WebGLRenderingContext*);
- WebGLRenderingContext* m_context;
+ WebGLExtension(WebGLRenderingContextBase&);
+ WebGLRenderingContextBase& m_context;
};
} // namespace WebCore
-
-#endif // WebGLExtension_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
index 7e1dc07f5..c2762b236 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,15 +24,14 @@
*/
#include "config.h"
+#include "WebGLFramebuffer.h"
#if ENABLE(WEBGL)
-#include "WebGLFramebuffer.h"
-
-#include "EXTDrawBuffers.h"
#include "Extensions3D.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLDrawBuffers.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
@@ -45,30 +44,30 @@ namespace {
class WebGLRenderbufferAttachment : public WebGLFramebuffer::WebGLAttachment {
public:
- static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
+ static Ref<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
private:
WebGLRenderbufferAttachment(WebGLRenderbuffer*);
- virtual GC3Dsizei getWidth() const override;
- virtual GC3Dsizei getHeight() const override;
- virtual GC3Denum getFormat() const override;
- virtual WebGLSharedObject* getObject() const override;
- virtual bool isSharedObject(WebGLSharedObject*) const override;
- virtual bool isValid() const override;
- virtual bool isInitialized() const override;
- virtual void setInitialized() override;
- virtual void onDetached(GraphicsContext3D*) override;
- virtual void attach(GraphicsContext3D*, GC3Denum attachment) override;
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment) override;
+ GC3Dsizei getWidth() const override;
+ GC3Dsizei getHeight() const override;
+ GC3Denum getFormat() const override;
+ WebGLSharedObject* getObject() const override;
+ bool isSharedObject(WebGLSharedObject*) const override;
+ bool isValid() const override;
+ bool isInitialized() const override;
+ void setInitialized() override;
+ void onDetached(GraphicsContext3D*) override;
+ void attach(GraphicsContext3D*, GC3Denum attachment) override;
+ void unattach(GraphicsContext3D*, GC3Denum attachment) override;
WebGLRenderbufferAttachment() { };
RefPtr<WebGLRenderbuffer> m_renderbuffer;
};
- PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLRenderbufferAttachment::create(WebGLRenderbuffer* renderbuffer)
+ Ref<WebGLFramebuffer::WebGLAttachment> WebGLRenderbufferAttachment::create(WebGLRenderbuffer* renderbuffer)
{
- return adoptRef(new WebGLRenderbufferAttachment(renderbuffer));
+ return adoptRef(*new WebGLRenderbufferAttachment(renderbuffer));
}
WebGLRenderbufferAttachment::WebGLRenderbufferAttachment(WebGLRenderbuffer* renderbuffer)
@@ -139,21 +138,21 @@ namespace {
class WebGLTextureAttachment : public WebGLFramebuffer::WebGLAttachment {
public:
- static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
+ static Ref<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
private:
WebGLTextureAttachment(WebGLTexture*, GC3Denum target, GC3Dint level);
- virtual GC3Dsizei getWidth() const override;
- virtual GC3Dsizei getHeight() const override;
- virtual GC3Denum getFormat() const override;
- virtual WebGLSharedObject* getObject() const override;
- virtual bool isSharedObject(WebGLSharedObject*) const override;
- virtual bool isValid() const override;
- virtual bool isInitialized() const override;
- virtual void setInitialized() override;
- virtual void onDetached(GraphicsContext3D*) override;
- virtual void attach(GraphicsContext3D*, GC3Denum attachment) override;
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment) override;
+ GC3Dsizei getWidth() const override;
+ GC3Dsizei getHeight() const override;
+ GC3Denum getFormat() const override;
+ WebGLSharedObject* getObject() const override;
+ bool isSharedObject(WebGLSharedObject*) const override;
+ bool isValid() const override;
+ bool isInitialized() const override;
+ void setInitialized() override;
+ void onDetached(GraphicsContext3D*) override;
+ void attach(GraphicsContext3D*, GC3Denum attachment) override;
+ void unattach(GraphicsContext3D*, GC3Denum attachment) override;
WebGLTextureAttachment() { };
@@ -162,9 +161,9 @@ namespace {
GC3Dint m_level;
};
- PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ Ref<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
{
- return adoptRef(new WebGLTextureAttachment(texture, target, level));
+ return adoptRef(*new WebGLTextureAttachment(texture, target, level));
}
WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GC3Denum target, GC3Dint level)
@@ -269,16 +268,16 @@ WebGLFramebuffer::WebGLAttachment::~WebGLAttachment()
{
}
-PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+Ref<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLFramebuffer(ctx));
+ return adoptRef(*new WebGLFramebuffer(ctx));
}
-WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase& ctx)
: WebGLContextObject(ctx)
, m_hasEverBeenBound(false)
{
- setObject(ctx->graphicsContext3D()->createFramebuffer());
+ setObject(ctx.graphicsContext3D()->createFramebuffer());
}
WebGLFramebuffer::~WebGLFramebuffer()
@@ -369,19 +368,19 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
return;
bool checkMore = true;
- while (checkMore) {
+ do {
checkMore = false;
- for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
- WebGLAttachment* attachmentObject = it->value.get();
+ for (auto& entry : m_attachments) {
+ WebGLAttachment* attachmentObject = entry.value.get();
if (attachmentObject->isSharedObject(attachment)) {
- GC3Denum attachmentType = it->key;
+ GC3Denum attachmentType = entry.key;
attachmentObject->unattach(context()->graphicsContext3D(), attachmentType);
removeAttachmentFromBoundFramebuffer(attachmentType);
checkMore = true;
break;
}
}
- }
+ } while (checkMore);
}
GC3Dsizei WebGLFramebuffer::getColorBufferWidth() const
@@ -423,19 +422,25 @@ GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
bool haveDepth = false;
bool haveStencil = false;
bool haveDepthStencil = false;
- for (AttachmentMap::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
- WebGLAttachment* attachment = it->value.get();
- if (!isAttachmentComplete(attachment, it->key, reason))
+ for (auto& entry : m_attachments) {
+ WebGLAttachment* attachment = entry.value.get();
+ if (!isAttachmentComplete(attachment, entry.key, reason))
return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
if (!attachment->isValid()) {
*reason = "attachment is not valid";
return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
}
- if (!attachment->getFormat()) {
+ GC3Denum attachmentFormat = attachment->getFormat();
+
+ // Attaching an SRGB_EXT format attachment to a framebuffer is invalid.
+ if (attachmentFormat == Extensions3D::SRGB_EXT)
+ attachmentFormat = 0;
+
+ if (!attachmentFormat) {
*reason = "attachment is an unsupported format";
return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- switch (it->key) {
+ switch (entry.key) {
case GraphicsContext3D::DEPTH_ATTACHMENT:
haveDepth = true;
break;
@@ -473,13 +478,11 @@ GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
}
-bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, bool needToInitializeAttachments, const char** reason)
+bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, const char** reason)
{
if (checkStatus(reason) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
return false;
- if (needToInitializeAttachments)
- return initializeAttachments(context3d, reason);
- return true;
+ return initializeAttachments(context3d, reason);
}
bool WebGLFramebuffer::hasStencilBuffer() const
@@ -492,8 +495,8 @@ bool WebGLFramebuffer::hasStencilBuffer() const
void WebGLFramebuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
- it->value->onDetached(context3d);
+ for (auto& attachment : m_attachments.values())
+ attachment->onDetached(context3d);
context3d->deleteFramebuffer(object);
}
@@ -503,9 +506,9 @@ bool WebGLFramebuffer::initializeAttachments(GraphicsContext3D* g3d, const char*
ASSERT(object());
GC3Dbitfield mask = 0;
- for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
- GC3Denum attachmentType = it->key;
- WebGLAttachment* attachment = it->value.get();
+ for (auto& entry : m_attachments) {
+ GC3Denum attachmentType = entry.key;
+ WebGLAttachment* attachment = entry.value.get();
if (!attachment->isInitialized())
mask |= GraphicsContext3D::getClearBitsByAttachmentType(attachmentType);
}
@@ -594,15 +597,20 @@ void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
{
m_drawBuffers = bufs;
m_filteredDrawBuffers.resize(m_drawBuffers.size());
- for (size_t i = 0; i < m_filteredDrawBuffers.size(); ++i)
- m_filteredDrawBuffers[i] = GraphicsContext3D::NONE;
+ for (auto& buffer : m_filteredDrawBuffers)
+ buffer = GraphicsContext3D::NONE;
drawBuffersIfNecessary(true);
}
void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
{
- if (!context()->m_extDrawBuffers)
+#if ENABLE(WEBGL2)
+ // FIXME: The logic here seems wrong. If we don't have WebGL 2 enabled at all, then
+ // we skip the m_webglDrawBuffers check. But if we do have WebGL 2 enabled, then we
+ // perform this check, for WebGL 1 contexts only.
+ if (!context()->m_webglDrawBuffers && !context()->isWebGL2())
return;
+#endif
bool reset = force;
// This filtering works around graphics driver bugs on Mac OS X.
for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
@@ -619,7 +627,7 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
}
}
if (reset) {
- context()->graphicsContext3D()->getExtensions()->drawBuffersEXT(
+ context()->graphicsContext3D()->getExtensions().drawBuffersEXT(
m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
}
}
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
index a0ee31c69..baeeae66b 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,13 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLFramebuffer_h
-#define WebGLFramebuffer_h
+#pragma once
#include "WebGLContextObject.h"
#include "WebGLSharedObject.h"
-
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -37,7 +34,7 @@ namespace WebCore {
class WebGLRenderbuffer;
class WebGLTexture;
-class WebGLFramebuffer : public WebGLContextObject {
+class WebGLFramebuffer final : public WebGLContextObject {
public:
class WebGLAttachment : public RefCounted<WebGLAttachment> {
public:
@@ -61,7 +58,7 @@ public:
virtual ~WebGLFramebuffer();
- static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+ static Ref<WebGLFramebuffer> create(WebGLRenderingContextBase&);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
@@ -81,7 +78,7 @@ public:
// Return false if the framebuffer is incomplete; otherwise initialize
// the buffers if they haven't been initialized and
// needToInitializeAttachments is true.
- bool onAccess(GraphicsContext3D*, bool needToInitializeAttachments, const char** reason);
+ bool onAccess(GraphicsContext3D*, const char** reason);
// Software version of glCheckFramebufferStatus(), except that when
// FRAMEBUFFER_COMPLETE is returned, it is still possible for
@@ -101,13 +98,11 @@ public:
GC3Denum getDrawBuffer(GC3Denum);
protected:
- WebGLFramebuffer(WebGLRenderingContext*);
+ WebGLFramebuffer(WebGLRenderingContextBase&);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
private:
- virtual bool isFramebuffer() const { return true; }
-
WebGLAttachment* getAttachment(GC3Denum) const;
// Return false if framebuffer is incomplete.
@@ -133,5 +128,3 @@ private:
};
} // namespace WebCore
-
-#endif // WebGLFramebuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.idl b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
index e609513b2..7c6cc4595 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
deleted file mode 100644
index 8e27d3b9a..000000000
--- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All Rights Reserved.
- * Copyright (C) 2009 Google 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 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 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.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-
-#include "WebGLGetInfo.h"
-
-#include "WebGLBuffer.h"
-#include "WebGLFramebuffer.h"
-#include "WebGLProgram.h"
-#include "WebGLRenderbuffer.h"
-#include "WebGLTexture.h"
-#include "WebGLVertexArrayObjectOES.h"
-#include <runtime/Float32Array.h>
-#include <runtime/Int32Array.h>
-#include <runtime/Uint32Array.h>
-#include <runtime/Uint8Array.h>
-
-namespace WebCore {
-
-WebGLGetInfo::WebGLGetInfo(bool value)
- : m_type(kTypeBool)
- , m_bool(value)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
- : m_type(kTypeBoolArray)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
-{
- if (!value || size <=0)
- return;
- m_boolArray.resize(size);
- for (int ii = 0; ii < size; ++ii)
- m_boolArray[ii] = value[ii];
-}
-
-WebGLGetInfo::WebGLGetInfo(float value)
- : m_type(kTypeFloat)
- , m_bool(false)
- , m_float(value)
- , m_int(0)
- , m_unsignedInt(0)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(int value)
- : m_type(kTypeInt)
- , m_bool(false)
- , m_float(0)
- , m_int(value)
- , m_unsignedInt(0)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo()
- : m_type(kTypeNull)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(const String& value)
- : m_type(kTypeString)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_string(value)
- , m_unsignedInt(0)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(unsigned int value)
- : m_type(kTypeUnsignedInt)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLBuffer> value)
- : m_type(kTypeWebGLBuffer)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglBuffer(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<Float32Array> value)
- : m_type(kTypeWebGLFloatArray)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglFloatArray(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value)
- : m_type(kTypeWebGLFramebuffer)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglFramebuffer(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<Int32Array> value)
- : m_type(kTypeWebGLIntArray)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglIntArray(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLProgram> value)
- : m_type(kTypeWebGLProgram)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglProgram(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value)
- : m_type(kTypeWebGLRenderbuffer)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglRenderbuffer(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLTexture> value)
- : m_type(kTypeWebGLTexture)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglTexture(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
- : m_type(kTypeWebGLUnsignedByteArray)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglUnsignedByteArray(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint32Array> value)
- : m_type(kTypeWebGLUnsignedIntArray)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglUnsignedIntArray(value)
-{
-}
-
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value)
- : m_type(kTypeWebGLVertexArrayObjectOES)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_webglVertexArrayObject(value)
-{
-}
-
-WebGLGetInfo::~WebGLGetInfo()
-{
-}
-
-WebGLGetInfo::Type WebGLGetInfo::getType() const
-{
- return m_type;
-}
-
-bool WebGLGetInfo::getBool() const
-{
- ASSERT(getType() == kTypeBool);
- return m_bool;
-}
-
-const Vector<bool>& WebGLGetInfo::getBoolArray() const
-{
- ASSERT(getType() == kTypeBoolArray);
- return m_boolArray;
-}
-
-float WebGLGetInfo::getFloat() const
-{
- ASSERT(getType() == kTypeFloat);
- return m_float;
-}
-
-int WebGLGetInfo::getInt() const
-{
- ASSERT(getType() == kTypeInt);
- return m_int;
-}
-
-const String& WebGLGetInfo::getString() const
-{
- ASSERT(getType() == kTypeString);
- return m_string;
-}
-
-unsigned int WebGLGetInfo::getUnsignedInt() const
-{
- ASSERT(getType() == kTypeUnsignedInt);
- return m_unsignedInt;
-}
-
-PassRefPtr<WebGLBuffer> WebGLGetInfo::getWebGLBuffer() const
-{
- ASSERT(getType() == kTypeWebGLBuffer);
- return m_webglBuffer;
-}
-
-PassRefPtr<Float32Array> WebGLGetInfo::getWebGLFloatArray() const
-{
- ASSERT(getType() == kTypeWebGLFloatArray);
- return m_webglFloatArray;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLGetInfo::getWebGLFramebuffer() const
-{
- ASSERT(getType() == kTypeWebGLFramebuffer);
- return m_webglFramebuffer;
-}
-
-PassRefPtr<Int32Array> WebGLGetInfo::getWebGLIntArray() const
-{
- ASSERT(getType() == kTypeWebGLIntArray);
- return m_webglIntArray;
-}
-
-PassRefPtr<WebGLProgram> WebGLGetInfo::getWebGLProgram() const
-{
- ASSERT(getType() == kTypeWebGLProgram);
- return m_webglProgram;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLGetInfo::getWebGLRenderbuffer() const
-{
- ASSERT(getType() == kTypeWebGLRenderbuffer);
- return m_webglRenderbuffer;
-}
-
-PassRefPtr<WebGLTexture> WebGLGetInfo::getWebGLTexture() const
-{
- ASSERT(getType() == kTypeWebGLTexture);
- return m_webglTexture;
-}
-
-PassRefPtr<Uint8Array> WebGLGetInfo::getWebGLUnsignedByteArray() const
-{
- ASSERT(getType() == kTypeWebGLUnsignedByteArray);
- return m_webglUnsignedByteArray;
-}
-
-PassRefPtr<Uint32Array> WebGLGetInfo::getWebGLUnsignedIntArray() const
-{
- ASSERT(getType() == kTypeWebGLUnsignedIntArray);
- return m_webglUnsignedIntArray;
-}
-
-PassRefPtr<WebGLVertexArrayObjectOES> WebGLGetInfo::getWebGLVertexArrayObjectOES() const
-{
- ASSERT(getType() == kTypeWebGLVertexArrayObjectOES);
- return m_webglVertexArrayObject;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.h b/Source/WebCore/html/canvas/WebGLGetInfo.h
deleted file mode 100644
index 082612ac9..000000000
--- a/Source/WebCore/html/canvas/WebGLGetInfo.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All Rights Reserved.
- * Copyright (C) 2009 Google 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 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 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 WebGLGetInfo_h
-#define WebGLGetInfo_h
-
-#include "WebGLBuffer.h"
-#include "WebGLFramebuffer.h"
-#include "WebGLProgram.h"
-#include "WebGLRenderbuffer.h"
-#include "WebGLTexture.h"
-#include "WebGLVertexArrayObjectOES.h"
-#include <runtime/Float32Array.h>
-#include <runtime/Int32Array.h>
-#include <runtime/Uint32Array.h>
-#include <runtime/Uint8Array.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-// A tagged union representing the result of get queries like
-// getParameter (encompassing getBooleanv, getIntegerv, getFloatv) and
-// similar variants. For reference counted types, increments and
-// decrements the reference count of the target object.
-
-class WebGLGetInfo {
-public:
- enum Type {
- kTypeBool,
- kTypeBoolArray,
- kTypeFloat,
- kTypeInt,
- kTypeNull,
- kTypeString,
- kTypeUnsignedInt,
- kTypeWebGLBuffer,
- kTypeWebGLFloatArray,
- kTypeWebGLFramebuffer,
- kTypeWebGLIntArray,
- kTypeWebGLObjectArray,
- kTypeWebGLProgram,
- kTypeWebGLRenderbuffer,
- kTypeWebGLTexture,
- kTypeWebGLUnsignedByteArray,
- kTypeWebGLUnsignedIntArray,
- kTypeWebGLVertexArrayObjectOES,
- };
-
- explicit WebGLGetInfo(bool value);
- WebGLGetInfo(const bool* value, int size);
- explicit WebGLGetInfo(float value);
- explicit WebGLGetInfo(int value);
- // Represents the null value and type.
- WebGLGetInfo();
- explicit WebGLGetInfo(const String& value);
- explicit WebGLGetInfo(unsigned int value);
- explicit WebGLGetInfo(PassRefPtr<WebGLBuffer> value);
- explicit WebGLGetInfo(PassRefPtr<Float32Array> value);
- explicit WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value);
- explicit WebGLGetInfo(PassRefPtr<Int32Array> value);
- // FIXME: implement WebGLObjectArray
- // WebGLGetInfo(PassRefPtr<WebGLObjectArray> value);
- explicit WebGLGetInfo(PassRefPtr<WebGLProgram> value);
- explicit WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value);
- explicit WebGLGetInfo(PassRefPtr<WebGLTexture> value);
- explicit WebGLGetInfo(PassRefPtr<Uint8Array> value);
- explicit WebGLGetInfo(PassRefPtr<Uint32Array> value);
- explicit WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value);
-
- virtual ~WebGLGetInfo();
-
- Type getType() const;
-
- bool getBool() const;
- const Vector<bool>& getBoolArray() const;
- float getFloat() const;
- int getInt() const;
- const String& getString() const;
- unsigned int getUnsignedInt() const;
- PassRefPtr<WebGLBuffer> getWebGLBuffer() const;
- PassRefPtr<Float32Array> getWebGLFloatArray() const;
- PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const;
- PassRefPtr<Int32Array> getWebGLIntArray() const;
- // FIXME: implement WebGLObjectArray
- // PassRefPtr<WebGLObjectArray> getWebGLObjectArray() const;
- PassRefPtr<WebGLProgram> getWebGLProgram() const;
- PassRefPtr<WebGLRenderbuffer> getWebGLRenderbuffer() const;
- PassRefPtr<WebGLTexture> getWebGLTexture() const;
- PassRefPtr<Uint8Array> getWebGLUnsignedByteArray() const;
- PassRefPtr<Uint32Array> getWebGLUnsignedIntArray() const;
- PassRefPtr<WebGLVertexArrayObjectOES> getWebGLVertexArrayObjectOES() const;
-
-private:
- Type m_type;
- bool m_bool;
- Vector<bool> m_boolArray;
- float m_float;
- int m_int;
- String m_string;
- unsigned int m_unsignedInt;
- RefPtr<WebGLBuffer> m_webglBuffer;
- RefPtr<Float32Array> m_webglFloatArray;
- RefPtr<WebGLFramebuffer> m_webglFramebuffer;
- RefPtr<Int32Array> m_webglIntArray;
- // FIXME: implement WebGLObjectArray
- // RefPtr<WebGLObjectArray> m_webglObjectArray;
- RefPtr<WebGLProgram> m_webglProgram;
- RefPtr<WebGLRenderbuffer> m_webglRenderbuffer;
- RefPtr<WebGLTexture> m_webglTexture;
- RefPtr<Uint8Array> m_webglUnsignedByteArray;
- RefPtr<Uint32Array> m_webglUnsignedIntArray;
- RefPtr<WebGLVertexArrayObjectOES> m_webglVertexArrayObject;
-};
-
-} // namespace WebCore
-
-#endif // WebGLGetInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.cpp b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
index 9f4e0b01e..9bcb049b4 100644
--- a/Source/WebCore/html/canvas/WebGLLoseContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
@@ -29,11 +29,11 @@
#include "WebGLLoseContext.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContextBase& context)
: WebGLExtension(context)
{
}
@@ -47,19 +47,14 @@ WebGLExtension::ExtensionName WebGLLoseContext::getName() const
return WebGLLoseContextName;
}
-OwnPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
-{
- return adoptPtr(new WebGLLoseContext(context));
-}
-
void WebGLLoseContext::loseContext()
{
- m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+ m_context.forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
}
void WebGLLoseContext::restoreContext()
{
- m_context->forceRestoreContext();
+ m_context.forceRestoreContext();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.h b/Source/WebCore/html/canvas/WebGLLoseContext.h
index edba14a7c..630d2645a 100644
--- a/Source/WebCore/html/canvas/WebGLLoseContext.h
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.h
@@ -23,30 +23,23 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLLoseContext_h
-#define WebGLLoseContext_h
+#pragma once
#include "WebGLExtension.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class WebGLLoseContext : public WebGLExtension {
+class WebGLLoseContext final : public WebGLExtension {
public:
- static OwnPtr<WebGLLoseContext> create(WebGLRenderingContext*);
-
+ explicit WebGLLoseContext(WebGLRenderingContextBase&);
virtual ~WebGLLoseContext();
- virtual ExtensionName getName() const override;
+
+ ExtensionName getName() const override;
void loseContext();
void restoreContext();
-
-private:
- WebGLLoseContext(WebGLRenderingContext*);
};
} // namespace WebCore
-
-#endif // WebGLLoseContext_h
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.idl b/Source/WebCore/html/canvas/WebGLLoseContext.idl
index a56c0d147..8560d8681 100644
--- a/Source/WebCore/html/canvas/WebGLLoseContext.idl
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.idl
@@ -28,6 +28,6 @@
Conditional=WEBGL,
GenerateIsReachable=ImplWebGLRenderingContext,
] interface WebGLLoseContext {
- [StrictTypeChecking] void loseContext();
- [StrictTypeChecking] void restoreContext();
+ void loseContext();
+ void restoreContext();
};
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
index 502877a0c..48f939e0d 100644
--- a/Source/WebCore/html/canvas/WebGLObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,36 +24,23 @@
*/
#include "config.h"
+#include "WebGLObject.h"
#if ENABLE(WEBGL)
-#include "WebGLObject.h"
-
-#include "EXTTextureFilterAnisotropic.h"
#include "WebGLCompressedTextureS3TC.h"
#include "WebGLContextGroup.h"
#include "WebGLDebugRendererInfo.h"
#include "WebGLDebugShaders.h"
#include "WebGLLoseContext.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLObject::WebGLObject(WebGLRenderingContext*)
- : m_object(0)
- , m_attachmentCount(0)
- , m_deleted(false)
-{
-}
-
-WebGLObject::~WebGLObject()
-{
-}
-
void WebGLObject::setObject(Platform3DObject object)
{
- // object==0 && m_deleted==false indicating an uninitialized state;
- ASSERT(!m_object && !m_deleted);
+ ASSERT(!m_object);
+ ASSERT(!m_deleted);
m_object = object;
}
@@ -80,8 +67,7 @@ void WebGLObject::deleteObject(GraphicsContext3D* context3d)
void WebGLObject::detach()
{
m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
- }
-
+}
void WebGLObject::onDetached(GraphicsContext3D* context3d)
{
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
index 61af64461..69dbb5aa0 100644
--- a/Source/WebCore/html/canvas/WebGLObject.h
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,22 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLObject_h
-#define WebGLObject_h
+#pragma once
#include "GraphicsContext3D.h"
-#include <wtf/RefCounted.h>
-
namespace WebCore {
-class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLObject : public RefCounted<WebGLObject> {
public:
- virtual ~WebGLObject();
+ virtual ~WebGLObject() { }
Platform3DObject object() const { return m_object; }
@@ -56,10 +52,10 @@ public:
bool isDeleted() { return m_deleted; }
// True if this object belongs to the group or context.
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase&) const = 0;
protected:
- WebGLObject(WebGLRenderingContext*);
+ WebGLObject() = default;
// setObject should be only called once right after creating a WebGLObject.
void setObject(Platform3DObject);
@@ -74,11 +70,9 @@ protected:
virtual GraphicsContext3D* getAGraphicsContext3D() const = 0;
private:
- Platform3DObject m_object;
- unsigned m_attachmentCount;
- bool m_deleted;
+ Platform3DObject m_object { 0 };
+ unsigned m_attachmentCount { 0 };
+ bool m_deleted { false };
};
} // namespace WebCore
-
-#endif // WebGLObject_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
index 40d35949e..c24335dc4 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.cpp
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,28 +24,25 @@
*/
#include "config.h"
+#include "WebGLProgram.h"
#if ENABLE(WEBGL)
-#include "WebGLProgram.h"
-
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
+#include "WebGLShader.h"
namespace WebCore {
-PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+Ref<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLProgram(ctx));
+ return adoptRef(*new WebGLProgram(ctx));
}
-WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+WebGLProgram::WebGLProgram(WebGLRenderingContextBase& ctx)
: WebGLSharedObject(ctx)
- , m_linkStatus(false)
- , m_linkCount(0)
- , m_infoValid(true)
{
- setObject(ctx->graphicsContext3D()->createProgram());
+ setObject(ctx.graphicsContext3D()->createProgram());
}
WebGLProgram::~WebGLProgram()
@@ -58,11 +55,11 @@ void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObje
context3d->deleteProgram(obj);
if (m_vertexShader) {
m_vertexShader->onDetached(context3d);
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
}
if (m_fragmentShader) {
m_fragmentShader->onDetached(context3d);
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
}
}
@@ -148,12 +145,12 @@ bool WebGLProgram::detachShader(WebGLShader* shader)
case GraphicsContext3D::VERTEX_SHADER:
if (m_vertexShader != shader)
return false;
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
return true;
case GraphicsContext3D::FRAGMENT_SHADER:
if (m_fragmentShader != shader)
return false;
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
return true;
default:
return false;
@@ -169,7 +166,7 @@ void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
for (int i = 0; i < numAttribs; ++i) {
ActiveInfo info;
- context3d->getActiveAttrib(object(), i, info);
+ context3d->getActiveAttribImpl(object(), i, info);
m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name);
}
}
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
index 718f18498..eab76c897 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.h
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,24 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLProgram_h
-#define WebGLProgram_h
+#pragma once
#include "WebGLSharedObject.h"
-#include "WebGLShader.h"
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/Vector.h>
-
namespace WebCore {
-class WebGLProgram : public WebGLSharedObject {
+class WebGLShader;
+
+class WebGLProgram final : public WebGLSharedObject {
public:
+ static Ref<WebGLProgram> create(WebGLRenderingContextBase&);
virtual ~WebGLProgram();
- static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
-
unsigned numActiveAttribLocations();
GC3Dint getActiveAttribLocation(GC3Duint index);
@@ -62,30 +57,25 @@ public:
bool detachShader(WebGLShader*);
protected:
- WebGLProgram(WebGLRenderingContext*);
+ WebGLProgram(WebGLRenderingContextBase&);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
private:
- virtual bool isProgram() const override { return true; }
-
void cacheActiveAttribLocations(GraphicsContext3D*);
void cacheInfoIfNeeded();
Vector<GC3Dint> m_activeAttribLocations;
- GC3Dint m_linkStatus;
+ GC3Dint m_linkStatus { 0 };
- // This is used to track whether a WebGLUniformLocation belongs to this
- // program or not.
- unsigned m_linkCount;
+ // This is used to track whether a WebGLUniformLocation belongs to this program or not.
+ unsigned m_linkCount { 0 };
RefPtr<WebGLShader> m_vertexShader;
RefPtr<WebGLShader> m_fragmentShader;
- bool m_infoValid;
+ bool m_infoValid { true };
};
} // namespace WebCore
-
-#endif // WebGLProgram_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.idl b/Source/WebCore/html/canvas/WebGLProgram.idl
index d404ebdb8..7c180e2b5 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.idl
+++ b/Source/WebCore/html/canvas/WebGLProgram.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLQuery.cpp b/Source/WebCore/html/canvas/WebGLQuery.cpp
new file mode 100644
index 000000000..8ca525115
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLQuery.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "WebGLQuery.h"
+
+#include "WebGLContextGroup.h"
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+Ref<WebGLQuery> WebGLQuery::create(WebGLRenderingContextBase& ctx)
+{
+ return adoptRef(*new WebGLQuery(ctx));
+}
+
+WebGLQuery::~WebGLQuery()
+{
+ deleteObject(0);
+}
+
+WebGLQuery::WebGLQuery(WebGLRenderingContextBase& ctx)
+ : WebGLSharedObject(ctx)
+{
+ // FIXME: Call createQuery from GraphicsContext3D.
+}
+
+void WebGLQuery::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ UNUSED_PARAM(context3d);
+ UNUSED_PARAM(object);
+ // FIXME: Call deleteQuery from GraphicsContext3D.
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLQuery.h b/Source/WebCore/html/canvas/WebGLQuery.h
new file mode 100644
index 000000000..3cb761777
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLQuery.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#include "WebGLSharedObject.h"
+
+namespace WebCore {
+
+class WebGLQuery final : public WebGLSharedObject {
+public:
+ static Ref<WebGLQuery> create(WebGLRenderingContextBase&);
+ virtual ~WebGLQuery();
+
+protected:
+ explicit WebGLQuery(WebGLRenderingContextBase&);
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.idl b/Source/WebCore/html/canvas/WebGLQuery.idl
index 6a68509cc..23d353c46 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.idl
+++ b/Source/WebCore/html/canvas/WebGLQuery.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,11 +24,6 @@
*/
[
- NoInterfaceObject,
- JSCustomMarkFunction,
- GenerateIsReachable,
- CustomToJSObject
-] interface CanvasRenderingContext {
- readonly attribute HTMLCanvasElement canvas;
+ Conditional=WEBGL
+] interface WebGLQuery {
};
-
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
index daaf9d4ee..6996d9b1d 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -30,13 +30,13 @@
#include "WebGLRenderbuffer.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+Ref<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLRenderbuffer(ctx));
+ return adoptRef(*new WebGLRenderbuffer(ctx));
}
WebGLRenderbuffer::~WebGLRenderbuffer()
@@ -44,7 +44,7 @@ WebGLRenderbuffer::~WebGLRenderbuffer()
deleteObject(0);
}
-WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase& ctx)
: WebGLSharedObject(ctx)
, m_internalFormat(GraphicsContext3D::RGBA4)
, m_initialized(false)
@@ -53,7 +53,7 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
, m_isValid(true)
, m_hasEverBeenBound(false)
{
- setObject(ctx->graphicsContext3D()->createRenderbuffer());
+ setObject(ctx.graphicsContext3D()->createRenderbuffer());
}
void WebGLRenderbuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.h b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
index 137953195..cf6ad6f65 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,21 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLRenderbuffer_h
-#define WebGLRenderbuffer_h
+#pragma once
#include "WebGLSharedObject.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-
namespace WebCore {
-class WebGLRenderbuffer : public WebGLSharedObject {
+class WebGLRenderbuffer final : public WebGLSharedObject {
public:
virtual ~WebGLRenderbuffer();
- static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+ static Ref<WebGLRenderbuffer> create(WebGLRenderingContextBase&);
void setInternalFormat(GC3Denum internalformat)
{
@@ -65,12 +61,12 @@ public:
void setHasEverBeenBound() { m_hasEverBeenBound = true; }
protected:
- WebGLRenderbuffer(WebGLRenderingContext*);
+ WebGLRenderbuffer(WebGLRenderingContextBase&);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
private:
- virtual bool isRenderbuffer() const override { return true; }
+ bool isRenderbuffer() const override { return true; }
GC3Denum m_internalFormat;
bool m_initialized;
@@ -81,5 +77,3 @@ private:
};
} // namespace WebCore
-
-#endif // WebGLRenderbuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
index 618f9c472..fb855a56c 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 840cee14e..b56d81f83 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,30 +24,22 @@
*/
#include "config.h"
+#include "WebGLRenderingContext.h"
#if ENABLE(WEBGL)
-#include "WebGLRenderingContext.h"
-
#include "ANGLEInstancedArrays.h"
#include "CachedImage.h"
-#include "DOMWindow.h"
-#include "EXTDrawBuffers.h"
+#include "EXTBlendMinMax.h"
+#include "EXTFragDepth.h"
+#include "EXTShaderTextureLOD.h"
#include "EXTTextureFilterAnisotropic.h"
-#include "ExceptionCode.h"
+#include "EXTsRGB.h"
#include "Extensions3D.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "FrameView.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
-#include "ImageBuffer.h"
#include "ImageData.h"
-#include "IntSize.h"
-#include "Logging.h"
-#include "NotImplemented.h"
#include "OESElementIndexUint.h"
#include "OESStandardDerivatives.h"
#include "OESTextureFloat.h"
@@ -55,2572 +47,437 @@
#include "OESTextureHalfFloat.h"
#include "OESTextureHalfFloatLinear.h"
#include "OESVertexArrayObject.h"
-#include "Page.h"
#include "RenderBox.h"
-#include "Settings.h"
-#include "WebGLActiveInfo.h"
-#include "WebGLBuffer.h"
#include "WebGLCompressedTextureATC.h"
#include "WebGLCompressedTexturePVRTC.h"
#include "WebGLCompressedTextureS3TC.h"
-#include "WebGLContextAttributes.h"
-#include "WebGLContextEvent.h"
-#include "WebGLContextGroup.h"
#include "WebGLDebugRendererInfo.h"
#include "WebGLDebugShaders.h"
#include "WebGLDepthTexture.h"
-#include "WebGLFramebuffer.h"
+#include "WebGLDrawBuffers.h"
#include "WebGLLoseContext.h"
-#include "WebGLProgram.h"
-#include "WebGLRenderbuffer.h"
-#include "WebGLShader.h"
-#include "WebGLShaderPrecisionFormat.h"
-#include "WebGLTexture.h"
-#include "WebGLUniformLocation.h"
-
-#include <runtime/Operations.h>
-#include <runtime/TypedArrayInlines.h>
-#include <runtime/Uint32Array.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-
-#if PLATFORM(WIN) || (PLATFORM(GTK) && OS(WINDOWS))
-#undef NO_ERROR
-#endif
-
-#if PLATFORM(GTK)
-#undef VERSION
-#endif
+#include "WebGLVertexArrayObjectOES.h"
+#include <JavaScriptCore/GenericTypedArrayViewInlines.h>
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <JavaScriptCore/JSCellInlines.h>
+#include <JavaScriptCore/JSGenericTypedArrayViewInlines.h>
+#include <heap/HeapInlines.h>
namespace WebCore {
-const double secondsBetweenRestoreAttempts = 1.0;
-const int maxGLErrorsAllowedToConsole = 256;
-
-namespace {
-
- class ScopedDrawingBufferBinder {
- public:
- ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
- : m_drawingBuffer(drawingBuffer)
- , m_framebufferBinding(framebufferBinding)
- {
- // Commit DrawingBuffer if needed (e.g., for multisampling)
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->commit();
- }
-
- ~ScopedDrawingBufferBinder()
- {
- // Restore DrawingBuffer if needed
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->bind();
- }
-
- private:
- DrawingBuffer* m_drawingBuffer;
- WebGLFramebuffer* m_framebufferBinding;
- };
-
- Platform3DObject objectOrZero(WebGLObject* object)
- {
- return object ? object->object() : 0;
- }
-
- void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
- {
- ASSERT(clippedStart && clippedRange);
- if (start < 0) {
- range += start;
- start = 0;
- }
- GC3Dint end = start + range;
- if (end > sourceRange)
- range -= end - sourceRange;
- *clippedStart = start;
- *clippedRange = range;
- }
-
- // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
- bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
- GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
- GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
- {
- ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
- clip1D(x, width, sourceWidth, clippedX, clippedWidth);
- clip1D(y, height, sourceHeight, clippedY, clippedHeight);
- return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
- }
-
- GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
- {
- if (value < min)
- value = min;
- if (value > max)
- value = max;
- return value;
- }
-
- // Return true if a character belongs to the ASCII subset as defined in
- // GLSL ES 1.0 spec section 3.1.
- bool validateCharacter(unsigned char c)
- {
- // Printing characters are valid except " $ ` @ \ ' DEL.
- if (c >= 32 && c <= 126
- && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
- return true;
- // Horizontal tab, line feed, vertical tab, form feed, carriage return
- // are also valid.
- if (c >= 9 && c <= 13)
- return true;
- return false;
- }
-
- bool isPrefixReserved(const String& name)
- {
- if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
- return true;
- return false;
- }
-
- // Strips comments from shader text. This allows non-ASCII characters
- // to be used in comments without potentially breaking OpenGL
- // implementations not expecting characters outside the GLSL ES set.
- class StripComments {
- public:
- StripComments(const String& str)
- : m_parseState(BeginningOfLine)
- , m_sourceString(str)
- , m_length(str.length())
- , m_position(0)
- {
- parse();
- }
-
- String result()
- {
- return m_builder.toString();
- }
-
- private:
- bool hasMoreCharacters() const
- {
- return (m_position < m_length);
- }
-
- void parse()
- {
- while (hasMoreCharacters()) {
- process(current());
- // process() might advance the position.
- if (hasMoreCharacters())
- advance();
- }
- }
-
- void process(UChar);
-
- bool peek(UChar& character) const
- {
- if (m_position + 1 >= m_length)
- return false;
- character = m_sourceString[m_position + 1];
- return true;
- }
-
- UChar current() const
- {
- ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
- return m_sourceString[m_position];
- }
-
- void advance()
- {
- ++m_position;
- }
-
- bool isNewline(UChar character) const
- {
- // Don't attempt to canonicalize newline related characters.
- return (character == '\n' || character == '\r');
- }
-
- void emit(UChar character)
- {
- m_builder.append(character);
- }
-
- enum ParseState {
- // Have not seen an ASCII non-whitespace character yet on
- // this line. Possible that we might see a preprocessor
- // directive.
- BeginningOfLine,
-
- // Have seen at least one ASCII non-whitespace character
- // on this line.
- MiddleOfLine,
-
- // Handling a preprocessor directive. Passes through all
- // characters up to the end of the line. Disables comment
- // processing.
- InPreprocessorDirective,
-
- // Handling a single-line comment. The comment text is
- // replaced with a single space.
- InSingleLineComment,
-
- // Handling a multi-line comment. Newlines are passed
- // through to preserve line numbers.
- InMultiLineComment
- };
-
- ParseState m_parseState;
- String m_sourceString;
- unsigned m_length;
- unsigned m_position;
- StringBuilder m_builder;
- };
-
- void StripComments::process(UChar c)
- {
- if (isNewline(c)) {
- // No matter what state we are in, pass through newlines
- // so we preserve line numbers.
- emit(c);
-
- if (m_parseState != InMultiLineComment)
- m_parseState = BeginningOfLine;
-
- return;
- }
-
- UChar temp = 0;
- switch (m_parseState) {
- case BeginningOfLine:
- if (WTF::isASCIISpace(c)) {
- emit(c);
- break;
- }
-
- if (c == '#') {
- m_parseState = InPreprocessorDirective;
- emit(c);
- break;
- }
-
- // Transition to normal state and re-handle character.
- m_parseState = MiddleOfLine;
- process(c);
- break;
-
- case MiddleOfLine:
- if (c == '/' && peek(temp)) {
- if (temp == '/') {
- m_parseState = InSingleLineComment;
- emit(' ');
- advance();
- break;
- }
-
- if (temp == '*') {
- m_parseState = InMultiLineComment;
- // Emit the comment start in case the user has
- // an unclosed comment and we want to later
- // signal an error.
- emit('/');
- emit('*');
- advance();
- break;
- }
- }
-
- emit(c);
- break;
-
- case InPreprocessorDirective:
- // No matter what the character is, just pass it
- // through. Do not parse comments in this state. This
- // might not be the right thing to do long term, but it
- // should handle the #error preprocessor directive.
- emit(c);
- break;
-
- case InSingleLineComment:
- // The newline code at the top of this function takes care
- // of resetting our state when we get out of the
- // single-line comment. Swallow all other characters.
- break;
-
- case InMultiLineComment:
- if (c == '*' && peek(temp) && temp == '/') {
- emit('*');
- emit('/');
- m_parseState = MiddleOfLine;
- advance();
- break;
- }
-
- // Swallow all other characters. Unclear whether we may
- // want or need to just emit a space per character to try
- // to preserve column numbers for debugging purposes.
- break;
- }
- }
-} // namespace anonymous
-
-class WebGLStateRestorer {
-public:
- WebGLStateRestorer(WebGLRenderingContext* context,
- bool changed)
- : m_context(context)
- , m_changed(changed)
- {
- }
-
- ~WebGLStateRestorer()
- {
- m_context->cleanupAfterGraphicsCall(m_changed);
- }
-
-private:
- WebGLRenderingContext* m_context;
- bool m_changed;
-};
-
-class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onContextLost() override { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
- virtual ~WebGLRenderingContextLostCallback() {}
-private:
- WebGLRenderingContext* m_context;
-};
-
-class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onErrorMessage(const String& message, GC3Dint) override
- {
- if (m_context->m_synthesizedErrorsToConsole)
- m_context->printGLErrorToConsole(message);
- }
- virtual ~WebGLRenderingContextErrorMessageCallback() { }
-private:
- WebGLRenderingContext* m_context;
-};
-
-OwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement& passedCanvas, GraphicsContext3DAttributes attributes)
+ : WebGLRenderingContextBase(passedCanvas, attributes)
{
- Document& document = canvas->document();
- Frame* frame = document.frame();
- if (!frame)
- return nullptr;
-
- // The FrameLoaderClient might creation of a new WebGL context despite the page settings; in
- // particular, if WebGL contexts were lost one or more times via the GL_ARB_robustness extension.
- if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled())) {
- canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL context."));
- return nullptr;
- }
-
- HostWindow* hostWindow = document.view()->root()->hostWindow();
- GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
-
- if (attributes.antialias) {
- if (!frame->settings().openGLMultisamplingEnabled())
- attributes.antialias = false;
- }
-
- attributes.noExtensions = true;
- attributes.shareResources = false;
- attributes.preferDiscreteGPU = true;
-
- if (frame->settings().multithreadedWebGLEnabled())
- attributes.multithreaded = true;
-
- if (frame->settings().forceSoftwareWebGLRendering())
- attributes.forceSoftwareRenderer = true;
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
-
- if (!context || !context->makeContextCurrent()) {
- canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
- return nullptr;
- }
-
- Extensions3D* extensions = context->getExtensions();
- if (extensions->supports("GL_EXT_debug_marker"))
- extensions->pushGroupMarkerEXT("WebGLRenderingContext");
-
- OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes));
- renderingContext->suspendIfNeeded();
-
- return renderingContext.release();
}
-WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
- GraphicsContext3D::Attributes attributes)
- : CanvasRenderingContext(passedCanvas)
- , ActiveDOMObject(&passedCanvas->document())
- , m_context(context)
- , m_drawingBuffer(0)
- , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
- , m_restoreAllowed(false)
- , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
- , m_generatedImageCache(4)
- , m_contextLost(false)
- , m_contextLostMode(SyntheticLostContext)
- , m_attributes(attributes)
- , m_synthesizedErrorsToConsole(true)
- , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement& passedCanvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes)
+ : WebGLRenderingContextBase(passedCanvas, WTFMove(context), attributes)
{
- ASSERT(m_context);
- m_contextGroup = WebGLContextGroup::create();
- m_contextGroup->addContext(this);
-
- m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
-
- if (m_drawingBuffer)
- m_drawingBuffer->bind();
-
- setupFlags();
- initializeNewContext();
+ initializeVertexArrayObjects();
}
-void WebGLRenderingContext::initializeNewContext()
+void WebGLRenderingContext::initializeVertexArrayObjects()
{
- ASSERT(!m_contextLost);
- m_needsUpdate = true;
- m_markedCanvasDirty = false;
- m_activeTextureUnit = 0;
- m_packAlignment = 4;
- m_unpackAlignment = 4;
- m_unpackFlipY = false;
- m_unpackPremultiplyAlpha = false;
- m_unpackColorspaceConversion = GraphicsContext3D::BROWSER_DEFAULT_WEBGL;
- m_boundArrayBuffer = 0;
- m_currentProgram = 0;
- m_framebufferBinding = 0;
- m_renderbufferBinding = 0;
- m_depthMask = true;
- m_stencilEnabled = false;
- m_stencilMask = 0xFFFFFFFF;
- m_stencilMaskBack = 0xFFFFFFFF;
- m_stencilFuncRef = 0;
- m_stencilFuncRefBack = 0;
- m_stencilFuncMask = 0xFFFFFFFF;
- m_stencilFuncMaskBack = 0xFFFFFFFF;
- m_layerCleared = false;
- m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
- m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
- m_scissorEnabled = false;
- m_clearDepth = 1;
- m_clearStencil = 0;
- m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
-
- GC3Dint numCombinedTextureImageUnits = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
- m_textureUnits.clear();
- m_textureUnits.resize(numCombinedTextureImageUnits);
-
- GC3Dint numVertexAttribs = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
- m_maxVertexAttribs = numVertexAttribs;
-
- m_maxTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
- m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
- m_maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
- m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
- m_maxRenderbufferSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
-
- // These two values from EXT_draw_buffers are lazily queried.
- m_maxDrawBuffers = 0;
- m_maxColorAttachments = 0;
-
- m_backDrawBuffer = GraphicsContext3D::BACK;
- m_drawBuffersWebGLRequirementsChecked = false;
- m_drawBuffersSupported = false;
-
- m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
- addContextObject(m_defaultVertexArrayObject.get());
+ m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(*this, WebGLVertexArrayObjectOES::Type::Default);
+ addContextObject(*m_defaultVertexArrayObject);
m_boundVertexArrayObject = m_defaultVertexArrayObject;
-
- m_vertexAttribValue.resize(m_maxVertexAttribs);
-
- if (!isGLES2NPOTStrict())
- createFallbackBlackTextures1x1();
if (!isGLES2Compliant())
initVertexAttrib0();
-
- IntSize canvasSize = clampedCanvasSize();
- if (m_drawingBuffer)
- m_drawingBuffer->reset(canvasSize);
-
- m_context->reshape(canvasSize.width(), canvasSize.height());
- m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
- m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
-
- m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
- m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
-}
-
-void WebGLRenderingContext::setupFlags()
-{
- ASSERT(m_context);
-
- if (Page* page = canvas()->document().page())
- m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
-
- m_isGLES2Compliant = m_context->isGLES2Compliant();
- m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->isEnabled("GL_CHROMIUM_strict_attribs");
- m_isResourceSafe = m_context->getExtensions()->isEnabled("GL_CHROMIUM_resource_safe");
- if (m_isGLES2Compliant) {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture_npot");
- m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_packed_depth_stencil");
- } else {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_ARB_texture_non_power_of_two");
- m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_EXT_packed_depth_stencil");
- }
- m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_robustness");
-}
-
-bool WebGLRenderingContext::allowPrivilegedExtensions() const
-{
- if (Page* page = canvas()->document().page())
- return page->settings().privilegedWebGLExtensionsEnabled();
- return false;
-}
-
-void WebGLRenderingContext::addCompressedTextureFormat(GC3Denum format)
-{
- if (!m_compressedTextureFormats.contains(format))
- m_compressedTextureFormats.append(format);
-}
-
-WebGLRenderingContext::~WebGLRenderingContext()
-{
- // Remove all references to WebGLObjects so if they are the last reference
- // they will be freed before the last context is removed from the context group.
- m_boundArrayBuffer = nullptr;
- m_defaultVertexArrayObject = nullptr;
- m_boundVertexArrayObject = nullptr;
- m_vertexAttrib0Buffer = nullptr;
- m_currentProgram = nullptr;
- m_framebufferBinding = nullptr;
- m_renderbufferBinding = nullptr;
-
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- m_textureUnits[i].texture2DBinding = nullptr;
- m_textureUnits[i].textureCubeMapBinding = nullptr;
- }
-
- m_blackTexture2D = nullptr;
- m_blackTextureCubeMap = nullptr;
-
- detachAndRemoveAllObjects();
- destroyGraphicsContext3D();
- m_contextGroup->removeContext(this);
-}
-
-void WebGLRenderingContext::destroyGraphicsContext3D()
-{
- // The drawing buffer holds a context reference. It must also be destroyed
- // in order for the context to be released.
- if (m_drawingBuffer)
- m_drawingBuffer.clear();
-
- if (m_context) {
- m_context->setContextLostCallback(nullptr);
- m_context->setErrorMessageCallback(nullptr);
- m_context.clear();
- }
-}
-
-void WebGLRenderingContext::markContextChanged()
-{
- if (m_framebufferBinding)
- return;
-
- m_context->markContextChanged();
-
- if (m_drawingBuffer)
- m_drawingBuffer->markContentsChanged();
-
- m_layerCleared = false;
-#if USE(ACCELERATED_COMPOSITING)
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing()) {
- m_markedCanvasDirty = true;
- canvas()->clearCopiedImage();
- renderBox->contentChanged(CanvasChanged);
- } else {
-#endif
- if (!m_markedCanvasDirty) {
- m_markedCanvasDirty = true;
- canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
- }
-#if USE(ACCELERATED_COMPOSITING)
- }
-#endif
-}
-
-bool WebGLRenderingContext::clearIfComposited(GC3Dbitfield mask)
-{
- if (isContextLost())
- return false;
-
- if (!m_context->layerComposited() || m_layerCleared
- || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
- return false;
-
- RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
-
- // Determine if it's possible to combine the clear the user asked for and this clear.
- bool combinedClear = mask && !m_scissorEnabled;
-
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
- if (combinedClear && (mask & GraphicsContext3D::COLOR_BUFFER_BIT))
- m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
- m_colorMask[1] ? m_clearColor[1] : 0,
- m_colorMask[2] ? m_clearColor[2] : 0,
- m_colorMask[3] ? m_clearColor[3] : 0);
- else
- m_context->clearColor(0, 0, 0, 0);
- m_context->colorMask(true, true, true, true);
- GC3Dbitfield clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
- if (contextAttributes->depth()) {
- if (!combinedClear || !m_depthMask || !(mask & GraphicsContext3D::DEPTH_BUFFER_BIT))
- m_context->clearDepth(1.0f);
- clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
- m_context->depthMask(true);
- }
- if (contextAttributes->stencil()) {
- if (combinedClear && (mask & GraphicsContext3D::STENCIL_BUFFER_BIT))
- m_context->clearStencil(m_clearStencil & m_stencilMask);
- else
- m_context->clearStencil(0);
- clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xFFFFFFFF);
- }
- if (m_drawingBuffer)
- m_drawingBuffer->clearFramebuffers(clearMask);
- else {
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
- m_context->clear(clearMask);
- }
-
- restoreStateAfterClear();
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- m_layerCleared = true;
-
- return combinedClear;
-}
-
-void WebGLRenderingContext::restoreStateAfterClear()
-{
- // Restore the state that the context set.
- if (m_scissorEnabled)
- m_context->enable(GraphicsContext3D::SCISSOR_TEST);
- m_context->clearColor(m_clearColor[0], m_clearColor[1],
- m_clearColor[2], m_clearColor[3]);
- m_context->colorMask(m_colorMask[0], m_colorMask[1],
- m_colorMask[2], m_colorMask[3]);
- m_context->clearDepth(m_clearDepth);
- m_context->clearStencil(m_clearStencil);
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, m_stencilMask);
- m_context->depthMask(m_depthMask);
-}
-
-void WebGLRenderingContext::markLayerComposited()
-{
- m_context->markLayerComposited();
-}
-
-void WebGLRenderingContext::paintRenderingResultsToCanvas()
-{
- if (canvas()->document().printing())
- canvas()->clearPresentationCopy();
-
- // Until the canvas is written to by the application, the clear that
- // happened after it was composited should be ignored by the compositor.
- if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
- m_context->paintCompositedResultsToCanvas(canvas()->buffer());
-
- canvas()->makePresentationCopy();
- } else
- canvas()->clearPresentationCopy();
- clearIfComposited();
-
- if (!m_markedCanvasDirty && !m_layerCleared)
- return;
-
- canvas()->clearCopiedImage();
- m_markedCanvasDirty = false;
-
- if (m_drawingBuffer)
- m_drawingBuffer->commit();
- m_context->paintRenderingResultsToCanvas(canvas()->buffer(), m_drawingBuffer.get());
-
- if (m_drawingBuffer) {
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
- }
-}
-
-PassRefPtr<ImageData> WebGLRenderingContext::paintRenderingResultsToImageData()
-{
- clearIfComposited();
- if (m_drawingBuffer)
- m_drawingBuffer->commit();
- RefPtr<ImageData> imageData = m_context->paintRenderingResultsToImageData(m_drawingBuffer.get());
-
- if (m_drawingBuffer) {
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
- }
-
- return imageData;
-}
-
-void WebGLRenderingContext::reshape(int width, int height)
-{
- // This is an approximation because at WebGLRenderingContext level we don't
- // know if the underlying FBO uses textures or renderbuffers.
- GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
- // Limit drawing buffer size to 4k to avoid memory exhaustion.
- const int sizeUpperLimit = 4096;
- maxSize = std::min(maxSize, sizeUpperLimit);
- GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
- GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
- width = clamp(width, 1, maxWidth);
- height = clamp(height, 1, maxHeight);
-
- if (m_needsUpdate) {
-#if USE(ACCELERATED_COMPOSITING)
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing())
- renderBox->contentChanged(CanvasChanged);
-#endif
- m_needsUpdate = false;
- }
-
- // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
- // clear (and this matches what reshape will do).
- if (m_drawingBuffer) {
- m_drawingBuffer->reset(IntSize(width, height));
- restoreStateAfterClear();
- } else
- m_context->reshape(width, height);
-
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].texture2DBinding.get()));
- m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-}
-
-int WebGLRenderingContext::drawingBufferWidth() const
-{
- if (m_drawingBuffer)
- return m_drawingBuffer->size().width();
-
- return m_context->getInternalFramebufferSize().width();
-}
-
-int WebGLRenderingContext::drawingBufferHeight() const
-{
- if (m_drawingBuffer)
- return m_drawingBuffer->size().height();
-
- return m_context->getInternalFramebufferSize().height();
-}
-
-unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GraphicsContext3D::BYTE:
- return sizeof(GC3Dbyte);
- case GraphicsContext3D::UNSIGNED_BYTE:
- return sizeof(GC3Dubyte);
- case GraphicsContext3D::SHORT:
- return sizeof(GC3Dshort);
- case GraphicsContext3D::UNSIGNED_SHORT:
- return sizeof(GC3Dushort);
- case GraphicsContext3D::INT:
- return sizeof(GC3Dint);
- case GraphicsContext3D::UNSIGNED_INT:
- return sizeof(GC3Duint);
- case GraphicsContext3D::FLOAT:
- return sizeof(GC3Dfloat);
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range");
- return;
- }
- m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
- m_context->activeTexture(texture);
-
- if (m_drawingBuffer)
- m_drawingBuffer->setActiveTextureUnit(texture);
-
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
- return;
- if (!program->attachShader(shader)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
- return;
- }
- m_context->attachShader(objectOrZero(program), objectOrZero(shader));
- shader->onAttached();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
- return;
- if (!validateLocationLength("bindAttribLocation", name))
- return;
- if (!validateString("bindAttribLocation", name))
- return;
- if (isPrefixReserved(name)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bindAttribLocation", "index out of range");
- return;
- }
- m_context->bindAttribLocation(objectOrZero(program), index, name);
- cleanupAfterGraphicsCall(false);
-}
-
-bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
-{
- deleted = false;
- if (isContextLost())
- return false;
- if (object) {
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
- return false;
- }
- deleted = !object->object();
- }
- return true;
-}
-
-void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
- return;
- }
- if (target == GraphicsContext3D::ARRAY_BUFFER)
- m_boundArrayBuffer = buffer;
- else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
- m_boundVertexArrayObject->setElementArrayBuffer(buffer);
- else {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target");
- return;
- }
-
- m_context->bindBuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setTarget(target);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target");
- return;
- }
- m_framebufferBinding = buffer;
- if (m_drawingBuffer)
- m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
- if (!m_framebufferBinding && m_drawingBuffer) {
- // Instead of binding fb 0, bind the drawing buffer.
- m_drawingBuffer->bind();
- } else
- m_context->bindFramebuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setHasEverBeenBound();
- applyStencilTest();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
- return;
- if (deleted)
- renderBuffer = 0;
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target");
- return;
- }
- m_renderbufferBinding = renderBuffer;
- m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
- if (renderBuffer)
- renderBuffer->setHasEverBeenBound();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindTexture", texture, deleted))
- return;
- if (deleted)
- texture = 0;
- if (texture && texture->getTarget() && texture->getTarget() != target) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
- return;
- }
- GC3Dint maxLevel = 0;
- if (target == GraphicsContext3D::TEXTURE_2D) {
- m_textureUnits[m_activeTextureUnit].texture2DBinding = texture;
- maxLevel = m_maxTextureLevel;
-
- if (m_drawingBuffer && !m_activeTextureUnit)
- m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
-
- } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
- m_textureUnits[m_activeTextureUnit].textureCubeMapBinding = texture;
- maxLevel = m_maxCubeMapTextureLevel;
- } else {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
- return;
- }
- m_context->bindTexture(target, objectOrZero(texture));
- if (texture)
- texture->setTarget(target, maxLevel);
-
- // Note: previously we used to automatically set the TEXTURE_WRAP_R
- // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
- // ES 2.0 doesn't expose this flag (a bug in the specification) and
- // otherwise the application has no control over the seams in this
- // dimension. However, it appears that supporting this properly on all
- // platforms is fairly involved (will require a HashMap from texture ID
- // in all ports), and we have not had any complaints, so the logic has
- // been removed.
-
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
-{
- if (isContextLost())
- return;
- m_context->blendColor(red, green, blue, alpha);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::blendEquation(GC3Denum mode)
-{
- if (isContextLost() || !validateBlendEquation("blendEquation", mode))
- return;
- m_context->blendEquation(mode);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- if (isContextLost() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha))
- return;
- m_context->blendEquationSeparate(modeRGB, modeAlpha);
- cleanupAfterGraphicsCall(false);
-}
-
-
-void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
-{
- if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
- return;
- m_context->blendFunc(sfactor, dfactor);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- // Note: Alpha does not have the same restrictions as RGB.
- if (isContextLost() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB))
- return;
- m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (size < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0");
- return;
- }
- if (!size) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size == 0");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(static_cast<GC3Dsizeiptr>(size))) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->bufferData(target, data->byteLength(), data->data(), usage);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
- return;
- }
- }
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
- return;
- }
- }
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
- cleanupAfterGraphicsCall(false);
-}
-
-GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
-{
- if (isContextLost())
- return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
- return 0;
- }
- if (!m_framebufferBinding || !m_framebufferBinding->object())
- return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
- const char* reason = "framebuffer incomplete";
- GC3Denum result = m_framebufferBinding->checkStatus(&reason);
- if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
- printGLWarningToConsole("checkFramebufferStatus", reason);
- return result;
- }
- result = m_context->checkFramebufferStatus(target);
- cleanupAfterGraphicsCall(false);
- return result;
-}
-
-void WebGLRenderingContext::clear(GC3Dbitfield mask)
-{
- if (isContextLost())
- return;
- if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
- return;
- }
- if (!clearIfComposited(mask))
- m_context->clear(mask);
- cleanupAfterGraphicsCall(true);
-}
-
-void WebGLRenderingContext::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
-{
- if (isContextLost())
- return;
- if (std::isnan(r))
- r = 0;
- if (std::isnan(g))
- g = 0;
- if (std::isnan(b))
- b = 0;
- if (std::isnan(a))
- a = 1;
- m_clearColor[0] = r;
- m_clearColor[1] = g;
- m_clearColor[2] = b;
- m_clearColor[3] = a;
- m_context->clearColor(r, g, b, a);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::clearDepth(GC3Dfloat depth)
-{
- if (isContextLost())
- return;
- m_clearDepth = depth;
- m_context->clearDepth(depth);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::clearStencil(GC3Dint s)
-{
- if (isContextLost())
- return;
- m_clearStencil = s;
- m_context->clearStencil(s);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- if (isContextLost())
- return;
- m_colorMask[0] = red;
- m_colorMask[1] = green;
- m_colorMask[2] = blue;
- m_colorMask[3] = alpha;
- m_context->colorMask(red, green, blue, alpha);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("compileShader", shader))
- return;
- m_context->compileShader(objectOrZero(shader));
- GC3Dint value;
- m_context->getShaderiv(objectOrZero(shader), GraphicsContext3D::COMPILE_STATUS, &value);
- shader->setValid(value);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexImage2D", target, level))
- return;
-
- if (!validateCompressedTexFormat(internalformat)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
- return;
- }
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "border not 0");
- return;
- }
- if (!validateCompressedTexDimensions("compressedTexImage2D", target, level, width, height, internalformat))
- return;
- if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
- if (!tex)
- return;
- if (!isGLES2NPOTStrict()) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
- return;
- }
- }
- graphicsContext3D()->compressedTexImage2D(target, level, internalformat, width, height,
- border, data->byteLength(), data->baseAddress());
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
- tex->setCompressed();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
- return;
- if (!validateCompressedTexFormat(format)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
- return;
- }
- if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
- if (!tex)
- return;
-
- if (format != tex->getInternalFormat(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
- return;
- }
-
- if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
- return;
-
- graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
- width, height, format, data->byteLength(), data->baseAddress());
- tex->setCompressed();
- cleanupAfterGraphicsCall(false);
-}
-
-bool WebGLRenderingContext::validateSettableTexFormat(const char* functionName, GC3Denum format)
-{
- if (GraphicsContext3D::getClearBitsByFormat(format) & (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format can not be set, only rendered to");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
- return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
- return;
- }
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
- return;
- }
- clearIfComposited();
- if (isResourceSafe()) {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- } else {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
- internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
- if (clippedWidth > 0 && clippedHeight > 0) {
- m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- }
- } else
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- }
- // FIXME: if the framebuffer is not complete, none of the below should be executed.
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
- if (!tex)
- return;
- if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
- return;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
- return;
- }
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
- return;
- }
- clearIfComposited();
- if (isResourceSafe()) {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
- } else {
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- GC3Denum format = tex->getInternalFormat(target, level);
- GC3Denum type = tex->getType(target, level);
- std::unique_ptr<unsigned char[]> zero;
- if (width && height) {
- unsigned int size;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- zero = std::make_unique<unsigned char[]>(size);
- if (!zero) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory");
- return;
- }
- memset(zero.get(), 0, size);
- }
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
- if (clippedWidth > 0 && clippedHeight > 0) {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexSubImage2D(target, level, xoffset + clippedX - x, yoffset + clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- }
- } else {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
- }
- }
- cleanupAfterGraphicsCall(false);
-}
-
-PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
- addContextObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLTexture> o = WebGLTexture::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLProgram> o = WebGLProgram::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return 0;
- if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type");
- return 0;
- }
-
- RefPtr<WebGLShader> o = WebGLShader::create(this, type);
- addSharedObject(o.get());
- return o;
-}
-
-void WebGLRenderingContext::cullFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- m_context->cullFace(mode);
- cleanupAfterGraphicsCall(false);
-}
-
-bool WebGLRenderingContext::deleteObject(WebGLObject* object)
-{
- if (isContextLost() || !object)
- return false;
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
- return false;
- }
- if (object->object())
- // We need to pass in context here because we want
- // things in this context unbound.
- object->deleteObject(graphicsContext3D());
- return true;
-}
-
-void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
-{
- if (!deleteObject(buffer))
- return;
- if (m_boundArrayBuffer == buffer)
- m_boundArrayBuffer = 0;
-
- m_boundVertexArrayObject->unbindBuffer(buffer);
-}
-
-void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!deleteObject(framebuffer))
- return;
- if (framebuffer == m_framebufferBinding) {
- m_framebufferBinding = 0;
- if (m_drawingBuffer) {
- m_drawingBuffer->setFramebufferBinding(0);
- // Have to call bindFramebuffer here to bind back to internal fbo.
- m_drawingBuffer->bind();
- } else
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
- }
-}
-
-void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
-{
- deleteObject(program);
- // We don't reset m_currentProgram to 0 here because the deletion of the
- // current program is delayed.
-}
-
-void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!deleteObject(renderbuffer))
- return;
- if (renderbuffer == m_renderbufferBinding)
- m_renderbufferBinding = 0;
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
-}
-
-void WebGLRenderingContext::deleteShader(WebGLShader* shader)
-{
- deleteObject(shader);
-}
-
-void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
-{
- if (!deleteObject(texture))
- return;
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- if (texture == m_textureUnits[i].texture2DBinding)
- m_textureUnits[i].texture2DBinding = nullptr;
- if (texture == m_textureUnits[i].textureCubeMapBinding)
- m_textureUnits[i].textureCubeMapBinding = nullptr;
- }
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
-}
-
-void WebGLRenderingContext::depthFunc(GC3Denum func)
-{
- if (isContextLost())
- return;
- m_context->depthFunc(func);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::depthMask(GC3Dboolean flag)
-{
- if (isContextLost())
- return;
- m_depthMask = flag;
- m_context->depthMask(flag);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
-{
- if (isContextLost())
- return;
- if (zNear > zFar) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar");
- return;
- }
- m_context->depthRange(zNear, zFar);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
- return;
- if (!program->detachShader(shader)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
- return;
- }
- m_context->detachShader(objectOrZero(program), objectOrZero(shader));
- shader->onDetached(graphicsContext3D());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::disable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("disable", cap))
- return;
- if (cap == GraphicsContext3D::STENCIL_TEST) {
- m_stencilEnabled = false;
- applyStencilTest();
- cleanupAfterGraphicsCall(false);
- return;
- }
- if (cap == GraphicsContext3D::SCISSOR_TEST) {
- m_scissorEnabled = false;
- if (m_drawingBuffer)
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->disable(cap);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = false;
-
- if (index > 0 || isGLES2Compliant()) {
- m_context->disableVertexAttribArray(index);
- cleanupAfterGraphicsCall(false);
- }
-}
-
-bool WebGLRenderingContext::validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
-{
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- if (offset < 0)
- return false;
-
- if (type == GraphicsContext3D::UNSIGNED_INT) {
- // For an unsigned int array, offset must be divisible by 4 for alignment reasons.
- if (offset % 4)
- return false;
-
- // Make uoffset an element offset.
- offset /= 4;
-
- GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 4;
- if (offset > n || count > n - offset)
- return false;
- } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
- // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
- if (offset % 2)
- return false;
-
- // Make uoffset an element offset.
- offset /= 2;
-
- GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 2;
- if (offset > n || count > n - offset)
- return false;
- } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
- GC3Dsizeiptr n = elementArrayBuffer->byteLength();
- if (offset > n || count > n - offset)
- return false;
- }
- return true;
}
-bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
-{
- // Performs conservative validation by caching a maximum index of
- // the given type per element array buffer. If all of the bound
- // array buffers have enough elements to satisfy that maximum
- // index, skips the expensive per-draw-call iteration in
- // validateIndexArrayPrecise.
-
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
- // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
- if (!numElements)
- return false;
- const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
- ASSERT(buffer);
-
- int maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
- if (maxIndex < 0) {
- // Compute the maximum index in the entire buffer for the given type of index.
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE: {
- const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_SHORT: {
- numElements /= sizeof(GC3Dushort);
- const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_INT: {
- if (!m_oesElementIndexUint)
- return false;
- numElements /= sizeof(GC3Duint);
- const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- default:
- return false;
- }
- elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
- }
-
- if (maxIndex >= 0) {
- // The number of required elements is one more than the maximum
- // index that will be accessed.
- numElementsRequired = maxIndex + 1;
- return true;
- }
-
- return false;
-}
-
-bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired)
+WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
{
- ASSERT(count >= 0 && offset >= 0);
- unsigned lastIndex = 0;
+ if (isContextLostOrPending())
+ return nullptr;
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- if (!count) {
- numElementsRequired = 0;
- return true;
- }
-
- if (!elementArrayBuffer->elementArrayBuffer())
- return false;
-
- unsigned long uoffset = offset;
- unsigned long n = count;
-
- if (type == GraphicsContext3D::UNSIGNED_INT) {
- // Make uoffset an element offset.
- uoffset /= sizeof(GC3Duint);
- const GC3Duint* p = static_cast<const GC3Duint*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
- // Make uoffset an element offset.
- uoffset /= sizeof(GC3Dushort);
- const GC3Dushort* p = static_cast<const GC3Dushort*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
- const GC3Dubyte* p = static_cast<const GC3Dubyte*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- }
-
- // Then set the last index in the index array and make sure it is valid.
- numElementsRequired = lastIndex + 1;
- return numElementsRequired > 0;
-}
-
-bool WebGLRenderingContext::validateVertexAttributes(unsigned elementCount, unsigned primitiveCount)
-{
- if (!m_currentProgram)
- return false;
-
- // Look in each enabled vertex attrib and check if they've been bound to a buffer.
- for (unsigned i = 0; i < m_maxVertexAttribs; ++i) {
- if (!m_boundVertexArrayObject->getVertexAttribState(i).validateBinding())
- return false;
- }
-
- if (elementCount <= 0)
- return true;
-
-
- // Look in each consumed vertex attrib (by the current program).
- bool sawNonInstancedAttrib = false;
- bool sawEnabledAttrib = false;
- int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
- for (int i = 0; i < numActiveAttribLocations; ++i) {
- int loc = m_currentProgram->getActiveAttribLocation(i);
- if (loc >= 0 && loc < static_cast<int>(m_maxVertexAttribs)) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(loc);
- if (state.enabled) {
- sawEnabledAttrib = true;
- // Avoid off-by-one errors in numElements computation.
- // For the last element, we will only touch the data for the
- // element and nothing beyond it.
- int bytesRemaining = static_cast<int>(state.bufferBinding->byteLength() - state.offset);
- unsigned numElements = 0;
- ASSERT(state.stride > 0);
- if (bytesRemaining >= state.bytesPerElement)
- numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
- unsigned instancesRequired = 0;
- if (state.divisor) {
- instancesRequired = ceil(static_cast<float>(primitiveCount) / state.divisor);
- if (instancesRequired > numElements)
- return false;
- } else {
- sawNonInstancedAttrib = true;
- if (elementCount > numElements)
- return false;
- }
- }
- }
- }
-
- if (!sawNonInstancedAttrib && sawEnabledAttrib)
- return false;
-
- return true;
-}
-
-bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
-{
- if (!object || !object->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
- return false;
- }
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primitiveCount)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- if (first < 0 || count < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "first or count < 0");
- return false;
- }
-
- if (!count) {
- cleanupAfterGraphicsCall(true);
- return false;
- }
-
- if (primitiveCount < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- // Ensure we have a valid rendering state
- Checked<GC3Dint, RecordOverflow> checkedFirst(first);
- Checked<GC3Dint, RecordOverflow> checkedCount(count);
- Checked<GC3Dint, RecordOverflow> checkedSum = checkedFirst + checkedCount;
- Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
- if (checkedSum.hasOverflowed() || checkedPrimitiveCount.hasOverflowed() || !validateVertexAttributes(checkedSum.unsafeGet(), checkedPrimitiveCount.unsafeGet())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
- }
- } else {
- if (!validateVertexAttributes(0)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- if (!validateDrawArrays("drawArrays", mode, first, count, 0))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant())
- vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArrays", true);
-
- m_context->drawArrays(mode, first, count);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArrays", false);
- cleanupAfterGraphicsCall(true);
-}
-
-bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primitiveCount)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT:
- break;
- case GraphicsContext3D::UNSIGNED_INT:
- if (m_oesElementIndexUint)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
- return false;
- }
-
- if (count < 0 || offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "count or offset < 0");
- return false;
- }
-
- if (!count) {
- cleanupAfterGraphicsCall(true);
- return false;
- }
-
- if (primitiveCount < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
- return false;
- }
-
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- // Ensure we have a valid rendering state
- if (!validateElementArraySize(count, type, static_cast<GC3Dintptr>(offset))) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "request out of bounds for current ELEMENT_ARRAY_BUFFER");
- return false;
- }
- if (!count)
- return false;
-
- Checked<GC3Dint, RecordOverflow> checkedCount(count);
- Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
- if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
- }
-
- if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
- if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast<GC3Dintptr>(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
+ if (equalIgnoringASCIICase(name, "EXT_blend_minmax")) {
+ if (!m_extBlendMinMax) {
+ m_extBlendMinMax = enableSupportedExtension("GL_EXT_blend_minmax")
+ ? std::make_unique<EXTBlendMinMax>(*this) : nullptr;
+ }
+ return m_extBlendMinMax.get();
+ }
+ if (equalIgnoringASCIICase(name, "EXT_sRGB")) {
+ if (!m_extsRGB) {
+ m_extsRGB = enableSupportedExtension("GL_EXT_sRGB")
+ ? std::make_unique<EXTsRGB>(*this) : nullptr;
+ }
+ return m_extsRGB.get();
+ }
+ if (equalIgnoringASCIICase(name, "EXT_frag_depth")) {
+ if (!m_extFragDepth) {
+ m_extFragDepth = enableSupportedExtension("GL_EXT_frag_depth")
+ ? std::make_unique<EXTFragDepth>(*this) : nullptr;
+ }
+ return m_extFragDepth.get();
+ }
+ if (equalIgnoringASCIICase(name, "EXT_shader_texture_lod")) {
+ if (!m_extShaderTextureLOD) {
+ if (!(m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_shader_texture_lod" }) || m_context->getExtensions().supports(ASCIILiteral { "GL_ARB_shader_texture_lod" })))
+ m_extShaderTextureLOD = nullptr;
+ else {
+ m_context->getExtensions().ensureEnabled(ASCIILiteral { "GL_EXT_shader_texture_lod" });
+ m_extShaderTextureLOD = std::make_unique<EXTShaderTextureLOD>(*this);
}
}
- } else {
- if (!validateVertexAttributes(0)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- unsigned numElements = 0;
- if (!validateDrawElements("drawElements", mode, count, type, offset, numElements, 0))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant()) {
- if (!numElements)
- validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
- vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
- }
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElements", true);
-
- m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElements", false);
- cleanupAfterGraphicsCall(true);
-}
-
-void WebGLRenderingContext::enable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("enable", cap))
- return;
- if (cap == GraphicsContext3D::STENCIL_TEST) {
- m_stencilEnabled = true;
- applyStencilTest();
- cleanupAfterGraphicsCall(false);
- return;
- }
- if (cap == GraphicsContext3D::SCISSOR_TEST) {
- m_scissorEnabled = true;
- if (m_drawingBuffer)
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->enable(cap);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = true;
-
- m_context->enableVertexAttribArray(index);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::finish()
-{
- if (isContextLost())
- return;
- m_context->finish();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::flush()
-{
- if (isContextLost())
- return;
- m_context->flush();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
- return;
- if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
- return;
- }
- if (buffer && !buffer->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
- return;
- }
- Platform3DObject bufferObject = objectOrZero(buffer);
- switch (attachment) {
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
- break;
- default:
- m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
- applyStencilTest();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
- return;
- if (level) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
- return;
- }
- if (texture && !texture->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
- return;
- }
- Platform3DObject textureObject = objectOrZero(texture);
- switch (attachment) {
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, GraphicsContext3D::DEPTH_ATTACHMENT, textarget, textureObject, level);
- m_context->framebufferTexture2D(target, GraphicsContext3D::STENCIL_ATTACHMENT, textarget, textureObject, level);
- break;
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- default:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
- applyStencilTest();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::frontFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- m_context->frontFace(mode);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::generateMipmap(GC3Denum target)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
- if (!tex)
- return;
- if (!tex->canGenerateMipmaps()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
- return;
- }
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=123916. Compressed textures should be allowed in WebGL 2:
- if (tex->isCompressed()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "trying to generate mipmaps from compressed texture");
- return;
- }
- if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
- return;
-
- // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
- // on Mac. Remove the hack once this driver bug is fixed.
-#if OS(DARWIN)
- bool needToResetMinFilter = false;
- if (tex->getMinFilter() != GraphicsContext3D::NEAREST_MIPMAP_LINEAR) {
- m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST_MIPMAP_LINEAR);
- needToResetMinFilter = true;
- }
-#endif
- m_context->generateMipmap(target);
-#if OS(DARWIN)
- if (needToResetMinFilter)
- m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, tex->getMinFilter());
-#endif
- tex->generateMipmapLevelInfo();
- cleanupAfterGraphicsCall(false);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
- return 0;
-
- LOG(WebGL, "Returning active attribute %d: %s", index, info.name.utf8().data());
-
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), index, info))
- return 0;
- if (!isGLES2Compliant())
- if (info.size > 1 && !info.name.endsWith("[0]"))
- info.name.append("[0]");
-
- LOG(WebGL, "Returning active uniform %d: %s", index, info.name.utf8().data());
-
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader>>& shaderObjects, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- shaderObjects.clear();
- if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
- return false;
-
- const GC3Denum shaderType[] = {
- GraphicsContext3D::VERTEX_SHADER,
- GraphicsContext3D::FRAGMENT_SHADER
- };
- for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
- WebGLShader* shader = program->getAttachedShader(shaderType[i]);
- if (shader)
- shaderObjects.append(shader);
- }
- return true;
-}
-
-GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
- return -1;
- if (!validateLocationLength("getAttribLocation", name))
- return -1;
- if (!validateString("getAttribLocation", name))
- return -1;
- if (isPrefixReserved(name))
- return -1;
- if (!program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getAttribLocation", "program not linked");
- return -1;
- }
- return m_context->getAttribLocation(objectOrZero(program), name);
-}
-
-WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
- return WebGLGetInfo();
- }
-
- if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name");
- return WebGLGetInfo();
+ return m_extShaderTextureLOD.get();
}
-
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- m_context->getBufferParameteriv(target, pname, &value);
- if (pname == GraphicsContext3D::BUFFER_SIZE)
- return WebGLGetInfo(value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
-{
- if (isContextLost())
- return 0;
- // We always need to return a new WebGLContextAttributes object to
- // prevent the user from mutating any cached version.
-
- // Also, we need to enforce requested values of "false" for depth
- // and stencil, regardless of the properties of the underlying
- // GraphicsContext3D or DrawingBuffer.
- RefPtr<WebGLContextAttributes> attributes = WebGLContextAttributes::create(m_context->getContextAttributes());
- if (!m_attributes.depth)
- attributes->setDepth(false);
- if (!m_attributes.stencil)
- attributes->setStencil(false);
- if (m_drawingBuffer) {
- // The DrawingBuffer obtains its parameters from GraphicsContext3D::getContextAttributes(),
- // but it makes its own determination of whether multisampling is supported.
- attributes->setAntialias(m_drawingBuffer->multisample());
- }
- return attributes.release();
-}
-
-GC3Denum WebGLRenderingContext::getError()
-{
- return m_context->getError();
-}
-
-WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
-{
- if (isContextLost())
- return 0;
-
- if (equalIgnoringCase(name, "WEBKIT_EXT_texture_filter_anisotropic")
- && m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic")) {
+ if (equalIgnoringASCIICase(name, "EXT_texture_filter_anisotropic") || equalIgnoringASCIICase(name, "WEBKIT_EXT_texture_filter_anisotropic")) {
if (!m_extTextureFilterAnisotropic) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic");
- m_extTextureFilterAnisotropic = EXTTextureFilterAnisotropic::create(this);
+ m_extTextureFilterAnisotropic = enableSupportedExtension("GL_EXT_texture_filter_anisotropic")
+ ? std::make_unique<EXTTextureFilterAnisotropic>(*this) : nullptr;
}
return m_extTextureFilterAnisotropic.get();
}
- if (equalIgnoringCase(name, "OES_standard_derivatives")
- && m_context->getExtensions()->supports("GL_OES_standard_derivatives")) {
+ if (equalIgnoringASCIICase(name, "OES_standard_derivatives")) {
if (!m_oesStandardDerivatives) {
- m_context->getExtensions()->ensureEnabled("GL_OES_standard_derivatives");
- m_oesStandardDerivatives = OESStandardDerivatives::create(this);
+ m_oesStandardDerivatives = enableSupportedExtension("GL_OES_standard_derivatives")
+ ? std::make_unique<OESStandardDerivatives>(*this) : nullptr;
}
return m_oesStandardDerivatives.get();
}
- if (equalIgnoringCase(name, "OES_texture_float")
- && m_context->getExtensions()->supports("GL_OES_texture_float")) {
+ if (equalIgnoringASCIICase(name, "OES_texture_float")) {
if (!m_oesTextureFloat) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_float");
- m_oesTextureFloat = OESTextureFloat::create(this);
+ m_oesTextureFloat = enableSupportedExtension("GL_OES_texture_float")
+ ? std::make_unique<OESTextureFloat>(*this) : nullptr;
}
return m_oesTextureFloat.get();
}
- if (equalIgnoringCase(name, "OES_texture_float_linear")
- && m_context->getExtensions()->supports("GL_OES_texture_float_linear")) {
+ if (equalIgnoringASCIICase(name, "OES_texture_float_linear")) {
if (!m_oesTextureFloatLinear) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_float_linear");
- m_oesTextureFloatLinear = OESTextureFloatLinear::create(this);
+ m_oesTextureFloatLinear = enableSupportedExtension("GL_OES_texture_float_linear")
+ ? std::make_unique<OESTextureFloatLinear>(*this) : nullptr;
}
return m_oesTextureFloatLinear.get();
}
- if (equalIgnoringCase(name, "OES_texture_half_float")
- && m_context->getExtensions()->supports("GL_OES_texture_half_float")) {
+ if (equalIgnoringASCIICase(name, "OES_texture_half_float")) {
if (!m_oesTextureHalfFloat) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float");
- m_oesTextureHalfFloat = OESTextureHalfFloat::create(this);
+ m_oesTextureHalfFloat = enableSupportedExtension("GL_OES_texture_half_float")
+ ? std::make_unique<OESTextureHalfFloat>(*this) : nullptr;
}
return m_oesTextureHalfFloat.get();
}
- if (equalIgnoringCase(name, "OES_texture_half_float_linear")
- && m_context->getExtensions()->supports("GL_OES_texture_half_float_linear")) {
+ if (equalIgnoringASCIICase(name, "OES_texture_half_float_linear")) {
if (!m_oesTextureHalfFloatLinear) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float_linear");
- m_oesTextureHalfFloatLinear = OESTextureHalfFloatLinear::create(this);
+ m_oesTextureHalfFloatLinear = enableSupportedExtension("GL_OES_texture_half_float_linear")
+ ? std::make_unique<OESTextureHalfFloatLinear>(*this) : nullptr;
}
return m_oesTextureHalfFloatLinear.get();
}
- if (equalIgnoringCase(name, "OES_vertex_array_object")
- && m_context->getExtensions()->supports("GL_OES_vertex_array_object")) {
+ if (equalIgnoringASCIICase(name, "OES_vertex_array_object")) {
if (!m_oesVertexArrayObject) {
- m_context->getExtensions()->ensureEnabled("GL_OES_vertex_array_object");
- m_oesVertexArrayObject = OESVertexArrayObject::create(this);
+ m_oesVertexArrayObject = enableSupportedExtension("GL_OES_vertex_array_object")
+ ? std::make_unique<OESVertexArrayObject>(*this) : nullptr;
}
return m_oesVertexArrayObject.get();
}
- if (equalIgnoringCase(name, "OES_element_index_uint")
- && m_context->getExtensions()->supports("GL_OES_element_index_uint")) {
+ if (equalIgnoringASCIICase(name, "OES_element_index_uint")) {
if (!m_oesElementIndexUint) {
- m_context->getExtensions()->ensureEnabled("GL_OES_element_index_uint");
- m_oesElementIndexUint = OESElementIndexUint::create(this);
+ m_oesElementIndexUint = enableSupportedExtension("GL_OES_element_index_uint")
+ ? std::make_unique<OESElementIndexUint>(*this) : nullptr;
}
return m_oesElementIndexUint.get();
}
- if (equalIgnoringCase(name, "WEBGL_lose_context")) {
+ if (equalIgnoringASCIICase(name, "WEBGL_lose_context")) {
if (!m_webglLoseContext)
- m_webglLoseContext = WebGLLoseContext::create(this);
+ m_webglLoseContext = std::make_unique<WebGLLoseContext>(*this);
return m_webglLoseContext.get();
}
- if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_atc"))
- && WebGLCompressedTextureATC::supported(this)) {
- if (!m_webglCompressedTextureATC)
- m_webglCompressedTextureATC = WebGLCompressedTextureATC::create(this);
+ if (equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_atc")) {
+ if (!m_webglCompressedTextureATC) {
+ m_webglCompressedTextureATC = WebGLCompressedTextureATC::supported(*this)
+ ? std::make_unique<WebGLCompressedTextureATC>(*this) : nullptr;
+ }
return m_webglCompressedTextureATC.get();
}
- if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc"))
- && WebGLCompressedTexturePVRTC::supported(this)) {
- if (!m_webglCompressedTexturePVRTC)
- m_webglCompressedTexturePVRTC = WebGLCompressedTexturePVRTC::create(this);
+ if (equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) {
+ if (!m_webglCompressedTexturePVRTC) {
+ m_webglCompressedTexturePVRTC = WebGLCompressedTexturePVRTC::supported(*this)
+ ? std::make_unique<WebGLCompressedTexturePVRTC>(*this) : nullptr;
+ }
+ return m_webglCompressedTexturePVRTC.get();
}
- if (equalIgnoringCase(name, "WEBGL_compressed_texture_s3tc")
- && WebGLCompressedTextureS3TC::supported(this)) {
- if (!m_webglCompressedTextureS3TC)
- m_webglCompressedTextureS3TC = WebGLCompressedTextureS3TC::create(this);
+ if (equalIgnoringASCIICase(name, "WEBGL_compressed_texture_s3tc")) {
+ if (!m_webglCompressedTextureS3TC) {
+ m_webglCompressedTextureS3TC = WebGLCompressedTextureS3TC::supported(*this)
+ ? std::make_unique<WebGLCompressedTextureS3TC>(*this) : nullptr;
+ }
return m_webglCompressedTextureS3TC.get();
}
- if (equalIgnoringCase(name, "WEBGL_depth_texture")
- && WebGLDepthTexture::supported(graphicsContext3D())) {
+ if (equalIgnoringASCIICase(name, "WEBGL_depth_texture")) {
if (!m_webglDepthTexture) {
- m_context->getExtensions()->ensureEnabled("GL_CHROMIUM_depth_texture");
- m_webglDepthTexture = WebGLDepthTexture::create(this);
+ m_webglDepthTexture = WebGLDepthTexture::supported(*m_context)
+ ? std::make_unique<WebGLDepthTexture>(*this) : nullptr;
}
return m_webglDepthTexture.get();
}
- if (equalIgnoringCase(name, "EXT_draw_buffers") && supportsDrawBuffers()) {
- if (!m_extDrawBuffers) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_draw_buffers");
- m_extDrawBuffers = EXTDrawBuffers::create(this);
+ if (equalIgnoringASCIICase(name, "WEBGL_draw_buffers")) {
+ if (!m_webglDrawBuffers) {
+ if (!supportsDrawBuffers())
+ m_webglDrawBuffers = nullptr;
+ else {
+ m_context->getExtensions().ensureEnabled(ASCIILiteral { "GL_EXT_draw_buffers" });
+ m_webglDrawBuffers = std::make_unique<WebGLDrawBuffers>(*this);
+ }
}
- return m_extDrawBuffers.get();
+ return m_webglDrawBuffers.get();
}
- if (equalIgnoringCase(name, "ANGLE_instanced_arrays") && ANGLEInstancedArrays::supported(this)) {
+ if (equalIgnoringASCIICase(name, "ANGLE_instanced_arrays")) {
if (!m_angleInstancedArrays) {
- m_context->getExtensions()->ensureEnabled("GL_ANGLE_instanced_arrays");
- m_angleInstancedArrays = ANGLEInstancedArrays::create(this);
+ if (!ANGLEInstancedArrays::supported(*this))
+ m_angleInstancedArrays = nullptr;
+ else {
+ m_context->getExtensions().ensureEnabled(ASCIILiteral { "GL_ANGLE_instanced_arrays" });
+ m_angleInstancedArrays = std::make_unique<ANGLEInstancedArrays>(*this);
+ }
}
return m_angleInstancedArrays.get();
}
- if (allowPrivilegedExtensions()) {
- if (equalIgnoringCase(name, "WEBGL_debug_renderer_info")) {
- if (!m_webglDebugRendererInfo)
- m_webglDebugRendererInfo = WebGLDebugRendererInfo::create(this);
- return m_webglDebugRendererInfo.get();
- }
- if (equalIgnoringCase(name, "WEBGL_debug_shaders")
- && m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source")) {
- if (!m_webglDebugShaders)
- m_webglDebugShaders = WebGLDebugShaders::create(this);
- return m_webglDebugShaders.get();
+ if (equalIgnoringASCIICase(name, "WEBGL_debug_renderer_info")) {
+ if (!m_webglDebugRendererInfo)
+ m_webglDebugRendererInfo = std::make_unique<WebGLDebugRendererInfo>(*this);
+ return m_webglDebugRendererInfo.get();
+ }
+ if (equalIgnoringASCIICase(name, "WEBGL_debug_shaders")) {
+ if (!m_webglDebugShaders) {
+ m_webglDebugShaders = m_context->getExtensions().supports(ASCIILiteral { "GL_ANGLE_translated_shader_source" })
+ ? std::make_unique<WebGLDebugShaders>(*this) : nullptr;
}
+ return m_webglDebugShaders.get();
}
- return 0;
+ return nullptr;
}
-WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
+std::optional<Vector<String>> WebGLRenderingContext::getSupportedExtensions()
{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
- return WebGLGetInfo();
+ if (isContextLost())
+ return std::nullopt;
+ Vector<String> result;
+
+ if (m_isPendingPolicyResolution)
+ return result;
+
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_blend_minmax" }))
+ result.append(ASCIILiteral { "EXT_blend_minmax" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_sRGB" }))
+ result.append(ASCIILiteral { "EXT_sRGB" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_frag_depth" }))
+ result.append(ASCIILiteral { "EXT_frag_depth" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_texture_float" }))
+ result.append(ASCIILiteral { "OES_texture_float" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_texture_float_linear" }))
+ result.append(ASCIILiteral { "OES_texture_float_linear" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_texture_half_float" }))
+ result.append(ASCIILiteral { "OES_texture_half_float" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_texture_half_float_linear" }))
+ result.append(ASCIILiteral { "OES_texture_half_float_linear" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_standard_derivatives" }))
+ result.append(ASCIILiteral { "OES_standard_derivatives" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_shader_texture_lod" }) || m_context->getExtensions().supports(ASCIILiteral { "GL_ARB_shader_texture_lod" }))
+ result.append(ASCIILiteral { "EXT_shader_texture_lod" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_EXT_texture_filter_anisotropic" }))
+ result.append(ASCIILiteral { "EXT_texture_filter_anisotropic" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_vertex_array_object" }))
+ result.append(ASCIILiteral { "OES_vertex_array_object" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_OES_element_index_uint" }))
+ result.append(ASCIILiteral { "OES_element_index_uint" });
+ result.append(ASCIILiteral { "WEBGL_lose_context" });
+ if (WebGLCompressedTextureATC::supported(*this))
+ result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_atc" });
+ if (WebGLCompressedTexturePVRTC::supported(*this))
+ result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_pvrtc" });
+ if (WebGLCompressedTextureS3TC::supported(*this))
+ result.append("WEBGL_compressed_texture_s3tc");
+ if (WebGLDepthTexture::supported(*m_context))
+ result.append(ASCIILiteral { "WEBGL_depth_texture" });
+ if (supportsDrawBuffers())
+ result.append(ASCIILiteral { "WEBGL_draw_buffers" });
+ if (ANGLEInstancedArrays::supported(*this))
+ result.append(ASCIILiteral { "ANGLE_instanced_arrays" });
+ if (m_context->getExtensions().supports(ASCIILiteral { "GL_ANGLE_translated_shader_source" }))
+ result.append(ASCIILiteral { "WEBGL_debug_shaders" });
+ result.append(ASCIILiteral { "WEBGL_debug_renderer_info" });
+
+ return result;
+}
+
+WebGLAny WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
+{
+ if (isContextLostOrPending() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ return nullptr;
+
if (!m_framebufferBinding || !m_framebufferBinding->object()) {
synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
- return WebGLGetInfo();
+ return nullptr;
}
-
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
+
+ auto* object = m_framebufferBinding->getAttachmentObject(attachment);
if (!object) {
if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(GraphicsContext3D::NONE);
+ return static_cast<unsigned>(GraphicsContext3D::NONE);
// OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
// specifies INVALID_OPERATION.
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
- return WebGLGetInfo();
+ return nullptr;
}
-
- ASSERT(object->isTexture() || object->isRenderbuffer());
+
if (object->isTexture()) {
switch (pname) {
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::TEXTURE);
+ return static_cast<unsigned>(GraphicsContext3D::TEXTURE);
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(reinterpret_cast<WebGLTexture*>(object)));
+ return makeRefPtr(reinterpret_cast<WebGLTexture&>(*object));
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- {
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
- return WebGLGetInfo(value);
- }
+ case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
+ GC3Dint value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return value;
+ }
default:
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
- return WebGLGetInfo();
+ return nullptr;
}
} else {
+ ASSERT(object->isRenderbuffer());
switch (pname) {
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
+ return static_cast<unsigned>(GraphicsContext3D::RENDERBUFFER);
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
+ return makeRefPtr(reinterpret_cast<WebGLRenderbuffer&>(*object));
+ case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
+ if (!m_extsRGB) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+ return nullptr;
+ }
+ WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
+ GC3Denum renderBufferFormat = renderBuffer->getInternalFormat();
+ ASSERT(renderBufferFormat != Extensions3D::SRGB_EXT && renderBufferFormat != Extensions3D::SRGB_ALPHA_EXT);
+ if (renderBufferFormat == Extensions3D::SRGB8_ALPHA8_EXT)
+ return static_cast<unsigned>(Extensions3D::SRGB_EXT);
+ return static_cast<unsigned>(GraphicsContext3D::LINEAR);
+ }
default:
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
+ return nullptr;
}
}
}
-WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
+bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return WebGLGetInfo();
- const int intZero = 0;
- WebGLStateRestorer(this, false);
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ // FIXME: Why does this return true unconditionally for COLOR_ATTACHMENT0,
+ // but false for other COLOR_ATTACHMENT values if m_webglDrawBuffers is false?
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ return true;
+ default:
+ if (m_webglDrawBuffers
+ && attachment >= GraphicsContext3D::COLOR_ATTACHMENT0
+ && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
+ return true;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
+ return false;
+ }
+}
+
+void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
+ return;
+ }
+ if (!validateSize("renderbufferStorage", width, height))
+ return;
+ switch (internalformat) {
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::STENCIL_INDEX8:
+ case Extensions3D::SRGB8_ALPHA8_EXT:
+ if (internalformat == Extensions3D::SRGB8_ALPHA8_EXT && !m_extsRGB) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ m_context->renderbufferStorage(target, internalformat, width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ m_renderbufferBinding->setIsValid(true);
+ m_renderbufferBinding->setSize(width, height);
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ if (isDepthStencilSupported())
+ m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setIsValid(isDepthStencilSupported());
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ applyStencilTest();
+}
+
+void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
+{
+ if (isContextLostOrPending())
+ return;
+ bool isValid = false;
+ switch (target) {
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ isValid = true;
+ break;
+ case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (m_oesStandardDerivatives)
+ isValid = true;
+ break;
+ }
+ if (!isValid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
+ return;
+ }
+ m_context->hint(target, mode);
+}
+
+void WebGLRenderingContext::clear(GC3Dbitfield mask)
+{
+ if (isContextLostOrPending())
+ return;
+ if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ return;
+ }
+ if (!clearIfComposited(mask))
+ m_context->clear(mask);
+ markContextChanged();
+}
+
+WebGLAny WebGLRenderingContext::getParameter(GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+
switch (pname) {
case GraphicsContext3D::ACTIVE_TEXTURE:
return getUnsignedIntParameter(pname);
@@ -2631,7 +488,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::ALPHA_BITS:
return getIntParameter(pname);
case GraphicsContext3D::ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
+ return m_boundArrayBuffer;
case GraphicsContext3D::BLEND:
return getBooleanParameter(pname);
case GraphicsContext3D::BLEND_COLOR:
@@ -2655,16 +512,16 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::COLOR_WRITEMASK:
return getBooleanArrayParameter(pname);
case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
- return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
+ return Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size());
case GraphicsContext3D::CULL_FACE:
return getBooleanParameter(pname);
case GraphicsContext3D::CULL_FACE_MODE:
return getUnsignedIntParameter(pname);
case GraphicsContext3D::CURRENT_PROGRAM:
- return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+ return m_currentProgram;
case GraphicsContext3D::DEPTH_BITS:
if (!m_framebufferBinding && !m_attributes.depth)
- return WebGLGetInfo(intZero);
+ return 0;
return getIntParameter(pname);
case GraphicsContext3D::DEPTH_CLEAR_VALUE:
return getFloatParameter(pname);
@@ -2679,15 +536,19 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::DITHER:
return getBooleanParameter(pname);
case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer()));
+ return makeRefPtr(m_boundVertexArrayObject->getElementArrayBuffer());
case GraphicsContext3D::FRAMEBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+ return m_framebufferBinding;
case GraphicsContext3D::FRONT_FACE:
return getUnsignedIntParameter(pname);
case GraphicsContext3D::GENERATE_MIPMAP_HINT:
return getUnsignedIntParameter(pname);
case GraphicsContext3D::GREEN_BITS:
return getIntParameter(pname);
+ case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
+ return getIntParameter(pname);
case GraphicsContext3D::LINE_WIDTH:
return getFloatParameter(pname);
case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
@@ -2713,7 +574,6 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::MAX_VIEWPORT_DIMS:
return getWebGLIntArrayParameter(pname);
case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
- // FIXME: should we always return 0 for this?
return getIntParameter(pname);
case GraphicsContext3D::PACK_ALIGNMENT:
return getIntParameter(pname);
@@ -2726,9 +586,9 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::RED_BITS:
return getIntParameter(pname);
case GraphicsContext3D::RENDERBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ return m_renderbufferBinding;
case GraphicsContext3D::RENDERER:
- return WebGLGetInfo(String("WebKit WebGL"));
+ return String { ASCIILiteral { "WebKit WebGL" } };
case GraphicsContext3D::SAMPLE_BUFFERS:
return getIntParameter(pname);
case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
@@ -2742,7 +602,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::SCISSOR_TEST:
return getBooleanParameter(pname);
case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
- return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
+ return "WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")";
case GraphicsContext3D::STENCIL_BACK_FAIL:
return getUnsignedIntParameter(pname);
case GraphicsContext3D::STENCIL_BACK_FUNC:
@@ -2759,7 +619,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
return getUnsignedIntParameter(pname);
case GraphicsContext3D::STENCIL_BITS:
if (!m_framebufferBinding && !m_attributes.stencil)
- return WebGLGetInfo(intZero);
+ return 0;
return getIntParameter(pname);
case GraphicsContext3D::STENCIL_CLEAR_VALUE:
return getIntParameter(pname);
@@ -2782,63 +642,63 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::SUBPIXEL_BITS:
return getIntParameter(pname);
case GraphicsContext3D::TEXTURE_BINDING_2D:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].texture2DBinding));
+ return m_textureUnits[m_activeTextureUnit].texture2DBinding;
case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].textureCubeMapBinding));
+ return m_textureUnits[m_activeTextureUnit].textureCubeMapBinding;
case GraphicsContext3D::UNPACK_ALIGNMENT:
return getIntParameter(pname);
case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
- return WebGLGetInfo(m_unpackFlipY);
+ return m_unpackFlipY;
case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ return m_unpackPremultiplyAlpha;
case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
- return WebGLGetInfo(m_unpackColorspaceConversion);
+ return m_unpackColorspaceConversion;
case GraphicsContext3D::VENDOR:
- return WebGLGetInfo(String("WebKit"));
+ return String { ASCIILiteral { "WebKit" } };
case GraphicsContext3D::VERSION:
- return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
+ return "WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")";
case GraphicsContext3D::VIEWPORT:
return getWebGLIntArrayParameter(pname);
case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
if (m_oesStandardDerivatives)
return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
- return WebGLGetInfo();
+ return nullptr;
case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
+ return m_context->getString(GraphicsContext3D::RENDERER);
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
+ return nullptr;
case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
+ return m_context->getString(GraphicsContext3D::VENDOR);
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
+ return nullptr;
case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
if (m_oesVertexArrayObject) {
- if (!m_boundVertexArrayObject->isDefaultObject())
- return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
- return WebGLGetInfo();
+ if (m_boundVertexArrayObject->isDefaultObject())
+ return nullptr;
+ return makeRefPtr(static_cast<WebGLVertexArrayObjectOES&>(*m_boundVertexArrayObject));
}
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
- return WebGLGetInfo();
+ return nullptr;
case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
if (m_extTextureFilterAnisotropic)
return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
+ return nullptr;
case Extensions3D::MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
- if (m_extDrawBuffers)
- return WebGLGetInfo(getMaxColorAttachments());
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_draw_buffers not enabled");
- return WebGLGetInfo();
+ if (m_webglDrawBuffers)
+ return getMaxColorAttachments();
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return nullptr;
case Extensions3D::MAX_DRAW_BUFFERS_EXT:
- if (m_extDrawBuffers)
- return WebGLGetInfo(getMaxDrawBuffers());
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_draw_buffers not enabled");
- return WebGLGetInfo();
+ if (m_webglDrawBuffers)
+ return getMaxDrawBuffers();
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return nullptr;
default:
- if (m_extDrawBuffers
+ if (m_webglDrawBuffers
&& pname >= Extensions3D::DRAW_BUFFER0_EXT
&& pname < static_cast<GC3Denum>(Extensions3D::DRAW_BUFFER0_EXT + getMaxDrawBuffers())) {
GC3Dint value = GraphicsContext3D::NONE;
@@ -2846,2751 +706,96 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
value = m_framebufferBinding->getDrawBuffer(pname);
else // emulated backbuffer
value = m_backDrawBuffer;
- return WebGLGetInfo(value);
+ return value;
}
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
- return WebGLGetInfo();
-
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::DELETE_STATUS:
- return WebGLGetInfo(program->isDeleted());
- case GraphicsContext3D::VALIDATE_STATUS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GraphicsContext3D::LINK_STATUS:
- return WebGLGetInfo(program->getLinkStatus());
- case GraphicsContext3D::ATTACHED_SHADERS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- case GraphicsContext3D::ACTIVE_ATTRIBUTES:
- case GraphicsContext3D::ACTIVE_UNIFORMS:
- m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getProgramInfoLog", program))
- return "";
- WebGLStateRestorer(this, false);
- return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
-}
-
-WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target");
- return WebGLGetInfo();
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
- return WebGLGetInfo();
- }
-
- if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
- && !m_renderbufferBinding->isValid()) {
- ASSERT(!isDepthStencilSupported());
- int value = 0;
- switch (pname) {
- case GraphicsContext3D::RENDERBUFFER_WIDTH:
- value = m_renderbufferBinding->getWidth();
- break;
- case GraphicsContext3D::RENDERBUFFER_HEIGHT:
- value = m_renderbufferBinding->getHeight();
- break;
- case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
- case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
- case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
- case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
- value = 0;
- break;
- case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
- value = 24;
- break;
- case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
- value = 8;
- break;
- case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
- return WebGLGetInfo(value);
- }
-
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::RENDERBUFFER_WIDTH:
- case GraphicsContext3D::RENDERBUFFER_HEIGHT:
- case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
- case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
- case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
- case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
- case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
- case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
- m_context->getRenderbufferParameteriv(target, pname, &value);
- return WebGLGetInfo(value);
- case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
- return WebGLGetInfo();
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::DELETE_STATUS:
- return WebGLGetInfo(shader->isDeleted());
- case GraphicsContext3D::COMPILE_STATUS:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GraphicsContext3D::SHADER_TYPE:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderInfoLog", shader))
- return "";
- WebGLStateRestorer(this, false);
- return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
-}
-
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContext::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return 0;
- switch (shaderType) {
- case GraphicsContext3D::VERTEX_SHADER:
- case GraphicsContext3D::FRAGMENT_SHADER:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
- return 0;
- }
- switch (precisionType) {
- case GraphicsContext3D::LOW_FLOAT:
- case GraphicsContext3D::MEDIUM_FLOAT:
- case GraphicsContext3D::HIGH_FLOAT:
- case GraphicsContext3D::LOW_INT:
- case GraphicsContext3D::MEDIUM_INT:
- case GraphicsContext3D::HIGH_INT:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
- return 0;
- }
-
- GC3Dint range[2] = {0, 0};
- GC3Dint precision = 0;
- m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
- return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
-}
-
-String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderSource", shader))
- return "";
- return ensureNotNull(shader->getSource());
-}
-
-Vector<String> WebGLRenderingContext::getSupportedExtensions()
-{
- Vector<String> result;
- if (m_context->getExtensions()->supports("GL_OES_texture_float"))
- result.append("OES_texture_float");
- if (m_context->getExtensions()->supports("GL_OES_texture_float_linear"))
- result.append("OES_texture_float_linear");
- if (m_context->getExtensions()->supports("GL_OES_texture_half_float"))
- result.append("OES_texture_half_float");
- if (m_context->getExtensions()->supports("GL_OES_texture_half_float_linear"))
- result.append("OES_texture_half_float_linear");
- if (m_context->getExtensions()->supports("GL_OES_standard_derivatives"))
- result.append("OES_standard_derivatives");
- if (m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic"))
- result.append("WEBKIT_EXT_texture_filter_anisotropic");
- if (m_context->getExtensions()->supports("GL_OES_vertex_array_object"))
- result.append("OES_vertex_array_object");
- if (m_context->getExtensions()->supports("GL_OES_element_index_uint"))
- result.append("OES_element_index_uint");
- result.append("WEBGL_lose_context");
- if (WebGLCompressedTextureATC::supported(this))
- result.append("WEBKIT_WEBGL_compressed_texture_atc");
- if (WebGLCompressedTexturePVRTC::supported(this))
- result.append("WEBKIT_WEBGL_compressed_texture_pvrtc");
- if (WebGLCompressedTextureS3TC::supported(this))
- result.append("WEBGL_compressed_texture_s3tc");
- if (WebGLDepthTexture::supported(graphicsContext3D()))
- result.append("WEBGL_depth_texture");
- if (supportsDrawBuffers())
- result.append("EXT_draw_buffers");
- if (ANGLEInstancedArrays::supported(this))
- result.append("ANGLE_instanced_arrays");
-
- if (allowPrivilegedExtensions()) {
- if (m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source"))
- result.append("WEBGL_debug_shaders");
- result.append("WEBGL_debug_renderer_info");
- }
-
- return result;
-}
-
-WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return WebGLGetInfo();
- WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
- if (!tex)
- return WebGLGetInfo();
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::TEXTURE_MAG_FILTER:
- case GraphicsContext3D::TEXTURE_MIN_FILTER:
- case GraphicsContext3D::TEXTURE_WRAP_S:
- case GraphicsContext3D::TEXTURE_WRAP_T:
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic) {
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- }
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getUniform", program))
- return WebGLGetInfo();
- if (!uniformLocation || uniformLocation->program() != program) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
- return WebGLGetInfo();
- }
- GC3Dint location = uniformLocation->location();
-
- WebGLStateRestorer(this, false);
- GC3Denum baseType;
- unsigned length;
- switch (uniformLocation->type()) {
- case GraphicsContext3D::BOOL:
- baseType = GraphicsContext3D::BOOL;
- length = 1;
- break;
- case GraphicsContext3D::BOOL_VEC2:
- baseType = GraphicsContext3D::BOOL;
- length = 2;
- break;
- case GraphicsContext3D::BOOL_VEC3:
- baseType = GraphicsContext3D::BOOL;
- length = 3;
- break;
- case GraphicsContext3D::BOOL_VEC4:
- baseType = GraphicsContext3D::BOOL;
- length = 4;
- break;
- case GraphicsContext3D::INT:
- baseType = GraphicsContext3D::INT;
- length = 1;
- break;
- case GraphicsContext3D::INT_VEC2:
- baseType = GraphicsContext3D::INT;
- length = 2;
- break;
- case GraphicsContext3D::INT_VEC3:
- baseType = GraphicsContext3D::INT;
- length = 3;
- break;
- case GraphicsContext3D::INT_VEC4:
- baseType = GraphicsContext3D::INT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT:
- baseType = GraphicsContext3D::FLOAT;
- length = 1;
- break;
- case GraphicsContext3D::FLOAT_VEC2:
- baseType = GraphicsContext3D::FLOAT;
- length = 2;
- break;
- case GraphicsContext3D::FLOAT_VEC3:
- baseType = GraphicsContext3D::FLOAT;
- length = 3;
- break;
- case GraphicsContext3D::FLOAT_VEC4:
- baseType = GraphicsContext3D::FLOAT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT_MAT2:
- baseType = GraphicsContext3D::FLOAT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT_MAT3:
- baseType = GraphicsContext3D::FLOAT;
- length = 9;
- break;
- case GraphicsContext3D::FLOAT_MAT4:
- baseType = GraphicsContext3D::FLOAT;
- length = 16;
- break;
- case GraphicsContext3D::SAMPLER_2D:
- case GraphicsContext3D::SAMPLER_CUBE:
- baseType = GraphicsContext3D::INT;
- length = 1;
- break;
- default:
- // Can't handle this type
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type");
- return WebGLGetInfo();
- }
- switch (baseType) {
- case GraphicsContext3D::FLOAT: {
- GC3Dfloat value[16] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformfvEXT(objectOrZero(program), location, 16 * sizeof(GC3Dfloat), value);
- else
- m_context->getUniformfv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Float32Array::create(value, length));
- }
- case GraphicsContext3D::INT: {
- GC3Dint value[4] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
- else
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Int32Array::create(value, length));
- }
- case GraphicsContext3D::BOOL: {
- GC3Dint value[4] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
- else
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length > 1) {
- bool boolValue[16] = {0};
- for (unsigned j = 0; j < length; j++)
- boolValue[j] = static_cast<bool>(value[j]);
- return WebGLGetInfo(boolValue, length);
- }
- return WebGLGetInfo(static_cast<bool>(value[0]));
- }
- default:
- notImplemented();
- }
-
- // If we get here, something went wrong in our unfortunately complex logic above
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error");
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
- return nullptr;
- if (!validateLocationLength("getUniformLocation", name))
- return nullptr;
- if (!validateString("getUniformLocation", name))
return nullptr;
- if (isPrefixReserved(name))
- return nullptr;
- if (!program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniformLocation", "program not linked");
- return nullptr;
- }
- WebGLStateRestorer(this, false);
- GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
- if (uniformLocation == -1)
- return nullptr;
-
- GC3Dint activeUniforms = 0;
- m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
- for (GC3Dint i = 0; i < activeUniforms; i++) {
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), i, info))
- return 0;
- // Strip "[0]" from the name if it's an array.
- if (info.name.endsWith("[0]"))
- info.name = info.name.left(info.name.length() - 3);
- // If it's an array, we need to iterate through each element, appending "[index]" to the name.
- for (GC3Dint index = 0; index < info.size; ++index) {
- String uniformName = info.name + "[" + String::number(index) + "]";
-
- if (name == uniformName || name == info.name)
- return WebGLUniformLocation::create(program, uniformLocation, info.type);
- }
- }
- return nullptr;
-}
-
-WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- if (isContextLost())
- return WebGLGetInfo();
-
- WebGLStateRestorer(this, false);
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range");
- return WebGLGetInfo();
- }
-
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-
- if (m_angleInstancedArrays && pname == GraphicsContext3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
- return WebGLGetInfo(state.divisor);
-
- switch (pname) {
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- if ((!isGLES2Compliant() && !index && m_boundVertexArrayObject->getVertexAttribState(0).bufferBinding == m_vertexAttrib0Buffer)
- || !state.bufferBinding
- || !state.bufferBinding->object())
- return WebGLGetInfo();
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
- return WebGLGetInfo(state.enabled);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
- return WebGLGetInfo(state.normalized);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
- return WebGLGetInfo(state.size);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
- return WebGLGetInfo(state.originalStride);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
- return WebGLGetInfo(state.type);
- case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
- return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
- return WebGLGetInfo();
}
}
-long long WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
-{
- if (isContextLost())
- return 0;
- GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
- cleanupAfterGraphicsCall(false);
- return static_cast<long long>(result);
-}
-
-void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
-{
- if (isContextLost())
- return;
- bool isValid = false;
- switch (target) {
- case GraphicsContext3D::GENERATE_MIPMAP_HINT:
- isValid = true;
- break;
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- isValid = true;
- break;
- }
- if (!isValid) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
- return;
- }
- m_context->hint(target, mode);
- cleanupAfterGraphicsCall(false);
-}
-
-GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
-{
- if (!buffer || isContextLost())
- return 0;
-
- if (!buffer->hasEverBeenBound())
- return 0;
-
- return m_context->isBuffer(buffer->object());
-}
-
-bool WebGLRenderingContext::isContextLost() const
-{
- return m_contextLost;
-}
-
-GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("isEnabled", cap))
- return 0;
- if (cap == GraphicsContext3D::STENCIL_TEST)
- return m_stencilEnabled;
- return m_context->isEnabled(cap);
-}
-
-GC3Dboolean WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!framebuffer || isContextLost())
- return 0;
-
- if (!framebuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isFramebuffer(framebuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isProgram(WebGLProgram* program)
-{
- if (!program || isContextLost())
- return 0;
-
- return m_context->isProgram(program->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!renderbuffer || isContextLost())
- return 0;
-
- if (!renderbuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isRenderbuffer(renderbuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isShader(WebGLShader* shader)
+GC3Dint WebGLRenderingContext::getMaxDrawBuffers()
{
- if (!shader || isContextLost())
+ if (!supportsDrawBuffers())
return 0;
-
- return m_context->isShader(shader->object());
+ if (!m_maxDrawBuffers)
+ m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+ return std::min(m_maxDrawBuffers, m_maxColorAttachments);
}
-GC3Dboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
+GC3Dint WebGLRenderingContext::getMaxColorAttachments()
{
- if (!texture || isContextLost())
- return 0;
-
- if (!texture->hasEverBeenBound())
+ if (!supportsDrawBuffers())
return 0;
-
- return m_context->isTexture(texture->object());
-}
-
-void WebGLRenderingContext::lineWidth(GC3Dfloat width)
-{
- if (isContextLost())
- return;
- m_context->lineWidth(width);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("linkProgram", program))
- return;
- if (!isGLES2Compliant()) {
- WebGLShader* vertexShader = program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER);
- WebGLShader* fragmentShader = program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER);
- if (!vertexShader || !vertexShader->isValid() || !fragmentShader || !fragmentShader->isValid() || !m_context->precisionsMatch(objectOrZero(vertexShader), objectOrZero(fragmentShader))) {
- program->setLinkStatus(false);
- return;
- }
- }
-
- m_context->linkProgram(objectOrZero(program));
- program->increaseLinkCount();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
-{
- if (isContextLost())
- return;
- switch (pname) {
- case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
- m_unpackFlipY = param;
- break;
- case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- m_unpackPremultiplyAlpha = param;
- break;
- case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
- if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE)
- m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
- else {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
- return;
- }
- break;
- case GraphicsContext3D::PACK_ALIGNMENT:
- case GraphicsContext3D::UNPACK_ALIGNMENT:
- if (param == 1 || param == 2 || param == 4 || param == 8) {
- if (pname == GraphicsContext3D::PACK_ALIGNMENT)
- m_packAlignment = param;
- else // GraphicsContext3D::UNPACK_ALIGNMENT:
- m_unpackAlignment = param;
- m_context->pixelStorei(pname, param);
- cleanupAfterGraphicsCall(false);
- } else {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
- return;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name");
- return;
- }
-}
-
-void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- if (isContextLost())
- return;
- m_context->polygonOffset(factor, units);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
-{
- if (isContextLost())
- return;
- // Due to WebGL's same-origin restrictions, it is not possible to
- // taint the origin using the WebGL API.
- ASSERT(canvas()->originClean());
- // Validate input parameters.
- if (!pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
- return;
- }
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::RGBA:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format");
- return;
- }
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type");
- return;
- }
- if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
- return;
- }
- // Validate array type against pixel type.
- if (pixels->getType() != JSC::TypeUint8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
- return;
- }
- // Calculate array size, taking into consideration of PACK_ALIGNMENT.
- unsigned int totalBytesRequired = 0;
- unsigned int padding = 0;
- if (!m_isRobustnessEXTSupported) {
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, "readPixels", "invalid dimensions");
- return;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
- return;
- }
- }
-
- clearIfComposited();
- void* data = pixels->baseAddress();
-
- {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->readnPixelsEXT(x, y, width, height, format, type, pixels->byteLength(), data);
- else
- m_context->readPixels(x, y, width, height, format, type, data);
- }
-
-#if OS(DARWIN)
- if (m_isRobustnessEXTSupported) // we haven't computed padding
- m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- // FIXME: remove this section when GL driver bug on Mac AND the GLES driver bug
- // on QC is fixed, i.e., when alpha is off, readPixels should
- // set alpha to 255 instead of 0.
- if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
- unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
- for (GC3Dsizei iy = 0; iy < height; ++iy) {
- for (GC3Dsizei ix = 0; ix < width; ++ix) {
- pixels[3] = 255;
- pixels += 4;
- }
- pixels += padding;
- }
- }
-#endif
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::releaseShaderCompiler()
-{
- if (isContextLost())
- return;
- m_context->releaseShaderCompiler();
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
- return;
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
- return;
- }
- if (!validateSize("renderbufferStorage", width, height))
- return;
- switch (internalformat) {
- case GraphicsContext3D::DEPTH_COMPONENT16:
- case GraphicsContext3D::RGBA4:
- case GraphicsContext3D::RGB5_A1:
- case GraphicsContext3D::RGB565:
- case GraphicsContext3D::STENCIL_INDEX8:
- m_context->renderbufferStorage(target, internalformat, width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- m_renderbufferBinding->setIsValid(true);
- m_renderbufferBinding->setSize(width, height);
- cleanupAfterGraphicsCall(false);
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- if (isDepthStencilSupported()) {
- m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
- cleanupAfterGraphicsCall(false);
- }
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->setIsValid(isDepthStencilSupported());
- m_renderbufferBinding->setInternalFormat(internalformat);
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
- applyStencilTest();
-}
-
-void WebGLRenderingContext::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
-{
- if (isContextLost())
- return;
- m_context->sampleCoverage(value, invert);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("scissor", width, height))
- return;
- m_context->scissor(x, y, width, height);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("shaderSource", shader))
- return;
- String stringWithoutComments = StripComments(string).result();
- if (!validateString("shaderSource", stringWithoutComments))
- return;
- shader->setSource(string);
- m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilFunc("stencilFunc", func))
- return;
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- m_context->stencilFunc(func, ref, mask);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilFunc("stencilFuncSeparate", func))
- return;
- switch (face) {
- case GraphicsContext3D::FRONT_AND_BACK:
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- break;
- case GraphicsContext3D::FRONT:
- m_stencilFuncRef = ref;
- m_stencilFuncMask = mask;
- break;
- case GraphicsContext3D::BACK:
- m_stencilFuncRefBack = ref;
- m_stencilFuncMaskBack = mask;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face");
- return;
- }
- m_context->stencilFuncSeparate(face, func, ref, mask);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilMask(GC3Duint mask)
-{
- if (isContextLost())
- return;
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- m_context->stencilMask(mask);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- if (isContextLost())
- return;
- switch (face) {
- case GraphicsContext3D::FRONT_AND_BACK:
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- break;
- case GraphicsContext3D::FRONT:
- m_stencilMask = mask;
- break;
- case GraphicsContext3D::BACK:
- m_stencilMaskBack = mask;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face");
- return;
- }
- m_context->stencilMaskSeparate(face, mask);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOp(fail, zfail, zpass);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOpSeparate(face, fail, zfail, zpass);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
-{
- // FIXME: For now we ignore any errors returned
- ec = 0;
- WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
- ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
- ASSERT(tex);
- ASSERT(!level || !WebGLTexture::isNPOT(width, height));
- if (!pixels) {
- // Note: Chromium's OpenGL implementation clears textures and isResourceSafe() is therefore true.
- // For other implementations, if they are using ANGLE_depth_texture, ANGLE depth textures
- // can not be cleared with texImage2D and must be cleared by binding to an fbo and calling
- // clear.
- if (isResourceSafe())
- m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0);
- else {
- bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
- border, format, type, m_unpackAlignment);
- if (!succeed)
- return;
- }
- } else {
- ASSERT(validateSettableTexFormat("texImage2D", internalformat));
- m_context->texImage2D(target, level, internalformat, width, height,
- border, format, type, pixels);
- }
- tex->setLevelInfo(target, level, internalformat, width, height, type);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
-{
- ec = 0;
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "packImage error");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ return m_maxColorAttachments;
}
-
-bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
+
+bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
{
- if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
+ // Performs conservative validation by caching a maximum index of
+ // the given type per element array buffer. If all of the bound
+ // array buffers have enough elements to satisfy that maximum
+ // index, skips the expensive per-draw-call iteration in
+ // validateIndexArrayPrecise.
+
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
return false;
-
- WebGLTexture* texture = validateTextureBinding(functionName, target, true);
- if (!texture)
+
+ GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
+ // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+ if (!numElements)
return false;
-
- if (functionType == NotTexSubImage2D) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2");
- return false;
- }
- // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
- // by checking if the ArrayBufferView is null or not.
- if (sourceType != SourceArrayBufferView) {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- }
- } else {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- if (!validateSize(functionName, xoffset, yoffset))
- return false;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "bad dimensions");
- return false;
- }
- if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
- return false;
- }
- if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
- return false;
- }
- }
-
- return true;
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
-{
- if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
- return;
- void* data = pixels ? pixels->baseAddress() : 0;
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, width, height, border,
- format, type, data, ec);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
- return;
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height, int deviceScaleFactor)
-{
- IntSize size(width, height);
- size.scale(deviceScaleFactor);
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
-
- IntRect srcRect(IntPoint(), image->size());
- IntRect destRect(IntPoint(), size);
- buf->context()->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
- return buf->copyImage(ImageBuffer::fastCopyImageMode());
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLImageElement("texImage2D", image, ec))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor());
-
- if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
- return;
-
- texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
- return;
-
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- // If possible, copy from the canvas element directly to the texture
- // via the GPU, without a read-back to system memory.
- //
- // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
- // ImageBuffer::copyToPlatformTexture implementations are fully functional.
- if (GraphicsContext3D::TEXTURE_2D == target && texture && type == texture->getType(target, level)
- && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA) && type == GraphicsContext3D::UNSIGNED_BYTE) {
- ImageBuffer* buffer = canvas->buffer();
- if (buffer && buffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- cleanupAfterGraphicsCall(false);
- return;
- }
- }
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
- else
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, ExceptionCode&)
-{
- IntSize size(video->videoWidth(), video->videoHeight());
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
- IntRect destRect(0, 0, size.width(), size.height());
- // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
- video->paintCurrentFrameInContext(buf->context(), destRect);
- return buf->copyImage(backingStoreCopy);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, ec)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
- return;
-
- // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
- // Otherwise, it will fall back to the normal SW path.
- // FIXME: The current restrictions require that format shoud be RGB or RGBA,
- // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- if (GraphicsContext3D::TEXTURE_2D == target && texture
- && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
- && type == GraphicsContext3D::UNSIGNED_BYTE
- && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
- && !level) {
- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
- cleanupAfterGraphicsCall(false);
- return;
- }
- }
-
- // Normal pure SW path.
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
- if (!image)
- return;
- texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
-void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
- if (!tex)
- return;
- switch (pname) {
- case GraphicsContext3D::TEXTURE_MIN_FILTER:
- case GraphicsContext3D::TEXTURE_MAG_FILTER:
- break;
- case GraphicsContext3D::TEXTURE_WRAP_S:
- case GraphicsContext3D::TEXTURE_WRAP_T:
- if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT)
- || (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter");
- return;
- }
- break;
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (!m_extTextureFilterAnisotropic) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
- return;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name");
- return;
- }
- if (isFloat) {
- tex->setParameterf(pname, paramf);
- m_context->texParameterf(target, pname, paramf);
- } else {
- tex->setParameteri(pname, parami);
- m_context->texParameteri(target, pname, parami);
- }
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
-{
- texParameter(target, pname, param, 0, true);
-}
-
-void WebGLRenderingContext::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
-{
- texParameter(target, pname, 0, param, false);
-}
-
-void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
-{
- // FIXME: For now we ignore any errors returned
- ec = 0;
- ASSERT(!isContextLost());
- ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
- ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
- ASSERT(validateSettableTexFormat("texSubImage2D", format));
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- if (!tex) {
- ASSERT_NOT_REACHED();
- return;
- }
- ASSERT((xoffset + width) >= 0);
- ASSERT((yoffset + height) >= 0);
- ASSERT(tex->getWidth(target, level) >= (xoffset + width));
- ASSERT(tex->getHeight(target, level) >= (yoffset + height));
- ASSERT(tex->getInternalFormat(target, level) == format);
- ASSERT(tex->getType(target, level) == type);
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
-{
- ec = 0;
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
-{
- if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
- return;
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
- return;
-
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, ec))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor());
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
- return;
-
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
-void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program");
- return;
- }
-
- m_context->uniform1f(location->location(), x);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
- return;
-
- m_context->uniform1fv(location->location(), v->length(), v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
- return;
-
- m_context->uniform1fv(location->location(), size, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program");
- return;
- }
-
- if ((location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE) && x >= (int)m_textureUnits.size()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1i", "invalid texture unit");
- return;
- }
-
- m_context->uniform1i(location->location(), x);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
- return;
-
- if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
- for (unsigned i = 0; i < v->length(); ++i) {
- if (v->data()[i] >= static_cast<int>(m_textureUnits.size())) {
- LOG(WebGL, "Texture unit size=%zu, v[%d]=%d. Location type = %04X.", m_textureUnits.size(), i, v->data()[i], location->type());
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
- return;
- }
- }
-
- m_context->uniform1iv(location->location(), v->length(), v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
- return;
-
- if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
- for (unsigned i = 0; i < static_cast<unsigned>(size); ++i) {
- if (((GC3Dint*)v)[i] >= static_cast<int>(m_textureUnits.size())) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
- return;
- }
- }
-
- m_context->uniform1iv(location->location(), size, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
- return;
- }
-
- m_context->uniform2f(location->location(), x, y);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
- return;
-
- m_context->uniform2fv(location->location(), v->length() / 2, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
- return;
-
- m_context->uniform2fv(location->location(), size / 2, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
- return;
- }
-
- m_context->uniform2i(location->location(), x, y);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
- return;
-
- m_context->uniform2iv(location->location(), v->length() / 2, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
- return;
-
- m_context->uniform2iv(location->location(), size / 2, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
- return;
- }
-
- m_context->uniform3f(location->location(), x, y, z);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
- return;
-
- m_context->uniform3fv(location->location(), v->length() / 3, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
- return;
-
- m_context->uniform3fv(location->location(), size / 3, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
- return;
- }
-
- m_context->uniform3i(location->location(), x, y, z);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
- return;
-
- m_context->uniform3iv(location->location(), v->length() / 3, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
- return;
-
- m_context->uniform3iv(location->location(), size / 3, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
- return;
- }
-
- m_context->uniform4f(location->location(), x, y, z, w);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
- return;
-
- m_context->uniform4fv(location->location(), v->length() / 4, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
- return;
-
- m_context->uniform4fv(location->location(), size / 4, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
- return;
- }
-
- m_context->uniform4i(location->location(), x, y, z, w);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
- return;
-
- m_context->uniform4iv(location->location(), v->length() / 4, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
- return;
-
- m_context->uniform4iv(location->location(), size / 4, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("useProgram", program, deleted))
- return;
- if (deleted)
- program = 0;
- if (program && !program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
- cleanupAfterGraphicsCall(false);
- return;
- }
- if (m_currentProgram != program) {
- if (m_currentProgram)
- m_currentProgram->onDetached(graphicsContext3D());
- m_currentProgram = program;
- m_context->useProgram(objectOrZero(program));
- if (program)
- program->onAttached();
- }
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject("validateProgram", program))
- return;
- m_context->validateProgram(objectOrZero(program));
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
-{
- vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
-{
- vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
-{
- vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
-}
-
-void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLost())
- return;
- switch (type) {
- case GraphicsContext3D::BYTE:
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::SHORT:
- case GraphicsContext3D::UNSIGNED_SHORT:
- case GraphicsContext3D::FLOAT:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range");
- return;
- }
- if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
- return;
- }
- if (!m_boundArrayBuffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
- return;
- }
- // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
- unsigned int typeSize = sizeInBytes(type);
- if (!typeSize) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
- return;
- }
- GC3Dsizei bytesPerElement = size * typeSize;
-
- m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
- m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("viewport", width, height))
- return;
- m_context->viewport(x, y, width, height);
- cleanupAfterGraphicsCall(false);
-}
-
-void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost");
- return;
- }
-
- m_contextGroup->loseContextGroup(mode);
-}
-
-void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost())
- return;
-
- m_contextLost = true;
- m_contextLostMode = mode;
-
- if (mode == RealLostContext) {
- // Inform the embedder that a lost context was received. In response, the embedder might
- // decide to take action such as asking the user for permission to use WebGL again.
- if (Frame* frame = canvas()->document().frame())
- frame->loader().client().didLoseWebGLContext(m_context->getExtensions()->getGraphicsResetStatusARB());
- }
-
- detachAndRemoveAllObjects();
-
- if (m_drawingBuffer) {
- // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
- m_drawingBuffer->setTexture2DBinding(0);
- m_drawingBuffer->setFramebufferBinding(0);
- }
-
- // There is no direct way to clear errors from a GL implementation and
- // looping until getError() becomes NO_ERROR might cause an infinite loop if
- // the driver or context implementation had a bug. So, loop a reasonably
- // large number of times to clear any existing errors.
- for (int i = 0; i < 100; ++i) {
- if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+ const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
+ ASSERT(buffer);
+
+ std::optional<unsigned> maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
+ if (!maxIndex) {
+ // Compute the maximum index in the entire buffer for the given type of index.
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE: {
+ const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
break;
- }
- ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
- synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
-
- // Don't allow restoration unless the context lost event has both been
- // dispatched and its default behavior prevented.
- m_restoreAllowed = false;
-
- // Always defer the dispatch of the context lost event, to implement
- // the spec behavior of queueing a task.
- m_dispatchContextLostEventTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::forceRestoreContext()
-{
- if (!isContextLost()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost");
- return;
- }
-
- if (!m_restoreAllowed) {
- if (m_contextLostMode == SyntheticLostContext)
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
- return;
- }
-
- if (!m_restoreTimer.isActive())
- m_restoreTimer.startOneShot(0);
-}
-
-#if USE(ACCELERATED_COMPOSITING)
-PlatformLayer* WebGLRenderingContext::platformLayer() const
-{
- return (!isContextLost()) ? m_context->platformLayer() : 0;
-}
-#endif
-
-void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
-{
- m_contextGroup->removeObject(object);
-}
-
-void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
-{
- ASSERT(!isContextLost());
- m_contextGroup->addObject(object);
-}
-
-void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
-{
- m_contextObjects.remove(object);
-}
-
-void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
-{
- ASSERT(!isContextLost());
- m_contextObjects.add(object);
-}
-
-void WebGLRenderingContext::detachAndRemoveAllObjects()
-{
- while (m_contextObjects.size() > 0) {
- HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
- (*it)->detachContext();
- }
-}
-
-bool WebGLRenderingContext::hasPendingActivity() const
-{
- return false;
-}
-
-void WebGLRenderingContext::stop()
-{
- if (!isContextLost()) {
- forceLostContext(SyntheticLostContext);
- destroyGraphicsContext3D();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
-{
- GC3Dboolean value = 0;
- m_context->getBooleanv(pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(GC3Denum pname)
-{
- if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
- notImplemented();
- return WebGLGetInfo(0, 0);
- }
- GC3Dboolean value[4] = {0};
- m_context->getBooleanv(pname, value);
- bool boolValue[4];
- for (int ii = 0; ii < 4; ++ii)
- boolValue[ii] = static_cast<bool>(value[ii]);
- return WebGLGetInfo(boolValue, 4);
-}
-
-WebGLGetInfo WebGLRenderingContext::getFloatParameter(GC3Denum pname)
-{
- GC3Dfloat value = 0;
- m_context->getFloatv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GC3Denum pname)
-{
- GC3Dfloat value[4] = {0};
- m_context->getFloatv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
- case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
- case GraphicsContext3D::DEPTH_RANGE:
- length = 2;
- break;
- case GraphicsContext3D::BLEND_COLOR:
- case GraphicsContext3D::COLOR_CLEAR_VALUE:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Float32Array::create(value, length));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GC3Denum pname)
-{
- GC3Dint value[4] = {0};
- m_context->getIntegerv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GraphicsContext3D::MAX_VIEWPORT_DIMS:
- length = 2;
- break;
- case GraphicsContext3D::SCISSOR_BOX:
- case GraphicsContext3D::VIEWPORT:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Int32Array::create(value, length));
-}
-
-void WebGLRenderingContext::checkTextureCompleteness(const char* functionName, bool prepareToDraw)
-{
- bool resetActiveUnit = false;
- WebGLTexture::TextureExtensionFlag extensions = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
-
- for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
- if ((m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
- || (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))) {
- if (ii != m_activeTextureUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = true;
- } else if (resetActiveUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = false;
- }
- WebGLTexture* tex2D;
- WebGLTexture* texCubeMap;
- if (prepareToDraw) {
- String msg(String("texture bound to texture unit ") + String::number(ii)
- + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
- + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
- printGLWarningToConsole(functionName, msg.utf8().data());
- tex2D = m_blackTexture2D.get();
- texCubeMap = m_blackTextureCubeMap.get();
- } else {
- tex2D = m_textureUnits[ii].texture2DBinding.get();
- texCubeMap = m_textureUnits[ii].textureCubeMapBinding.get();
- }
- if (m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
- if (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
- }
- }
- if (resetActiveUnit)
- m_context->activeTexture(m_activeTextureUnit);
-}
-
-void WebGLRenderingContext::createFallbackBlackTextures1x1()
-{
- unsigned char black[] = {0, 0, 0, 255};
- m_blackTexture2D = createTexture();
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D->object());
- m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- m_blackTextureCubeMap = createTexture();
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
-}
-
-bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat)
-{
- unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
- unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
- return (need & have) == need;
-}
-
-GC3Denum WebGLRenderingContext::getBoundFramebufferColorFormat()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferFormat();
- if (m_attributes.alpha)
- return GraphicsContext3D::RGBA;
- return GraphicsContext3D::RGB;
-}
-
-int WebGLRenderingContext::getBoundFramebufferWidth()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferWidth();
- return m_drawingBuffer ? m_drawingBuffer->size().width() : m_context->getInternalFramebufferSize().width();
-}
-
-int WebGLRenderingContext::getBoundFramebufferHeight()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferHeight();
- return m_drawingBuffer ? m_drawingBuffer->size().height() : m_context->getInternalFramebufferSize().height();
-}
-
-WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
-{
- WebGLTexture* texture = nullptr;
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (!useSixEnumsForCubeMap) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP:
- if (useSixEnumsForCubeMap) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- if (!texture)
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
- return texture;
-}
-
-bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
-{
- const unsigned maxWebGLLocationLength = 256;
- if (string.length() > maxWebGLLocationLength) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
-{
- if (x < 0 || y < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
-{
- for (size_t i = 0; i < string.length(); ++i) {
- if (!validateCharacter(string[i])) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII");
- return false;
}
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)
-{
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::RGBA:
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
- return false;
- }
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- break;
- case GraphicsContext3D::FLOAT:
- if (m_oesTextureFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::HALF_FLOAT_OES:
- if (m_oesTextureHalfFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::UNSIGNED_INT:
- case GraphicsContext3D::UNSIGNED_INT_24_8:
- case GraphicsContext3D::UNSIGNED_SHORT:
- if (m_webglDepthTexture)
+ case GraphicsContext3D::UNSIGNED_SHORT: {
+ numElements /= sizeof(GC3Dushort);
+ const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- }
-
- // Verify that the combination of format and type is supported.
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format");
- return false;
- }
- break;
- case GraphicsContext3D::RGB:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format");
- return false;
- }
- break;
- case GraphicsContext3D::RGBA:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
- && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format");
- return false;
- }
- break;
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
- return false;
- }
- if (type != GraphicsContext3D::UNSIGNED_SHORT
- && type != GraphicsContext3D::UNSIGNED_INT) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
- }
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
- return false;
- }
- if (type != GraphicsContext3D::UNSIGNED_INT_24_8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
-{
- if (level < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0");
- return false;
- }
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- if (level >= m_maxTextureLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (level >= m_maxCubeMapTextureLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- }
- // This function only checks if level is legal, so we return true and don't
- // generate INVALID_ENUM if target is illegal.
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType functionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type)
-{
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage2D && width != height) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
- return false;
- }
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
- }
-
- if (format != internalformat) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
- return false;
- }
-
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition disposition)
-{
- if (!pixels) {
- if (disposition == NullAllowed)
- return true;
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
- return false;
- }
-
- if (!validateTexFuncFormatAndType(functionName, format, type, level))
- return false;
- if (!validateSettableTexFormat(functionName, format))
- return false;
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- if (pixels->getType() != JSC::TypeUint8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
- return false;
- }
- break;
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- if (pixels->getType() != JSC::TypeUint16) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
- return false;
- }
- break;
- case GraphicsContext3D::FLOAT: // OES_texture_float
- if (pixels->getType() != JSC::TypeFloat32) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
- return false;
- }
- break;
- case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
- // As per the specification, ArrayBufferView should be null when
- // OES_texture_half_float is enabled.
- if (pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned int totalBytesRequired;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, functionName, "invalid texture dimensions");
- return false;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- if (m_unpackAlignment != 1) {
- error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
- }
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexFormat(GC3Denum format)
-{
- return m_compressedTextureFormats.contains(format);
-}
-
-bool WebGLRenderingContext::validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels)
-{
- if (!pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
- return false;
- }
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- unsigned int bytesRequired = 0;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_ATC_RGB_AMD:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
}
- break;
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
- case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
- {
- const int kBlockSize = 16;
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 8;
- const int kBlockHeight = 8;
- bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 4 + 7) / kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 16;
- const int kBlockHeight = 8;
- bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 2 + 7) / kBlockSize;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format");
- return false;
- }
-
- if (pixels->byteLength() != bytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
-{
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const GC3Dsizei kBlockWidth = 4;
- const GC3Dsizei kBlockHeight = 4;
- const GC3Dint maxTextureSize = target ? m_maxTextureSize : m_maxCubeMapTextureSize;
- const GC3Dsizei maxCompressedDimension = maxTextureSize >> level;
- bool widthValid = (level && width == 1) || (level && width == 2) || (!(width % kBlockWidth) && width <= maxCompressedDimension);
- bool heightValid = (level && height == 1) || (level && height == 2) || (!(height % kBlockHeight) && height <= maxCompressedDimension);
- if (!widthValid || !heightValid) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
- return false;
- }
- return true;
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
-{
- if (xoffset < 0 || yoffset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "xoffset or yoffset < 0");
- return false;
- }
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
- return false;
+ case GraphicsContext3D::UNSIGNED_INT: {
+ if (!m_oesElementIndexUint)
+ return false;
+ numElements /= sizeof(GC3Duint);
+ const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = maxIndex ? std::max(maxIndex.value(), static_cast<unsigned>(p[i])) : static_cast<unsigned>(p[i]);
+ break;
}
- if (width - xoffset > tex->getWidth(target, level)
- || height - yoffset > tex->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions out of range");
+ default:
return false;
}
- return validateCompressedTexDimensions(functionName, target, level, width, height, format);
+ if (maxIndex)
+ elementArrayBuffer->setCachedMaxIndex(type, maxIndex.value());
}
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GraphicsContext3D::POINTS:
- case GraphicsContext3D::LINE_STRIP:
- case GraphicsContext3D::LINE_LOOP:
- case GraphicsContext3D::LINES:
- case GraphicsContext3D::TRIANGLE_STRIP:
- case GraphicsContext3D::TRIANGLE_FAN:
- case GraphicsContext3D::TRIANGLES:
- return true;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
-{
- if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateStencilFunc(const char* functionName, GC3Denum func)
-{
- switch (func) {
- case GraphicsContext3D::NEVER:
- case GraphicsContext3D::LESS:
- case GraphicsContext3D::LEQUAL:
- case GraphicsContext3D::GREATER:
- case GraphicsContext3D::GEQUAL:
- case GraphicsContext3D::EQUAL:
- case GraphicsContext3D::NOTEQUAL:
- case GraphicsContext3D::ALWAYS:
- return true;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function");
+
+ if (!maxIndex)
return false;
- }
-}
-
-void WebGLRenderingContext::printGLErrorToConsole(const String& message)
-{
- if (!m_numGLErrorsToConsoleAllowed)
- return;
- --m_numGLErrorsToConsoleAllowed;
- printWarningToConsole(message);
-
- if (!m_numGLErrorsToConsoleAllowed)
- printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
-}
-
-void WebGLRenderingContext::printWarningToConsole(const String& message)
-{
- if (!canvas())
- return;
- canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
-}
+ // The number of required elements is one more than the maximum
+ // index that will be accessed.
+ numElementsRequired = maxIndex.value() + 1;
-bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
-{
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- switch (attachment) {
- case GraphicsContext3D::COLOR_ATTACHMENT0:
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- break;
- default:
- if (m_extDrawBuffers
- && attachment > GraphicsContext3D::COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
- return false;
- }
- return true;
+ // Check for overflow.
+ return numElementsRequired > 0;
}
bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
@@ -5599,25 +804,20 @@ bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3D
case GraphicsContext3D::FUNC_ADD:
case GraphicsContext3D::FUNC_SUBTRACT:
case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+ case Extensions3D::MIN_EXT:
+ case Extensions3D::MAX_EXT:
+ if ((mode == Extensions3D::MIN_EXT || mode == Extensions3D::MAX_EXT) && !m_extBlendMinMax) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ }
return true;
+ break;
default:
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
return false;
}
}
-bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
-{
- if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
- && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
- || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
- && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst");
- return false;
- }
- return true;
-}
-
bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
{
switch (cap) {
@@ -5637,621 +837,6 @@ bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denu
}
}
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- if (!location)
- return false;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
- return false;
- }
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- if (transpose) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE");
- return false;
- }
- if (size < requiredMinSize || (size % requiredMinSize)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
- return false;
- }
- return true;
-}
-
-WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
-{
- WebGLBuffer* buffer = 0;
- switch (target) {
- case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
- buffer = m_boundVertexArrayObject->getElementArrayBuffer().get();
- break;
- case GraphicsContext3D::ARRAY_BUFFER:
- buffer = m_boundArrayBuffer.get();
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return 0;
- }
- if (!buffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
- return 0;
- }
- switch (usage) {
- case GraphicsContext3D::STREAM_DRAW:
- case GraphicsContext3D::STATIC_DRAW:
- case GraphicsContext3D::DYNAMIC_DRAW:
- return buffer;
- }
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage");
- return 0;
-}
-
-bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionCode& ec)
-{
- if (!image || !image->cachedImage()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image");
- return false;
- }
- const URL& url = image->cachedImage()->response().url();
- if (url.isNull() || url.isEmpty() || !url.isValid()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image");
- return false;
- }
- if (wouldTaintOrigin(image)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- if (!canvas || !canvas->buffer()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no canvas");
- return false;
- }
- if (wouldTaintOrigin(canvas)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-
-#if ENABLE(VIDEO)
-bool WebGLRenderingContext::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionCode& ec)
-{
- if (!video || !video->videoWidth() || !video->videoHeight()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no video");
- return false;
- }
- if (wouldTaintOrigin(video)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-#endif
-
-void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- if (index || isGLES2Compliant()) {
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1f(index, v0);
- break;
- case 2:
- m_context->vertexAttrib2f(index, v0, v1);
- break;
- case 3:
- m_context->vertexAttrib3f(index, v0, v1, v2);
- break;
- case 4:
- m_context->vertexAttrib4f(index, v0, v1, v2, v3);
- break;
- }
- cleanupAfterGraphicsCall(false);
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.value[0] = v0;
- attribValue.value[1] = v1;
- attribValue.value[2] = v2;
- attribValue.value[3] = v3;
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return;
- }
- vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return;
- }
- if (size < expectedSize) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- if (index || isGLES2Compliant()) {
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1fv(index, v);
- break;
- case 2:
- m_context->vertexAttrib2fv(index, v);
- break;
- case 3:
- m_context->vertexAttrib3fv(index, v);
- break;
- case 4:
- m_context->vertexAttrib4fv(index, v);
- break;
- }
- cleanupAfterGraphicsCall(false);
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.initValue();
- for (int ii = 0; ii < expectedSize; ++ii)
- attribValue.value[ii] = v[ii];
-}
-
-void WebGLRenderingContext::initVertexAttrib0()
-{
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
-
- m_vertexAttrib0Buffer = createBuffer();
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
- m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
- state.bufferBinding = m_vertexAttrib0Buffer;
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
- m_context->enableVertexAttribArray(0);
- m_vertexAttrib0BufferSize = 0;
- m_vertexAttrib0BufferValue[0] = 0.0f;
- m_vertexAttrib0BufferValue[1] = 0.0f;
- m_vertexAttrib0BufferValue[2] = 0.0f;
- m_vertexAttrib0BufferValue[3] = 1.0f;
- m_forceAttrib0BufferRefill = false;
- m_vertexAttrib0UsedBefore = false;
-}
-
-bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex)
-{
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
- const VertexAttribValue& attribValue = m_vertexAttribValue[0];
- if (!m_currentProgram)
- return false;
- bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
- if (usingVertexAttrib0)
- m_vertexAttrib0UsedBefore = true;
- if (state.enabled && usingVertexAttrib0)
- return false;
- if (!usingVertexAttrib0 && !m_vertexAttrib0UsedBefore)
- return false;
- m_vertexAttrib0UsedBefore = true;
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
- GC3Dsizeiptr bufferDataSize = (numVertex + 1) * 4 * sizeof(GC3Dfloat);
- if (bufferDataSize > m_vertexAttrib0BufferSize) {
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, 0, GraphicsContext3D::DYNAMIC_DRAW);
- m_vertexAttrib0BufferSize = bufferDataSize;
- m_forceAttrib0BufferRefill = true;
- }
- if (usingVertexAttrib0
- && (m_forceAttrib0BufferRefill
- || attribValue.value[0] != m_vertexAttrib0BufferValue[0]
- || attribValue.value[1] != m_vertexAttrib0BufferValue[1]
- || attribValue.value[2] != m_vertexAttrib0BufferValue[2]
- || attribValue.value[3] != m_vertexAttrib0BufferValue[3])) {
- auto bufferData = std::make_unique<GC3Dfloat[]>((numVertex + 1) * 4);
- for (GC3Dsizei ii = 0; ii < numVertex + 1; ++ii) {
- bufferData[ii * 4] = attribValue.value[0];
- bufferData[ii * 4 + 1] = attribValue.value[1];
- bufferData[ii * 4 + 2] = attribValue.value[2];
- bufferData[ii * 4 + 3] = attribValue.value[3];
- }
- m_vertexAttrib0BufferValue[0] = attribValue.value[0];
- m_vertexAttrib0BufferValue[1] = attribValue.value[1];
- m_vertexAttrib0BufferValue[2] = attribValue.value[2];
- m_vertexAttrib0BufferValue[3] = attribValue.value[3];
- m_forceAttrib0BufferRefill = false;
- m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, bufferDataSize, bufferData.get());
- }
- m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, 0, 0, 0);
- return true;
-}
-
-void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
-{
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
- if (state.bufferBinding != m_vertexAttrib0Buffer) {
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(state.bufferBinding.get()));
- m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
- }
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
-}
-
-void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
-{
- RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
- canvas()->dispatchEvent(event);
- m_restoreAllowed = event->defaultPrevented();
- if (m_contextLostMode == RealLostContext && m_restoreAllowed)
- m_restoreTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
-{
- ASSERT(m_contextLost);
- if (!m_contextLost)
- return;
-
- // The rendering context is not restored unless the default behavior of the
- // webglcontextlost event was prevented earlier.
- //
- // Because of the way m_restoreTimer is set up for real vs. synthetic lost
- // context events, we don't have to worry about this test short-circuiting
- // the retry loop for real context lost events.
- if (!m_restoreAllowed)
- return;
-
- int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
-
- switch (contextLostReason) {
- case GraphicsContext3D::NO_ERROR:
- // The GraphicsContext3D implementation might not fully
- // support GL_ARB_robustness semantics yet. Alternatively, the
- // WEBGL_lose_context extension might have been used to force
- // a lost context.
- break;
- case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
- // The rendering context is not restored if this context was
- // guilty of causing the graphics reset.
- printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
- return;
- case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
- // Always allow the context to be restored.
- break;
- case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
- // Warn. Ideally, prompt the user telling them that WebGL
- // content on the page might have caused the graphics card to
- // reset and ask them whether they want to continue running
- // the content. Only if they say "yes" should we start
- // attempting to restore the context.
- printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
- break;
- }
-
- Frame* frame = canvas()->document().frame();
- if (!frame)
- return;
-
- if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled()))
- return;
-
- FrameView* view = frame->view();
- if (!view)
- return;
- ScrollView* root = view->root();
- if (!root)
- return;
- HostWindow* hostWindow = root->hostWindow();
- if (!hostWindow)
- return;
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, hostWindow));
- if (!context) {
- if (m_contextLostMode == RealLostContext)
- m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
- else
- // This likely shouldn't happen but is the best way to report it to the WebGL app.
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context");
- return;
- }
-
- // Construct a new drawing buffer with the new GraphicsContext3D.
- if (m_drawingBuffer) {
- m_drawingBuffer->discardResources();
- DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
- DrawingBuffer::AlphaRequirement alpha = m_attributes.alpha ? DrawingBuffer::Alpha : DrawingBuffer::Opaque;
- m_drawingBuffer = DrawingBuffer::create(context.get(), m_drawingBuffer->size(), preserve, alpha);
- m_drawingBuffer->bind();
- }
-
- m_context = context;
- m_contextLost = false;
- setupFlags();
- initializeNewContext();
- canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
-}
-
-String WebGLRenderingContext::ensureNotNull(const String& text) const
-{
- if (text.isNull())
- return WTF::emptyString();
- return text;
-}
-
-WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
- : m_buffers(std::make_unique<std::unique_ptr<ImageBuffer>[]>(capacity))
- , m_capacity(capacity)
-{
-}
-
-ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
-{
- int i;
- for (i = 0; i < m_capacity; ++i) {
- ImageBuffer* buf = m_buffers[i].get();
- if (!buf)
- break;
- if (buf->logicalSize() != size)
- continue;
- bubbleToFront(i);
- return buf;
- }
-
- std::unique_ptr<ImageBuffer> temp = ImageBuffer::create(size, 1);
- if (!temp)
- return 0;
- i = std::min(m_capacity - 1, i);
- m_buffers[i] = std::move(temp);
-
- ImageBuffer* buf = m_buffers[i].get();
- bubbleToFront(i);
- return buf;
-}
-
-void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
-{
- for (int i = idx; i > 0; --i)
- m_buffers[i].swap(m_buffers[i-1]);
-}
-
-namespace {
-
- String GetErrorString(GC3Denum error)
- {
- switch (error) {
- case GraphicsContext3D::INVALID_ENUM:
- return "INVALID_ENUM";
- case GraphicsContext3D::INVALID_VALUE:
- return "INVALID_VALUE";
- case GraphicsContext3D::INVALID_OPERATION:
- return "INVALID_OPERATION";
- case GraphicsContext3D::OUT_OF_MEMORY:
- return "OUT_OF_MEMORY";
- case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION:
- return "INVALID_FRAMEBUFFER_OPERATION";
- case GraphicsContext3D::CONTEXT_LOST_WEBGL:
- return "CONTEXT_LOST_WEBGL";
- default:
- return String::format("WebGL ERROR(%04x)", error);
- }
- }
-
-} // namespace anonymous
-
-void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
-{
- if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
- String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
- printGLErrorToConsole(str);
- }
- m_context->synthesizeGLError(error);
-}
-
-
-void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, const char* description)
-{
- if (m_synthesizedErrorsToConsole) {
- String str = String("WebGL: ") + String(functionName) + ": " + String(description);
- printGLErrorToConsole(str);
- }
-}
-
-void WebGLRenderingContext::applyStencilTest()
-{
- bool haveStencilBuffer = false;
-
- if (m_framebufferBinding)
- haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
- else {
- RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
- haveStencilBuffer = attributes->stencil();
- }
- enableOrDisable(GraphicsContext3D::STENCIL_TEST,
- m_stencilEnabled && haveStencilBuffer);
-}
-
-void WebGLRenderingContext::enableOrDisable(GC3Denum capability, bool enable)
-{
- if (enable)
- m_context->enable(capability);
- else
- m_context->disable(capability);
-}
-
-IntSize WebGLRenderingContext::clampedCanvasSize()
-{
- return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
- clamp(canvas()->height(), 1, m_maxViewportDims[1]));
-}
-
-GC3Dint WebGLRenderingContext::getMaxDrawBuffers()
-{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
- return std::min(m_maxDrawBuffers, m_maxColorAttachments);
-}
-
-GC3Dint WebGLRenderingContext::getMaxColorAttachments()
-{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- return m_maxColorAttachments;
-}
-
-void WebGLRenderingContext::setBackDrawBuffer(GC3Denum buf)
-{
- m_backDrawBuffer = buf;
-}
-
-void WebGLRenderingContext::restoreCurrentFramebuffer()
-{
- ExceptionCode ec;
- bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec);
-}
-
-void WebGLRenderingContext::restoreCurrentTexture2D()
-{
- ExceptionCode ec;
- bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUnit].texture2DBinding.get(), ec);
-}
-
-bool WebGLRenderingContext::supportsDrawBuffers()
-{
- if (!m_drawBuffersWebGLRequirementsChecked) {
- m_drawBuffersWebGLRequirementsChecked = true;
- m_drawBuffersSupported = EXTDrawBuffers::supported(this);
- }
- return m_drawBuffersSupported;
-}
-
-void WebGLRenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
-{
- if (!primcount) {
- cleanupAfterGraphicsCall(true);
- return;
- }
-
- if (!validateDrawArrays("drawArraysInstanced", mode, first, count, primcount))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant())
- vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArraysInstanced", true);
-
- m_context->drawArraysInstanced(mode, first, count, primcount);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArraysInstanced", false);
- cleanupAfterGraphicsCall(true);
-}
-
-void WebGLRenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
-{
- if (!primcount) {
- cleanupAfterGraphicsCall(true);
- return;
- }
-
- unsigned numElements = 0;
- if (!validateDrawElements("drawElementsInstanced", mode, count, type, offset, numElements, primcount))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant()) {
- if (!numElements)
- validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
- vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
- }
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElementsInstanced", true);
-
- m_context->drawElementsInstanced(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElementsInstanced", false);
- cleanupAfterGraphicsCall(true);
-}
-
-void WebGLRenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- if (isContextLost())
- return;
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribDivisor", "index out of range");
- return;
- }
-
- m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
- m_context->vertexAttribDivisor(index, divisor);
-}
-
-
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index a4a0a1b7b..5f4e5d00b 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,782 +23,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLRenderingContext_h
-#define WebGLRenderingContext_h
+#pragma once
-#include "ActiveDOMObject.h"
-#include "CanvasRenderingContext.h"
-#include "DrawingBuffer.h"
-#include "GraphicsContext3D.h"
-#include "ImageBuffer.h"
-#include "Timer.h"
-#include "WebGLGetInfo.h"
-
-#include <memory>
-#include <runtime/Float32Array.h>
-#include <runtime/Int32Array.h>
-#include <wtf/text/WTFString.h>
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-class ANGLEInstancedArrays;
-class EXTDrawBuffers;
-class EXTTextureFilterAnisotropic;
-class HTMLImageElement;
-class HTMLVideoElement;
-class ImageBuffer;
-class ImageData;
-class IntSize;
-class OESStandardDerivatives;
-class OESTextureFloat;
-class OESTextureFloatLinear;
-class OESTextureHalfFloat;
-class OESTextureHalfFloatLinear;
-class OESVertexArrayObject;
-class OESElementIndexUint;
-class WebGLActiveInfo;
-class WebGLBuffer;
-class WebGLContextGroup;
-class WebGLContextObject;
-class WebGLCompressedTextureATC;
-class WebGLCompressedTexturePVRTC;
-class WebGLCompressedTextureS3TC;
-class WebGLContextAttributes;
-class WebGLDebugRendererInfo;
-class WebGLDebugShaders;
-class WebGLDepthTexture;
-class WebGLExtension;
-class WebGLFramebuffer;
-class WebGLLoseContext;
-class WebGLObject;
-class WebGLProgram;
-class WebGLRenderbuffer;
-class WebGLShader;
-class WebGLSharedObject;
-class WebGLShaderPrecisionFormat;
-class WebGLTexture;
-class WebGLUniformLocation;
-class WebGLVertexArrayObjectOES;
-
-typedef int ExceptionCode;
-
-class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject {
+class WebGLRenderingContext final : public WebGLRenderingContextBase {
public:
- static OwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
- virtual ~WebGLRenderingContext();
-
- virtual bool is3d() const override { return true; }
- virtual bool isAccelerated() const override { return true; }
-
- int drawingBufferWidth() const;
- int drawingBufferHeight() const;
-
- void activeTexture(GC3Denum texture, ExceptionCode&);
- void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
- void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode&);
- void bindBuffer(GC3Denum target, WebGLBuffer*, ExceptionCode&);
- void bindFramebuffer(GC3Denum target, WebGLFramebuffer*, ExceptionCode&);
- void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*, ExceptionCode&);
- void bindTexture(GC3Denum target, WebGLTexture*, ExceptionCode&);
- void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void blendEquation(GC3Denum mode);
- void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
- void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
- void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
-
- void bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode&);
- void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode&);
- void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode&);
- void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode&);
- void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode&);
-
- GC3Denum checkFramebufferStatus(GC3Denum target);
- void clear(GC3Dbitfield mask);
- void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void clearDepth(GC3Dfloat);
- void clearStencil(GC3Dint);
- void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
- void compileShader(WebGLShader*, ExceptionCode&);
-
- void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
- void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
-
- void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
- void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- PassRefPtr<WebGLBuffer> createBuffer();
- PassRefPtr<WebGLFramebuffer> createFramebuffer();
- PassRefPtr<WebGLProgram> createProgram();
- PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
- PassRefPtr<WebGLShader> createShader(GC3Denum type, ExceptionCode&);
- PassRefPtr<WebGLTexture> createTexture();
-
- void cullFace(GC3Denum mode);
-
- void deleteBuffer(WebGLBuffer*);
- void deleteFramebuffer(WebGLFramebuffer*);
- void deleteProgram(WebGLProgram*);
- void deleteRenderbuffer(WebGLRenderbuffer*);
- void deleteShader(WebGLShader*);
- void deleteTexture(WebGLTexture*);
-
- void depthFunc(GC3Denum);
- void depthMask(GC3Dboolean);
- void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
- void detachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
- void disable(GC3Denum cap);
- void disableVertexAttribArray(GC3Duint index, ExceptionCode&);
- void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode&);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode&);
-
- void enable(GC3Denum cap);
- void enableVertexAttribArray(GC3Duint index, ExceptionCode&);
- void finish();
- void flush();
- void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*, ExceptionCode&);
- void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level, ExceptionCode&);
- void frontFace(GC3Denum mode);
- void generateMipmap(GC3Denum target);
-
- PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index, ExceptionCode&);
- PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index, ExceptionCode&);
- bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader>>&, ExceptionCode&);
- GC3Dint getAttribLocation(WebGLProgram*, const String& name);
- WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- PassRefPtr<WebGLContextAttributes> getContextAttributes();
- GC3Denum getError();
- WebGLExtension* getExtension(const String& name);
- WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname, ExceptionCode&);
- String getProgramInfoLog(WebGLProgram*, ExceptionCode&);
- WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname, ExceptionCode&);
- String getShaderInfoLog(WebGLShader*, ExceptionCode&);
- PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode&);
- String getShaderSource(WebGLShader*, ExceptionCode&);
- Vector<String> getSupportedExtensions();
- WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
- PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
- WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode&);
- long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
-
- void hint(GC3Denum target, GC3Denum mode);
- GC3Dboolean isBuffer(WebGLBuffer*);
- bool isContextLost() const;
- GC3Dboolean isEnabled(GC3Denum cap);
- GC3Dboolean isFramebuffer(WebGLFramebuffer*);
- GC3Dboolean isProgram(WebGLProgram*);
- GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
- GC3Dboolean isShader(WebGLShader*);
- GC3Dboolean isTexture(WebGLTexture*);
-
- void lineWidth(GC3Dfloat);
- void linkProgram(WebGLProgram*, ExceptionCode&);
- void pixelStorei(GC3Denum pname, GC3Dint param);
- void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
- void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&);
- void releaseShaderCompiler();
- void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
- void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
- void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void shaderSource(WebGLShader*, const String&, ExceptionCode&);
- void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilMask(GC3Duint);
- void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
- void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
- void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
-
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
-#if ENABLE(VIDEO)
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
-#endif
-
- void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
- void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
-
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
-#if ENABLE(VIDEO)
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
-#endif
-
- void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&);
- void uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode&);
- void uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode&);
- void uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode&);
- void uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode&);
- void uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode&);
- void uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode&);
- void uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode&);
- void uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
-
- void useProgram(WebGLProgram*, ExceptionCode&);
- void validateProgram(WebGLProgram*, ExceptionCode&);
-
- void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
- void vertexAttrib1fv(GC3Duint index, Float32Array* values);
- void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
- void vertexAttrib2fv(GC3Duint index, Float32Array* values);
- void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void vertexAttrib3fv(GC3Duint index, Float32Array* values);
- void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void vertexAttrib4fv(GC3Duint index, Float32Array* values);
- void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, long long offset, ExceptionCode&);
-
- void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- // WEBKIT_lose_context support
- enum LostContextMode {
- // Lost context occurred at the graphics system level.
- RealLostContext,
-
- // Lost context provoked by WEBKIT_lose_context.
- SyntheticLostContext
- };
- void forceLostContext(LostContextMode);
- void forceRestoreContext();
- void loseContextImpl(LostContextMode);
-
- GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
- WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
-#if USE(ACCELERATED_COMPOSITING)
- virtual PlatformLayer* platformLayer() const override;
-#endif
-
- void reshape(int width, int height);
-
- void markLayerComposited();
- virtual void paintRenderingResultsToCanvas() override;
- virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
-
- void removeSharedObject(WebGLSharedObject*);
- void removeContextObject(WebGLContextObject*);
-
- unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
-
- // ANGLE_instanced_arrays extension functions.
- void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
- void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+ WebGLRenderingContext(HTMLCanvasElement&, GraphicsContext3DAttributes);
+ WebGLRenderingContext(HTMLCanvasElement&, Ref<GraphicsContext3D>&&, GraphicsContext3DAttributes);
private:
- friend class EXTDrawBuffers;
- friend class WebGLFramebuffer;
- friend class WebGLObject;
- friend class OESVertexArrayObject;
- friend class WebGLDebugShaders;
- friend class WebGLCompressedTextureATC;
- friend class WebGLCompressedTexturePVRTC;
- friend class WebGLCompressedTextureS3TC;
- friend class WebGLRenderingContextErrorMessageCallback;
- friend class WebGLVertexArrayObjectOES;
-
- WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
- void initializeNewContext();
- void setupFlags();
-
- // ActiveDOMObject
- virtual bool hasPendingActivity() const override;
- virtual void stop() override;
-
- void addSharedObject(WebGLSharedObject*);
- void addContextObject(WebGLContextObject*);
- void detachAndRemoveAllObjects();
-
- void destroyGraphicsContext3D();
- void markContextChanged();
- void cleanupAfterGraphicsCall(bool changed)
- {
- if (changed)
- markContextChanged();
- }
-
- // Query whether it is built on top of compliant GLES2 implementation.
- bool isGLES2Compliant() { return m_isGLES2Compliant; }
- // Query if the GL implementation is NPOT strict.
- bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
- // Query if the GL implementation generates errors on out-of-bounds buffer accesses.
- bool isErrorGeneratedOnOutOfBoundsAccesses() { return m_isErrorGeneratedOnOutOfBoundsAccesses; }
- // Query if the GL implementation initializes textures/renderbuffers to 0.
- bool isResourceSafe() { return m_isResourceSafe; }
- // Query if depth_stencil buffer is supported.
- bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
-
- // Helper to return the size in bytes of OpenGL data types
- // like GL_FLOAT, GL_INT, etc.
- unsigned int sizeInBytes(GC3Denum type);
-
- // Basic validation of count and offset against number of elements in element array buffer
- bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
-
- // Conservative but quick index validation
- bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired);
-
- // Precise but slow index validation -- only done if conservative checks fail
- bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired);
- bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);
-
- bool validateWebGLObject(const char*, WebGLObject*);
-
- bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primcount);
-
- // Adds a compressed texture format.
- void addCompressedTextureFormat(GC3Denum);
-
- PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, int deviceScaleFactor);
-
-#if ENABLE(VIDEO)
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&);
-#endif
-
- RefPtr<GraphicsContext3D> m_context;
- RefPtr<WebGLContextGroup> m_contextGroup;
-
- // Optional structure for rendering to a DrawingBuffer, instead of directly
- // to the back-buffer of m_context.
- RefPtr<DrawingBuffer> m_drawingBuffer;
-
- // Dispatches a context lost event once it is determined that one is needed.
- // This is used both for synthetic 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.
- Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
- bool m_restoreAllowed;
- Timer<WebGLRenderingContext> m_restoreTimer;
-
- bool m_needsUpdate;
- bool m_markedCanvasDirty;
- HashSet<WebGLContextObject*> m_contextObjects;
-
- // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
- RefPtr<WebGLBuffer> m_boundArrayBuffer;
-
- RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
- RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
- void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
- {
- if (arrayObject)
- m_boundVertexArrayObject = arrayObject;
- else
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
- }
-
- class VertexAttribValue {
- public:
- VertexAttribValue()
- {
- initValue();
- }
-
- void initValue()
- {
- value[0] = 0.0f;
- value[1] = 0.0f;
- value[2] = 0.0f;
- value[3] = 1.0f;
- }
-
- GC3Dfloat value[4];
- };
- Vector<VertexAttribValue> m_vertexAttribValue;
- unsigned m_maxVertexAttribs;
- RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
- long m_vertexAttrib0BufferSize;
- GC3Dfloat m_vertexAttrib0BufferValue[4];
- bool m_forceAttrib0BufferRefill;
- bool m_vertexAttrib0UsedBefore;
-
- RefPtr<WebGLProgram> m_currentProgram;
- RefPtr<WebGLFramebuffer> m_framebufferBinding;
- RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
- struct TextureUnitState {
- RefPtr<WebGLTexture> texture2DBinding;
- RefPtr<WebGLTexture> textureCubeMapBinding;
- };
- Vector<TextureUnitState> m_textureUnits;
- unsigned long m_activeTextureUnit;
-
- RefPtr<WebGLTexture> m_blackTexture2D;
- RefPtr<WebGLTexture> m_blackTextureCubeMap;
-
- Vector<GC3Denum> m_compressedTextureFormats;
-
- // Fixed-size cache of reusable image buffers for video texImage2D calls.
- class LRUImageBufferCache {
- public:
- LRUImageBufferCache(int capacity);
- // The pointer returned is owned by the image buffer map.
- ImageBuffer* imageBuffer(const IntSize& size);
- private:
- void bubbleToFront(int idx);
- std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
- int m_capacity;
- };
- LRUImageBufferCache m_generatedImageCache;
-
- GC3Dint m_maxTextureSize;
- GC3Dint m_maxCubeMapTextureSize;
- GC3Dint m_maxRenderbufferSize;
- GC3Dint m_maxViewportDims[2];
- GC3Dint m_maxTextureLevel;
- GC3Dint m_maxCubeMapTextureLevel;
-
- GC3Dint m_maxDrawBuffers;
- GC3Dint m_maxColorAttachments;
- GC3Denum m_backDrawBuffer;
- bool m_drawBuffersWebGLRequirementsChecked;
- bool m_drawBuffersSupported;
-
- GC3Dint m_packAlignment;
- GC3Dint m_unpackAlignment;
- bool m_unpackFlipY;
- bool m_unpackPremultiplyAlpha;
- GC3Denum m_unpackColorspaceConversion;
- bool m_contextLost;
- LostContextMode m_contextLostMode;
- GraphicsContext3D::Attributes m_attributes;
-
- bool m_layerCleared;
- GC3Dfloat m_clearColor[4];
- bool m_scissorEnabled;
- GC3Dfloat m_clearDepth;
- GC3Dint m_clearStencil;
- GC3Dboolean m_colorMask[4];
- GC3Dboolean m_depthMask;
-
- bool m_stencilEnabled;
- GC3Duint m_stencilMask, m_stencilMaskBack;
- GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
- GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
-
- bool m_isGLES2Compliant;
- bool m_isGLES2NPOTStrict;
- bool m_isErrorGeneratedOnOutOfBoundsAccesses;
- bool m_isResourceSafe;
- bool m_isDepthStencilSupported;
- bool m_isRobustnessEXTSupported;
-
- bool m_synthesizedErrorsToConsole;
- int m_numGLErrorsToConsoleAllowed;
-
- // Enabled extension objects.
- OwnPtr<EXTDrawBuffers> m_extDrawBuffers;
- OwnPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
- OwnPtr<OESTextureFloat> m_oesTextureFloat;
- OwnPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
- OwnPtr<OESTextureHalfFloat> m_oesTextureHalfFloat;
- OwnPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
- OwnPtr<OESStandardDerivatives> m_oesStandardDerivatives;
- OwnPtr<OESVertexArrayObject> m_oesVertexArrayObject;
- OwnPtr<OESElementIndexUint> m_oesElementIndexUint;
- OwnPtr<WebGLLoseContext> m_webglLoseContext;
- OwnPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
- OwnPtr<WebGLDebugShaders> m_webglDebugShaders;
- OwnPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
- OwnPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
- OwnPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
- OwnPtr<WebGLDepthTexture> m_webglDepthTexture;
- OwnPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
-
- // Helpers for getParameter and others
- WebGLGetInfo getBooleanParameter(GC3Denum);
- WebGLGetInfo getBooleanArrayParameter(GC3Denum);
- WebGLGetInfo getFloatParameter(GC3Denum);
- WebGLGetInfo getIntParameter(GC3Denum);
- WebGLGetInfo getUnsignedIntParameter(GC3Denum);
- WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
- WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
-
- // 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 true if that clear is now unnecessary.
- bool clearIfComposited(GC3Dbitfield clearMask = 0);
-
- // Helper to restore state that clearing the framebuffer may destroy.
- void restoreStateAfterClear();
-
- void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
- void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
- void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
- void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
-
- void checkTextureCompleteness(const char*, bool);
-
- void createFallbackBlackTextures1x1();
-
- // 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(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat);
-
- // Helper function to get the bound framebuffer's color buffer format.
- GC3Denum getBoundFramebufferColorFormat();
-
- // Helper function to get the bound framebuffer's width.
- int getBoundFramebufferWidth();
-
- // Helper function to get the bound framebuffer's height.
- int getBoundFramebufferHeight();
-
- // Helper function to verify limits on the length of uniform and attribute locations.
- bool validateLocationLength(const char* functionName, 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* functionName, GC3Dint x, GC3Dint y);
-
- // 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* functionName, const String&);
-
- // Helper function to check 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* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
-
- // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
-
- // 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* functionName, GC3Denum target, GC3Dint level);
-
- enum TexFuncValidationFunctionType {
- NotTexSubImage2D,
- TexSubImage2D,
- };
-
- enum TexFuncValidationSourceType {
- SourceArrayBufferView,
- SourceImageData,
- SourceHTMLImageElement,
- SourceHTMLCanvasElement,
- SourceHTMLVideoElement,
- };
-
- // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
- // Otherwise, it would return quickly without doing other work.
- bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
-
- // 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* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type);
-
- enum NullDisposition {
- NullAllowed,
- NullNotAllowed
- };
-
- // 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* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition);
-
- // 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* functionName, GC3Denum format);
-
- // Helper function to validate compressed texture data is correct size
- // for the given format and dimensions.
- bool validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels);
-
- // Helper function for validating compressed texture formats.
- bool validateCompressedTexFormat(GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
-
- // Helper function to validate mode for draw{Arrays/Elements}.
- bool validateDrawMode(const char* functionName, GC3Denum);
-
- // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
- bool validateStencilSettings(const char* functionName);
-
- // Helper function to validate stencil func.
- bool validateStencilFunc(const char* functionName, GC3Denum);
-
- // Helper function for texParameterf and texParameteri.
- void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
-
- // Helper function to print GL errors to console.
- void printGLErrorToConsole(const String&);
- void printGLWarningToConsole(const char* function, const char* reason);
-
- // 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 input parameters for framebuffer functions.
- // Generate GL error if parameters are illegal.
- bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
-
- // Helper function to validate blend equation mode.
- bool validateBlendEquation(const char* functionName, GC3Denum);
-
- // Helper function to validate blend func factors.
- bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
-
- // Helper function to validate a GL capability.
- bool validateCapability(const char* functionName, GC3Denum);
-
- // Helper function to validate input parameters for uniform functions.
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
-
- // Helper function to validate parameters for bufferData.
- // Return the current bound buffer to target, or 0 if parameters are invalid.
- WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
-
- // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
- bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionCode&);
-
- // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
- bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionCode&);
-
-#if ENABLE(VIDEO)
- // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
- bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionCode&);
-#endif
-
- // Helper functions for vertexAttribNf{v}.
- void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
-
- // 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* functionName, WebGLObject*, bool& deleted);
-
- // Helpers for simulating vertexAttrib0
- void initVertexAttrib0();
- bool simulateVertexAttrib0(GC3Dsizei numVertex);
- void restoreStatesAfterVertexAttrib0Simulation();
-
- void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
- // Helper for restoration after context lost.
- void maybeRestoreContext(Timer<WebGLRenderingContext>*);
-
- // Determine if we are running privileged code in the browser, for example,
- // a Safari or Chrome extension.
- bool allowPrivilegedExtensions() const;
-
- enum ConsoleDisplayPreference {
- DisplayInConsole,
- DontDisplayInConsole
- };
-
- // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
- // to the JavaScript console.
- void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
-
- 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(GC3Denum capability, bool enable);
-
- // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
- IntSize clampedCanvasSize();
-
- // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
- // Later, return the cached value.
- GC3Dint getMaxDrawBuffers();
- GC3Dint getMaxColorAttachments();
-
- void setBackDrawBuffer(GC3Denum);
-
- void restoreCurrentFramebuffer();
- void restoreCurrentTexture2D();
-
- // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
- bool supportsDrawBuffers();
-
- friend class WebGLStateRestorer;
+ bool isWebGL1() const final { return true; }
+
+ WebGLExtension* getExtension(const String&) final;
+ WebGLAny getParameter(GC3Denum pname) final;
+ std::optional<Vector<String>> getSupportedExtensions() final;
+
+ WebGLAny getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname) final;
+ void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) final;
+ bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) final;
+ void hint(GC3Denum target, GC3Denum mode) final;
+ void clear(GC3Dbitfield mask) final;
+
+ GC3Dint getMaxDrawBuffers() final;
+ GC3Dint getMaxColorAttachments() final;
+ void initializeVertexArrayObjects() final;
+ bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) final;
+ bool validateBlendEquation(const char* functionName, GC3Denum mode) final;
+ bool validateCapability(const char* functionName, GC3Denum cap) final;
};
-
+
} // namespace WebCore
-#endif
+SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::WebGLRenderingContext, isWebGL1())
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
index 54d9b0431..80cd98eca 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,647 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-typedef unsigned long GLenum;
-typedef boolean GLboolean;
-typedef unsigned long GLbitfield;
-typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
-typedef short GLshort;
-typedef long GLint;
-typedef long GLsizei;
-typedef long long GLintptr;
-typedef long long GLsizeiptr;
-typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
-typedef unsigned short GLushort;
-typedef unsigned long GLuint;
-typedef /*unrestricted*/ float GLfloat;
-typedef /*unrestricted*/ float GLclampf;
-
[
Conditional=WEBGL,
JSCustomMarkFunction,
+ JSGenerateToJSObject,
DoNotCheckConstants,
-] interface WebGLRenderingContext : CanvasRenderingContext {
-
- /* ClearBufferMask */
- const GLenum DEPTH_BUFFER_BIT = 0x00000100;
- const GLenum STENCIL_BUFFER_BIT = 0x00000400;
- const GLenum COLOR_BUFFER_BIT = 0x00004000;
-
- /* BeginMode */
- const GLenum POINTS = 0x0000;
- const GLenum LINES = 0x0001;
- const GLenum LINE_LOOP = 0x0002;
- const GLenum LINE_STRIP = 0x0003;
- const GLenum TRIANGLES = 0x0004;
- const GLenum TRIANGLE_STRIP = 0x0005;
- const GLenum TRIANGLE_FAN = 0x0006;
-
- /* AlphaFunction (not supported in ES20) */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* BlendingFactorDest */
- const GLenum ZERO = 0;
- const GLenum ONE = 1;
- const GLenum SRC_COLOR = 0x0300;
- const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
- const GLenum SRC_ALPHA = 0x0302;
- const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
- const GLenum DST_ALPHA = 0x0304;
- const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
-
- /* BlendingFactorSrc */
- /* ZERO */
- /* ONE */
- const GLenum DST_COLOR = 0x0306;
- const GLenum ONE_MINUS_DST_COLOR = 0x0307;
- const GLenum SRC_ALPHA_SATURATE = 0x0308;
- /* SRC_ALPHA */
- /* ONE_MINUS_SRC_ALPHA */
- /* DST_ALPHA */
- /* ONE_MINUS_DST_ALPHA */
-
- /* BlendEquationSeparate */
- const GLenum FUNC_ADD = 0x8006;
- const GLenum BLEND_EQUATION = 0x8009;
- const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
- const GLenum BLEND_EQUATION_ALPHA = 0x883D;
-
- /* BlendSubtract */
- const GLenum FUNC_SUBTRACT = 0x800A;
- const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
-
- /* Separate Blend Functions */
- const GLenum BLEND_DST_RGB = 0x80C8;
- const GLenum BLEND_SRC_RGB = 0x80C9;
- const GLenum BLEND_DST_ALPHA = 0x80CA;
- const GLenum BLEND_SRC_ALPHA = 0x80CB;
- const GLenum CONSTANT_COLOR = 0x8001;
- const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
- const GLenum CONSTANT_ALPHA = 0x8003;
- const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
- const GLenum BLEND_COLOR = 0x8005;
-
- /* Buffer Objects */
- const GLenum ARRAY_BUFFER = 0x8892;
- const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
- const GLenum ARRAY_BUFFER_BINDING = 0x8894;
- const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
-
- const GLenum STREAM_DRAW = 0x88E0;
- const GLenum STATIC_DRAW = 0x88E4;
- const GLenum DYNAMIC_DRAW = 0x88E8;
-
- const GLenum BUFFER_SIZE = 0x8764;
- const GLenum BUFFER_USAGE = 0x8765;
-
- const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
-
- /* CullFaceMode */
- const GLenum FRONT = 0x0404;
- const GLenum BACK = 0x0405;
- const GLenum FRONT_AND_BACK = 0x0408;
-
- /* DepthFunction */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* EnableCap */
- const GLenum TEXTURE_2D = 0x0DE1;
- const GLenum CULL_FACE = 0x0B44;
- const GLenum BLEND = 0x0BE2;
- const GLenum DITHER = 0x0BD0;
- const GLenum STENCIL_TEST = 0x0B90;
- const GLenum DEPTH_TEST = 0x0B71;
- const GLenum SCISSOR_TEST = 0x0C11;
- const GLenum POLYGON_OFFSET_FILL = 0x8037;
- const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
- const GLenum SAMPLE_COVERAGE = 0x80A0;
-
- /* ErrorCode */
- const GLenum NO_ERROR = 0;
- const GLenum INVALID_ENUM = 0x0500;
- const GLenum INVALID_VALUE = 0x0501;
- const GLenum INVALID_OPERATION = 0x0502;
- const GLenum OUT_OF_MEMORY = 0x0505;
-
- /* FrontFaceDirection */
- const GLenum CW = 0x0900;
- const GLenum CCW = 0x0901;
-
- /* GetPName */
- const GLenum LINE_WIDTH = 0x0B21;
- const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
- const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
- const GLenum CULL_FACE_MODE = 0x0B45;
- const GLenum FRONT_FACE = 0x0B46;
- const GLenum DEPTH_RANGE = 0x0B70;
- const GLenum DEPTH_WRITEMASK = 0x0B72;
- const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
- const GLenum DEPTH_FUNC = 0x0B74;
- const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
- const GLenum STENCIL_FUNC = 0x0B92;
- const GLenum STENCIL_FAIL = 0x0B94;
- const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
- const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
- const GLenum STENCIL_REF = 0x0B97;
- const GLenum STENCIL_VALUE_MASK = 0x0B93;
- const GLenum STENCIL_WRITEMASK = 0x0B98;
- const GLenum STENCIL_BACK_FUNC = 0x8800;
- const GLenum STENCIL_BACK_FAIL = 0x8801;
- const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
- const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
- const GLenum STENCIL_BACK_REF = 0x8CA3;
- const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
- const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
- const GLenum VIEWPORT = 0x0BA2;
- const GLenum SCISSOR_BOX = 0x0C10;
- /* SCISSOR_TEST */
- const GLenum COLOR_CLEAR_VALUE = 0x0C22;
- const GLenum COLOR_WRITEMASK = 0x0C23;
- const GLenum UNPACK_ALIGNMENT = 0x0CF5;
- const GLenum PACK_ALIGNMENT = 0x0D05;
- const GLenum MAX_TEXTURE_SIZE = 0x0D33;
- const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
- const GLenum SUBPIXEL_BITS = 0x0D50;
- const GLenum RED_BITS = 0x0D52;
- const GLenum GREEN_BITS = 0x0D53;
- const GLenum BLUE_BITS = 0x0D54;
- const GLenum ALPHA_BITS = 0x0D55;
- const GLenum DEPTH_BITS = 0x0D56;
- const GLenum STENCIL_BITS = 0x0D57;
- const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
- /* POLYGON_OFFSET_FILL */
- const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
- const GLenum TEXTURE_BINDING_2D = 0x8069;
- const GLenum SAMPLE_BUFFERS = 0x80A8;
- const GLenum SAMPLES = 0x80A9;
- const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
- const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
-
- /* GetTextureParameter */
- /* TEXTURE_MAG_FILTER */
- /* TEXTURE_MIN_FILTER */
- /* TEXTURE_WRAP_S */
- /* TEXTURE_WRAP_T */
-
- const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
-
- /* HintMode */
- const GLenum DONT_CARE = 0x1100;
- const GLenum FASTEST = 0x1101;
- const GLenum NICEST = 0x1102;
-
- /* HintTarget */
- const GLenum GENERATE_MIPMAP_HINT = 0x8192;
-
- /* DataType */
- const GLenum BYTE = 0x1400;
- const GLenum UNSIGNED_BYTE = 0x1401;
- const GLenum SHORT = 0x1402;
- const GLenum UNSIGNED_SHORT = 0x1403;
- const GLenum INT = 0x1404;
- const GLenum UNSIGNED_INT = 0x1405;
- const GLenum FLOAT = 0x1406;
-
- /* PixelFormat */
- const GLenum DEPTH_COMPONENT = 0x1902;
- const GLenum ALPHA = 0x1906;
- const GLenum RGB = 0x1907;
- const GLenum RGBA = 0x1908;
- const GLenum LUMINANCE = 0x1909;
- const GLenum LUMINANCE_ALPHA = 0x190A;
-
- /* PixelType */
- /* UNSIGNED_BYTE */
- const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
- const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
- const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
-
- /* Shaders */
- const GLenum FRAGMENT_SHADER = 0x8B30;
- const GLenum VERTEX_SHADER = 0x8B31;
- const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
- const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
- const GLenum MAX_VARYING_VECTORS = 0x8DFC;
- const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
- const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
- const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
- const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
- const GLenum SHADER_TYPE = 0x8B4F;
- const GLenum DELETE_STATUS = 0x8B80;
- const GLenum LINK_STATUS = 0x8B82;
- const GLenum VALIDATE_STATUS = 0x8B83;
- const GLenum ATTACHED_SHADERS = 0x8B85;
- const GLenum ACTIVE_UNIFORMS = 0x8B86;
- const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
- const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
- const GLenum CURRENT_PROGRAM = 0x8B8D;
-
- /* StencilFunction */
- const GLenum NEVER = 0x0200;
- const GLenum LESS = 0x0201;
- const GLenum EQUAL = 0x0202;
- const GLenum LEQUAL = 0x0203;
- const GLenum GREATER = 0x0204;
- const GLenum NOTEQUAL = 0x0205;
- const GLenum GEQUAL = 0x0206;
- const GLenum ALWAYS = 0x0207;
-
- /* StencilOp */
- /* ZERO */
- const GLenum KEEP = 0x1E00;
- const GLenum REPLACE = 0x1E01;
- const GLenum INCR = 0x1E02;
- const GLenum DECR = 0x1E03;
- const GLenum INVERT = 0x150A;
- const GLenum INCR_WRAP = 0x8507;
- const GLenum DECR_WRAP = 0x8508;
-
- /* StringName */
- const GLenum VENDOR = 0x1F00;
- const GLenum RENDERER = 0x1F01;
- const GLenum VERSION = 0x1F02;
-
- /* TextureMagFilter */
- const GLenum NEAREST = 0x2600;
- const GLenum LINEAR = 0x2601;
-
- /* TextureMinFilter */
- /* NEAREST */
- /* LINEAR */
- const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
- const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
- const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
- const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
-
- /* TextureParameterName */
- const GLenum TEXTURE_MAG_FILTER = 0x2800;
- const GLenum TEXTURE_MIN_FILTER = 0x2801;
- const GLenum TEXTURE_WRAP_S = 0x2802;
- const GLenum TEXTURE_WRAP_T = 0x2803;
-
- /* TextureTarget */
- /* TEXTURE_2D */
- const GLenum TEXTURE = 0x1702;
-
- const GLenum TEXTURE_CUBE_MAP = 0x8513;
- const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
- const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
-
- /* TextureUnit */
- const GLenum TEXTURE0 = 0x84C0;
- const GLenum TEXTURE1 = 0x84C1;
- const GLenum TEXTURE2 = 0x84C2;
- const GLenum TEXTURE3 = 0x84C3;
- const GLenum TEXTURE4 = 0x84C4;
- const GLenum TEXTURE5 = 0x84C5;
- const GLenum TEXTURE6 = 0x84C6;
- const GLenum TEXTURE7 = 0x84C7;
- const GLenum TEXTURE8 = 0x84C8;
- const GLenum TEXTURE9 = 0x84C9;
- const GLenum TEXTURE10 = 0x84CA;
- const GLenum TEXTURE11 = 0x84CB;
- const GLenum TEXTURE12 = 0x84CC;
- const GLenum TEXTURE13 = 0x84CD;
- const GLenum TEXTURE14 = 0x84CE;
- const GLenum TEXTURE15 = 0x84CF;
- const GLenum TEXTURE16 = 0x84D0;
- const GLenum TEXTURE17 = 0x84D1;
- const GLenum TEXTURE18 = 0x84D2;
- const GLenum TEXTURE19 = 0x84D3;
- const GLenum TEXTURE20 = 0x84D4;
- const GLenum TEXTURE21 = 0x84D5;
- const GLenum TEXTURE22 = 0x84D6;
- const GLenum TEXTURE23 = 0x84D7;
- const GLenum TEXTURE24 = 0x84D8;
- const GLenum TEXTURE25 = 0x84D9;
- const GLenum TEXTURE26 = 0x84DA;
- const GLenum TEXTURE27 = 0x84DB;
- const GLenum TEXTURE28 = 0x84DC;
- const GLenum TEXTURE29 = 0x84DD;
- const GLenum TEXTURE30 = 0x84DE;
- const GLenum TEXTURE31 = 0x84DF;
- const GLenum ACTIVE_TEXTURE = 0x84E0;
-
- /* TextureWrapMode */
- const GLenum REPEAT = 0x2901;
- const GLenum CLAMP_TO_EDGE = 0x812F;
- const GLenum MIRRORED_REPEAT = 0x8370;
-
- /* Uniform Types */
- const GLenum FLOAT_VEC2 = 0x8B50;
- const GLenum FLOAT_VEC3 = 0x8B51;
- const GLenum FLOAT_VEC4 = 0x8B52;
- const GLenum INT_VEC2 = 0x8B53;
- const GLenum INT_VEC3 = 0x8B54;
- const GLenum INT_VEC4 = 0x8B55;
- const GLenum BOOL = 0x8B56;
- const GLenum BOOL_VEC2 = 0x8B57;
- const GLenum BOOL_VEC3 = 0x8B58;
- const GLenum BOOL_VEC4 = 0x8B59;
- const GLenum FLOAT_MAT2 = 0x8B5A;
- const GLenum FLOAT_MAT3 = 0x8B5B;
- const GLenum FLOAT_MAT4 = 0x8B5C;
- const GLenum SAMPLER_2D = 0x8B5E;
- const GLenum SAMPLER_CUBE = 0x8B60;
-
- /* Vertex Arrays */
- const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
- const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
- const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
- const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
- const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
- const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
- const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
-
- /* Shader Source */
- const GLenum COMPILE_STATUS = 0x8B81;
-
- /* Shader Precision-Specified Types */
- const GLenum LOW_FLOAT = 0x8DF0;
- const GLenum MEDIUM_FLOAT = 0x8DF1;
- const GLenum HIGH_FLOAT = 0x8DF2;
- const GLenum LOW_INT = 0x8DF3;
- const GLenum MEDIUM_INT = 0x8DF4;
- const GLenum HIGH_INT = 0x8DF5;
-
- /* Framebuffer Object. */
- const GLenum FRAMEBUFFER = 0x8D40;
- const GLenum RENDERBUFFER = 0x8D41;
-
- const GLenum RGBA4 = 0x8056;
- const GLenum RGB5_A1 = 0x8057;
- const GLenum RGB565 = 0x8D62;
- const GLenum DEPTH_COMPONENT16 = 0x81A5;
- const GLenum STENCIL_INDEX = 0x1901;
- const GLenum STENCIL_INDEX8 = 0x8D48;
- const GLenum DEPTH_STENCIL = 0x84F9;
-
- const GLenum RENDERBUFFER_WIDTH = 0x8D42;
- const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
- const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
- const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
- const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
- const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
- const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
- const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
- const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
-
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
-
- const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
- const GLenum DEPTH_ATTACHMENT = 0x8D00;
- const GLenum STENCIL_ATTACHMENT = 0x8D20;
- const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
-
- const GLenum NONE = 0;
-
- const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
- const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
- const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
- const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
- const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
-
- const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
- const GLenum RENDERBUFFER_BINDING = 0x8CA7;
- const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
-
- const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
-
- /* WebGL-specific enums */
- const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
- const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
- const GLenum CONTEXT_LOST_WEBGL = 0x9242;
- const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
- const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
-
- readonly attribute GLsizei drawingBufferWidth;
- readonly attribute GLsizei drawingBufferHeight;
-
- [StrictTypeChecking, RaisesException] void activeTexture(GLenum texture);
- [StrictTypeChecking, RaisesException] void attachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking, RaisesException] void bindAttribLocation(WebGLProgram program, GLuint index, DOMString name);
- [StrictTypeChecking, RaisesException] void bindBuffer(GLenum target, WebGLBuffer buffer);
- [StrictTypeChecking, RaisesException] void bindFramebuffer(GLenum target, WebGLFramebuffer framebuffer);
- [StrictTypeChecking, RaisesException] void bindRenderbuffer(GLenum target, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking, RaisesException] void bindTexture(GLenum target, WebGLTexture texture);
- [StrictTypeChecking] void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void blendEquation(GLenum mode);
- [StrictTypeChecking] void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
- [StrictTypeChecking] void blendFunc(GLenum sfactor, GLenum dfactor);
- [StrictTypeChecking] void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
- [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
-
- [StrictTypeChecking] GLenum checkFramebufferStatus(GLenum target);
- [StrictTypeChecking] void clear(GLbitfield mask);
- [StrictTypeChecking] void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void clearDepth(GLclampf depth);
- [StrictTypeChecking] void clearStencil(GLint s);
- [StrictTypeChecking] void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
- [StrictTypeChecking, RaisesException] void compileShader(WebGLShader shader);
-
- [StrictTypeChecking] void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
- [StrictTypeChecking] void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
-
- [StrictTypeChecking] void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
- [StrictTypeChecking] void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
- [StrictTypeChecking] WebGLBuffer createBuffer();
- [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
- [StrictTypeChecking] WebGLProgram createProgram();
- [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
- [StrictTypeChecking, RaisesException] WebGLShader createShader(GLenum type);
- [StrictTypeChecking] WebGLTexture createTexture();
-
- [StrictTypeChecking] void cullFace(GLenum mode);
-
- [StrictTypeChecking] void deleteBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] void deleteFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void deleteProgram(WebGLProgram program);
- [StrictTypeChecking] void deleteRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void deleteShader(WebGLShader shader);
- [StrictTypeChecking] void deleteTexture(WebGLTexture texture);
-
- [StrictTypeChecking] void depthFunc(GLenum func);
- [StrictTypeChecking] void depthMask(GLboolean flag);
- [StrictTypeChecking] void depthRange(GLclampf zNear, GLclampf zFar);
- [StrictTypeChecking, RaisesException] void detachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void disable(GLenum cap);
- [StrictTypeChecking, RaisesException] void disableVertexAttribArray(GLuint index);
- [StrictTypeChecking, RaisesException] void drawArrays(GLenum mode, GLint first, GLsizei count);
- [StrictTypeChecking, RaisesException] void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
-
- [StrictTypeChecking] void enable(GLenum cap);
- [StrictTypeChecking, RaisesException] void enableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void finish();
- [StrictTypeChecking] void flush();
- [StrictTypeChecking, RaisesException] void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking, RaisesException] void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture texture, GLint level);
- [StrictTypeChecking] void frontFace(GLenum mode);
- [StrictTypeChecking] void generateMipmap(GLenum target);
-
- [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index);
- [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index);
-
- [StrictTypeChecking, Custom, RaisesException] void getAttachedShaders(WebGLProgram program);
-
- [StrictTypeChecking] GLint getAttribLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getBufferParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
-
- [StrictTypeChecking] GLenum getError();
-
- // object getExtension(DOMString name);
- [StrictTypeChecking, Custom] any getExtension(DOMString name);
-
- [StrictTypeChecking, Custom, RaisesException] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getParameter(GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getProgramParameter(WebGLProgram program, GLenum pname);
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getProgramInfoLog(WebGLProgram program);
- [StrictTypeChecking, Custom, RaisesException] any getRenderbufferParameter(GLenum target, GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getShaderParameter(WebGLShader shader, GLenum pname);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderInfoLog(WebGLShader shader);
-
- [StrictTypeChecking, RaisesException] WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderSource(WebGLShader shader);
-
- [StrictTypeChecking, Custom] sequence<DOMString> getSupportedExtensions();
-
- [StrictTypeChecking, Custom, RaisesException] any getTexParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking, Custom, RaisesException] any getUniform(WebGLProgram program, WebGLUniformLocation location);
-
- [StrictTypeChecking, RaisesException] WebGLUniformLocation getUniformLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom, RaisesException] any getVertexAttrib(GLuint index, GLenum pname);
-
- [StrictTypeChecking] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
-
- [StrictTypeChecking] void hint(GLenum target, GLenum mode);
- [StrictTypeChecking] GLboolean isBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] GLboolean isContextLost();
- [StrictTypeChecking] GLboolean isEnabled(GLenum cap);
- [StrictTypeChecking] GLboolean isFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] GLboolean isProgram(WebGLProgram program);
- [StrictTypeChecking] GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] GLboolean isShader(WebGLShader shader);
- [StrictTypeChecking] GLboolean isTexture(WebGLTexture texture);
- [StrictTypeChecking] void lineWidth(GLfloat width);
- [StrictTypeChecking, RaisesException] void linkProgram(WebGLProgram program);
- [StrictTypeChecking] void pixelStorei(GLenum pname, GLint param);
- [StrictTypeChecking] void polygonOffset(GLfloat factor, GLfloat units);
-
- [StrictTypeChecking, RaisesException] void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
-
- [StrictTypeChecking] void releaseShaderCompiler();
- [StrictTypeChecking] void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
- [StrictTypeChecking] void sampleCoverage(GLclampf value, GLboolean invert);
- [StrictTypeChecking] void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking, RaisesException] void shaderSource(WebGLShader shader, DOMString string);
- [StrictTypeChecking] void stencilFunc(GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilMask(GLuint mask);
- [StrictTypeChecking] void stencilMaskSeparate(GLenum face, GLuint mask);
- [StrictTypeChecking] void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
- [StrictTypeChecking] void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
- [StrictTypeChecking] void texParameterf(GLenum target, GLenum pname, GLfloat param);
- [StrictTypeChecking] void texParameteri(GLenum target, GLenum pname, GLint param);
-
- // Supported forms:
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
-#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLVideoElement? video);
-#endif
-
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
-#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLVideoElement? video);
-#endif
-
- [StrictTypeChecking, RaisesException] void uniform1f(WebGLUniformLocation location, GLfloat x);
- [StrictTypeChecking, Custom, RaisesException] void uniform1fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform1i(WebGLUniformLocation location, GLint x);
- [StrictTypeChecking, Custom, RaisesException] void uniform1iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform2f(WebGLUniformLocation location, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom, RaisesException] void uniform2fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform2i(WebGLUniformLocation location, GLint x, GLint y);
- [StrictTypeChecking, Custom, RaisesException] void uniform2iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform3f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom, RaisesException] void uniform3fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform3i(WebGLUniformLocation location, GLint x, GLint y, GLint z);
- [StrictTypeChecking, Custom, RaisesException] void uniform3iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform4f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom, RaisesException] void uniform4fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform4i(WebGLUniformLocation location, GLint x, GLint y, GLint z, GLint w);
- [StrictTypeChecking, Custom, RaisesException] void uniform4iv(WebGLUniformLocation location, Int32Array v);
-
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix2fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix3fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix4fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
-
- [StrictTypeChecking, RaisesException] void useProgram(WebGLProgram program);
- [StrictTypeChecking, RaisesException] void validateProgram(WebGLProgram program);
-
- [StrictTypeChecking] void vertexAttrib1f(GLuint indx, GLfloat x);
- [StrictTypeChecking, Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
- [StrictTypeChecking, RaisesException] void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
- GLsizei stride, GLintptr offset);
-
- [StrictTypeChecking] void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+] interface WebGLRenderingContext : WebGLRenderingContextBase {
};
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
new file mode 100644
index 000000000..f8fd63f7d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
@@ -0,0 +1,5897 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#include "config.h"
+#include "WebGLRenderingContextBase.h"
+
+#if ENABLE(WEBGL)
+
+#include "ANGLEInstancedArrays.h"
+#include "CachedImage.h"
+#include "DOMWindow.h"
+#include "DiagnosticLoggingClient.h"
+#include "DiagnosticLoggingKeys.h"
+#include "Document.h"
+#include "EXTBlendMinMax.h"
+#include "EXTFragDepth.h"
+#include "EXTShaderTextureLOD.h"
+#include "EXTTextureFilterAnisotropic.h"
+#include "EXTsRGB.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Extensions3D.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntSize.h"
+#include "Logging.h"
+#include "MainFrame.h"
+#include "NotImplemented.h"
+#include "OESElementIndexUint.h"
+#include "OESStandardDerivatives.h"
+#include "OESTextureFloat.h"
+#include "OESTextureFloatLinear.h"
+#include "OESTextureHalfFloat.h"
+#include "OESTextureHalfFloatLinear.h"
+#include "OESVertexArrayObject.h"
+#include "Page.h"
+#include "RenderBox.h"
+#include "RuntimeEnabledFeatures.h"
+#include "Settings.h"
+#include "WebGL2RenderingContext.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLBuffer.h"
+#include "WebGLCompressedTextureATC.h"
+#include "WebGLCompressedTexturePVRTC.h"
+#include "WebGLCompressedTextureS3TC.h"
+#include "WebGLContextAttributes.h"
+#include "WebGLContextEvent.h"
+#include "WebGLContextGroup.h"
+#include "WebGLDebugRendererInfo.h"
+#include "WebGLDebugShaders.h"
+#include "WebGLDepthTexture.h"
+#include "WebGLDrawBuffers.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLLoseContext.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLRenderingContext.h"
+#include "WebGLShader.h"
+#include "WebGLShaderPrecisionFormat.h"
+#include "WebGLTexture.h"
+#include "WebGLUniformLocation.h"
+
+#include <runtime/JSCInlines.h>
+#include <runtime/TypedArrayInlines.h>
+#include <runtime/Uint32Array.h>
+#include <wtf/CheckedArithmetic.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+const int maxGLErrorsAllowedToConsole = 256;
+static const std::chrono::seconds checkContextLossHandlingDelay { 3 };
+
+namespace {
+
+ Platform3DObject objectOrZero(WebGLObject* object)
+ {
+ return object ? object->object() : 0;
+ }
+
+ GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
+ {
+ if (value < min)
+ value = min;
+ if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Return true if a character belongs to the ASCII subset as defined in
+ // GLSL ES 1.0 spec section 3.1.
+ bool validateCharacter(unsigned char c)
+ {
+ // Printing characters are valid except " $ ` @ \ ' DEL.
+ if (c >= 32 && c <= 126
+ && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+ return true;
+ // Horizontal tab, line feed, vertical tab, form feed, carriage return
+ // are also valid.
+ if (c >= 9 && c <= 13)
+ return true;
+ return false;
+ }
+
+ bool isPrefixReserved(const String& name)
+ {
+ if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
+ return true;
+ return false;
+ }
+
+ // Strips comments from shader text. This allows non-ASCII characters
+ // to be used in comments without potentially breaking OpenGL
+ // implementations not expecting characters outside the GLSL ES set.
+ class StripComments {
+ public:
+ StripComments(const String& str)
+ : m_parseState(BeginningOfLine)
+ , m_sourceString(str)
+ , m_length(str.length())
+ , m_position(0)
+ {
+ parse();
+ }
+
+ String result()
+ {
+ return m_builder.toString();
+ }
+
+ private:
+ bool hasMoreCharacters() const
+ {
+ return (m_position < m_length);
+ }
+
+ void parse()
+ {
+ while (hasMoreCharacters()) {
+ process(current());
+ // process() might advance the position.
+ if (hasMoreCharacters())
+ advance();
+ }
+ }
+
+ void process(UChar);
+
+ bool peek(UChar& character) const
+ {
+ if (m_position + 1 >= m_length)
+ return false;
+ character = m_sourceString[m_position + 1];
+ return true;
+ }
+
+ UChar current() const
+ {
+ ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
+ return m_sourceString[m_position];
+ }
+
+ void advance()
+ {
+ ++m_position;
+ }
+
+ bool isNewline(UChar character) const
+ {
+ // Don't attempt to canonicalize newline related characters.
+ return (character == '\n' || character == '\r');
+ }
+
+ void emit(UChar character)
+ {
+ m_builder.append(character);
+ }
+
+ enum ParseState {
+ // Have not seen an ASCII non-whitespace character yet on
+ // this line. Possible that we might see a preprocessor
+ // directive.
+ BeginningOfLine,
+
+ // Have seen at least one ASCII non-whitespace character
+ // on this line.
+ MiddleOfLine,
+
+ // Handling a preprocessor directive. Passes through all
+ // characters up to the end of the line. Disables comment
+ // processing.
+ InPreprocessorDirective,
+
+ // Handling a single-line comment. The comment text is
+ // replaced with a single space.
+ InSingleLineComment,
+
+ // Handling a multi-line comment. Newlines are passed
+ // through to preserve line numbers.
+ InMultiLineComment
+ };
+
+ ParseState m_parseState;
+ String m_sourceString;
+ unsigned m_length;
+ unsigned m_position;
+ StringBuilder m_builder;
+ };
+
+ void StripComments::process(UChar c)
+ {
+ if (isNewline(c)) {
+ // No matter what state we are in, pass through newlines
+ // so we preserve line numbers.
+ emit(c);
+
+ if (m_parseState != InMultiLineComment)
+ m_parseState = BeginningOfLine;
+
+ return;
+ }
+
+ UChar temp = 0;
+ switch (m_parseState) {
+ case BeginningOfLine:
+ if (WTF::isASCIISpace(c)) {
+ emit(c);
+ break;
+ }
+
+ if (c == '#') {
+ m_parseState = InPreprocessorDirective;
+ emit(c);
+ break;
+ }
+
+ // Transition to normal state and re-handle character.
+ m_parseState = MiddleOfLine;
+ process(c);
+ break;
+
+ case MiddleOfLine:
+ if (c == '/' && peek(temp)) {
+ if (temp == '/') {
+ m_parseState = InSingleLineComment;
+ emit(' ');
+ advance();
+ break;
+ }
+
+ if (temp == '*') {
+ m_parseState = InMultiLineComment;
+ // Emit the comment start in case the user has
+ // an unclosed comment and we want to later
+ // signal an error.
+ emit('/');
+ emit('*');
+ advance();
+ break;
+ }
+ }
+
+ emit(c);
+ break;
+
+ case InPreprocessorDirective:
+ // No matter what the character is, just pass it
+ // through. Do not parse comments in this state. This
+ // might not be the right thing to do long term, but it
+ // should handle the #error preprocessor directive.
+ emit(c);
+ break;
+
+ case InSingleLineComment:
+ // The newline code at the top of this function takes care
+ // of resetting our state when we get out of the
+ // single-line comment. Swallow all other characters.
+ break;
+
+ case InMultiLineComment:
+ if (c == '*' && peek(temp) && temp == '/') {
+ emit('*');
+ emit('/');
+ m_parseState = MiddleOfLine;
+ advance();
+ break;
+ }
+
+ // Swallow all other characters. Unclear whether we may
+ // want or need to just emit a space per character to try
+ // to preserve column numbers for debugging purposes.
+ break;
+ }
+ }
+} // namespace anonymous
+
+class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextLostCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ void onContextLost() override { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
+ virtual ~WebGLRenderingContextLostCallback() {}
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ void onErrorMessage(const String& message, GC3Dint) override
+ {
+ if (m_context->m_synthesizedErrorsToConsole)
+ m_context->printGLErrorToConsole(message);
+ }
+ virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+static bool isHighPerformanceContext(const RefPtr<GraphicsContext3D>& context)
+{
+ return context->powerPreferenceUsedForCreation() == WebGLPowerPreference::HighPerformance;
+}
+
+std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(HTMLCanvasElement& canvas, WebGLContextAttributes& attributes, const String& type)
+{
+#if ENABLE(WEBGL2)
+ if (type == "webgl2" && !RuntimeEnabledFeatures::sharedFeatures().webGL2Enabled())
+ return nullptr;
+#else
+ UNUSED_PARAM(type);
+#endif
+
+ Document& document = canvas.document();
+ Frame* frame = document.frame();
+ if (!frame)
+ return nullptr;
+
+ // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
+ // particular, if WebGL contexts were lost one or more times via the GL_ARB_robustness extension.
+ if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled())) {
+ canvas.dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL context."));
+ return nullptr;
+ }
+
+ bool isPendingPolicyResolution = false;
+ Document& topDocument = document.topDocument();
+ Page* page = topDocument.page();
+ bool forcingPendingPolicy = frame->settings().isForcePendingWebGLPolicy();
+
+ if (forcingPendingPolicy || (page && !topDocument.url().isLocalFile())) {
+ WebGLLoadPolicy policy = forcingPendingPolicy ? WebGLPendingCreation : page->mainFrame().loader().client().webGLPolicyForURL(topDocument.url());
+
+ if (policy == WebGLBlockCreation) {
+ LOG(WebGL, "The policy for this URL (%s) is to block WebGL.", topDocument.url().host().utf8().data());
+ return nullptr;
+ }
+
+ if (policy == WebGLPendingCreation) {
+ LOG(WebGL, "WebGL policy is pending. May need to be resolved later.");
+ isPendingPolicyResolution = true;
+ }
+ }
+
+ attributes.noExtensions = true;
+ attributes.shareResources = false;
+
+ if (frame->settings().forceSoftwareWebGLRendering())
+ attributes.forceSoftwareRenderer = true;
+
+ attributes.initialPowerPreference = attributes.powerPreference;
+ if (frame->settings().forceWebGLUsesLowPower()) {
+ if (attributes.powerPreference == GraphicsContext3DPowerPreference::HighPerformance)
+ LOG(WebGL, "Overriding powerPreference from high-performance to low-power.");
+ attributes.powerPreference = GraphicsContext3DPowerPreference::LowPower;
+ }
+
+ if (page)
+ attributes.devicePixelRatio = page->deviceScaleFactor();
+
+#if ENABLE(WEBGL2)
+ if (type == "webgl2")
+ attributes.useGLES3 = true;
+#endif
+
+ if (isPendingPolicyResolution) {
+ LOG(WebGL, "Create a WebGL context that looks real, but will require a policy resolution if used.");
+ std::unique_ptr<WebGLRenderingContextBase> renderingContext = nullptr;
+#if ENABLE(WEBGL2)
+ if (type == "webgl2")
+ renderingContext = std::make_unique<WebGL2RenderingContext>(canvas, attributes);
+ else
+#endif
+ renderingContext = std::make_unique<WebGLRenderingContext>(canvas, attributes);
+ renderingContext->suspendIfNeeded();
+ return renderingContext;
+ }
+
+ auto context = GraphicsContext3D::create(attributes, document.view()->root()->hostWindow());
+ if (!context || !context->makeContextCurrent()) {
+ canvas.dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
+ return nullptr;
+ }
+
+ auto& extensions = context->getExtensions();
+ if (extensions.supports(ASCIILiteral { "GL_EXT_debug_marker" }))
+ extensions.pushGroupMarkerEXT(ASCIILiteral { "WebGLRenderingContext" });
+
+#if ENABLE(WEBGL2) && PLATFORM(MAC)
+ // glTexStorage() was only added to Core in OpenGL 4.2.
+ // However, according to https://developer.apple.com/opengl/capabilities/ all Apple GPUs support this extension.
+ if (attributes.useGLES3 && !extensions.supports("GL_ARB_texture_storage"))
+ return nullptr;
+#endif
+
+ std::unique_ptr<WebGLRenderingContextBase> renderingContext;
+#if ENABLE(WEBGL2)
+ if (type == "webgl2")
+ renderingContext = std::make_unique<WebGL2RenderingContext>(canvas, context.releaseNonNull(), attributes);
+ else
+#endif
+ renderingContext = std::make_unique<WebGLRenderingContext>(canvas, context.releaseNonNull(), attributes);
+ renderingContext->suspendIfNeeded();
+
+ return renderingContext;
+}
+
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement& passedCanvas, WebGLContextAttributes attributes)
+ : CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(&passedCanvas.document())
+ , m_dispatchContextLostEventTimer(*this, &WebGLRenderingContextBase::dispatchContextLostEvent)
+ , m_restoreTimer(*this, &WebGLRenderingContextBase::maybeRestoreContext)
+ , m_attributes(attributes)
+ , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+ , m_isPendingPolicyResolution(true)
+ , m_checkForContextLossHandlingTimer(*this, &WebGLRenderingContextBase::checkForContextLossHandling)
+{
+ registerWithWebGLStateTracker();
+ m_checkForContextLossHandlingTimer.startOneShot(checkContextLossHandlingDelay);
+}
+
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement& passedCanvas, Ref<GraphicsContext3D>&& context, WebGLContextAttributes attributes)
+ : CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(&passedCanvas.document())
+ , m_context(WTFMove(context))
+ , m_dispatchContextLostEventTimer(*this, &WebGLRenderingContextBase::dispatchContextLostEvent)
+ , m_restoreTimer(*this, &WebGLRenderingContextBase::maybeRestoreContext)
+ , m_generatedImageCache(4)
+ , m_attributes(attributes)
+ , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+ , m_checkForContextLossHandlingTimer(*this, &WebGLRenderingContextBase::checkForContextLossHandling)
+{
+ m_contextGroup = WebGLContextGroup::create();
+ m_contextGroup->addContext(*this);
+
+ m_context->setWebGLContext(this);
+
+ m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+ setupFlags();
+ initializeNewContext();
+ registerWithWebGLStateTracker();
+ m_checkForContextLossHandlingTimer.startOneShot(checkContextLossHandlingDelay);
+
+ addActivityStateChangeObserverIfNecessary();
+}
+
+// We check for context loss handling after a few seconds to give the JS a chance to register the event listeners
+// and to discard temporary GL contexts (e.g. feature detection).
+void WebGLRenderingContextBase::checkForContextLossHandling()
+{
+ if (!canvas().renderer())
+ return;
+
+ auto* page = canvas().document().page();
+ if (!page)
+ return;
+
+ bool handlesContextLoss = canvas().hasEventListeners(eventNames().webglcontextlostEvent) && canvas().hasEventListeners(eventNames().webglcontextrestoredEvent);
+ page->diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::pageHandlesWebGLContextLossKey(), handlesContextLoss ? DiagnosticLoggingKeys::yesKey() : DiagnosticLoggingKeys::noKey(), ShouldSample::No);
+}
+
+void WebGLRenderingContextBase::registerWithWebGLStateTracker()
+{
+ auto* page = canvas().document().page();
+ if (!page)
+ return;
+
+ auto* tracker = page->webGLStateTracker();
+ if (!tracker)
+ return;
+
+ m_trackerToken = tracker->token(m_attributes.initialPowerPreference);
+}
+
+void WebGLRenderingContextBase::initializeNewContext()
+{
+ ASSERT(!m_contextLost);
+ m_needsUpdate = true;
+ m_markedCanvasDirty = false;
+ m_activeTextureUnit = 0;
+ m_packAlignment = 4;
+ m_unpackAlignment = 4;
+ m_unpackFlipY = false;
+ m_unpackPremultiplyAlpha = false;
+ m_unpackColorspaceConversion = GraphicsContext3D::BROWSER_DEFAULT_WEBGL;
+ m_boundArrayBuffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+ m_depthMask = true;
+ m_stencilEnabled = false;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_layerCleared = false;
+ m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
+
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
+ m_scissorEnabled = false;
+ m_clearDepth = 1;
+ m_clearStencil = 0;
+ m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
+
+ GC3Dint numCombinedTextureImageUnits = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
+ m_textureUnits.resize(numCombinedTextureImageUnits);
+ for (GC3Dint i = 0; i < numCombinedTextureImageUnits; ++i)
+ m_unrenderableTextureUnits.add(i);
+
+ GC3Dint numVertexAttribs = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
+ m_maxVertexAttribs = numVertexAttribs;
+
+ m_maxTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
+ m_maxRenderbufferSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
+
+ // These two values from EXT_draw_buffers are lazily queried.
+ m_maxDrawBuffers = 0;
+ m_maxColorAttachments = 0;
+
+ m_backDrawBuffer = GraphicsContext3D::BACK;
+ m_drawBuffersWebGLRequirementsChecked = false;
+ m_drawBuffersSupported = false;
+
+ m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+ if (!isGLES2NPOTStrict())
+ createFallbackBlackTextures1x1();
+
+ IntSize canvasSize = clampedCanvasSize();
+ m_context->reshape(canvasSize.width(), canvasSize.height());
+ m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
+ m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
+
+ m_context->setContextLostCallback(std::make_unique<WebGLRenderingContextLostCallback>(this));
+ m_context->setErrorMessageCallback(std::make_unique<WebGLRenderingContextErrorMessageCallback>(this));
+}
+
+void WebGLRenderingContextBase::setupFlags()
+{
+ ASSERT(m_context);
+
+ if (Page* page = canvas().document().page())
+ m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
+
+ m_isGLES2Compliant = m_context->isGLES2Compliant();
+ if (m_isGLES2Compliant) {
+ m_isGLES2NPOTStrict = !m_context->getExtensions().isEnabled("GL_OES_texture_npot");
+ m_isDepthStencilSupported = m_context->getExtensions().isEnabled("GL_OES_packed_depth_stencil");
+ } else {
+ m_isGLES2NPOTStrict = !m_context->getExtensions().isEnabled("GL_ARB_texture_non_power_of_two");
+ m_isDepthStencilSupported = m_context->getExtensions().isEnabled("GL_EXT_packed_depth_stencil");
+ }
+ m_isRobustnessEXTSupported = m_context->getExtensions().isEnabled("GL_EXT_robustness");
+}
+
+void WebGLRenderingContextBase::addCompressedTextureFormat(GC3Denum format)
+{
+ if (!m_compressedTextureFormats.contains(format))
+ m_compressedTextureFormats.append(format);
+}
+
+void WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary()
+{
+ // We are only interested in visibility changes for contexts
+ // that are using the high-performance GPU.
+ if (!isHighPerformanceContext(m_context))
+ return;
+
+ auto* page = canvas().document().page();
+ if (!page)
+ return;
+
+ page->addActivityStateChangeObserver(*this);
+
+ // We won't get a state change right away, so
+ // make sure the context knows if it visible or not.
+ if (m_context)
+ m_context->setContextVisibility(page->isVisible());
+}
+
+void WebGLRenderingContextBase::removeActivityStateChangeObserver()
+{
+ if (auto* page = canvas().document().page())
+ page->removeActivityStateChangeObserver(*this);
+}
+
+WebGLRenderingContextBase::~WebGLRenderingContextBase()
+{
+ // Remove all references to WebGLObjects so if they are the last reference
+ // they will be freed before the last context is removed from the context group.
+ m_boundArrayBuffer = nullptr;
+ m_defaultVertexArrayObject = nullptr;
+ m_boundVertexArrayObject = nullptr;
+ m_vertexAttrib0Buffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+
+ for (auto& textureUnit : m_textureUnits) {
+ textureUnit.texture2DBinding = nullptr;
+ textureUnit.textureCubeMapBinding = nullptr;
+ }
+
+ m_blackTexture2D = nullptr;
+ m_blackTextureCubeMap = nullptr;
+
+ if (!m_isPendingPolicyResolution) {
+ detachAndRemoveAllObjects();
+ destroyGraphicsContext3D();
+ m_contextGroup->removeContext(*this);
+ }
+}
+
+void WebGLRenderingContextBase::destroyGraphicsContext3D()
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ removeActivityStateChangeObserver();
+
+ if (m_context) {
+ m_context->setContextLostCallback(nullptr);
+ m_context->setErrorMessageCallback(nullptr);
+ m_context = nullptr;
+ }
+}
+
+void WebGLRenderingContextBase::markContextChanged()
+{
+ if (m_framebufferBinding)
+ return;
+
+ m_context->markContextChanged();
+
+ m_layerCleared = false;
+ RenderBox* renderBox = canvas().renderBox();
+ if (isAccelerated() && renderBox && renderBox->hasAcceleratedCompositing()) {
+ m_markedCanvasDirty = true;
+ canvas().clearCopiedImage();
+ renderBox->contentChanged(CanvasChanged);
+ } else {
+ if (!m_markedCanvasDirty) {
+ m_markedCanvasDirty = true;
+ canvas().didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+ }
+ }
+}
+
+bool WebGLRenderingContextBase::clearIfComposited(GC3Dbitfield mask)
+{
+ if (isContextLostOrPending())
+ return false;
+
+ if (!m_context->layerComposited() || m_layerCleared
+ || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
+ return false;
+
+ auto contextAttributes = getContextAttributes();
+ ASSERT(contextAttributes);
+
+ // Determine if it's possible to combine the clear the user asked for and this clear.
+ bool combinedClear = mask && !m_scissorEnabled;
+
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (combinedClear && (mask & GraphicsContext3D::COLOR_BUFFER_BIT))
+ m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
+ m_colorMask[1] ? m_clearColor[1] : 0,
+ m_colorMask[2] ? m_clearColor[2] : 0,
+ m_colorMask[3] ? m_clearColor[3] : 0);
+ else
+ m_context->clearColor(0, 0, 0, 0);
+ m_context->colorMask(true, true, true, true);
+ GC3Dbitfield clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
+ if (contextAttributes->depth) {
+ if (!combinedClear || !m_depthMask || !(mask & GraphicsContext3D::DEPTH_BUFFER_BIT))
+ m_context->clearDepth(1.0f);
+ clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ m_context->depthMask(true);
+ }
+ if (contextAttributes->stencil) {
+ if (combinedClear && (mask & GraphicsContext3D::STENCIL_BUFFER_BIT))
+ m_context->clearStencil(m_clearStencil & m_stencilMask);
+ else
+ m_context->clearStencil(0);
+ clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xFFFFFFFF);
+ }
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ m_context->clear(clearMask);
+
+ restoreStateAfterClear();
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ m_layerCleared = true;
+
+ return combinedClear;
+}
+
+void WebGLRenderingContextBase::restoreStateAfterClear()
+{
+ // Restore the state that the context set.
+ if (m_scissorEnabled)
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clearColor(m_clearColor[0], m_clearColor[1],
+ m_clearColor[2], m_clearColor[3]);
+ m_context->colorMask(m_colorMask[0], m_colorMask[1],
+ m_colorMask[2], m_colorMask[3]);
+ m_context->clearDepth(m_clearDepth);
+ m_context->clearStencil(m_clearStencil);
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, m_stencilMask);
+ m_context->depthMask(m_depthMask);
+}
+
+void WebGLRenderingContextBase::markLayerComposited()
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->markLayerComposited();
+}
+
+void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
+{
+ if (isContextLostOrPending())
+ return;
+
+ if (canvas().document().printing())
+ canvas().clearPresentationCopy();
+
+ // Until the canvas is written to by the application, the clear that
+ // happened after it was composited should be ignored by the compositor.
+ if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
+ m_context->paintCompositedResultsToCanvas(canvas().buffer());
+
+ canvas().makePresentationCopy();
+ } else
+ canvas().clearPresentationCopy();
+ clearIfComposited();
+
+ if (!m_markedCanvasDirty && !m_layerCleared)
+ return;
+
+ canvas().clearCopiedImage();
+ m_markedCanvasDirty = false;
+
+ m_context->paintRenderingResultsToCanvas(canvas().buffer());
+}
+
+RefPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ clearIfComposited();
+ return m_context->paintRenderingResultsToImageData();
+}
+
+WebGLTexture::TextureExtensionFlag WebGLRenderingContextBase::textureExtensionFlags() const
+{
+ return static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
+}
+
+void WebGLRenderingContextBase::reshape(int width, int height)
+{
+ if (isContextLostOrPending())
+ return;
+
+ // This is an approximation because at WebGLRenderingContext level we don't
+ // know if the underlying FBO uses textures or renderbuffers.
+ GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
+ // Limit drawing buffer size to 4k to avoid memory exhaustion.
+ const int sizeUpperLimit = 4096;
+ maxSize = std::min(maxSize, sizeUpperLimit);
+ GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
+ GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
+ width = clamp(width, 1, maxWidth);
+ height = clamp(height, 1, maxHeight);
+
+ if (m_needsUpdate) {
+ RenderBox* renderBox = canvas().renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing())
+ renderBox->contentChanged(CanvasChanged);
+ m_needsUpdate = false;
+ }
+
+ // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+ // clear (and this matches what reshape will do).
+ m_context->reshape(width, height);
+
+ auto& textureUnit = m_textureUnits[m_activeTextureUnit];
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(textureUnit.texture2DBinding.get()));
+ if (textureUnit.texture2DBinding && textureUnit.texture2DBinding->needToUseBlackTexture(textureExtensionFlags()))
+ m_unrenderableTextureUnits.add(m_activeTextureUnit);
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+}
+
+int WebGLRenderingContextBase::drawingBufferWidth() const
+{
+ if (isContextLost())
+ return 0;
+
+ if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
+ return 0;
+
+ return m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContextBase::drawingBufferHeight() const
+{
+ if (isContextLost())
+ return 0;
+
+ if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
+ return 0;
+
+ return m_context->getInternalFramebufferSize().height();
+}
+
+unsigned WebGLRenderingContextBase::sizeInBytes(GC3Denum type)
+{
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ return sizeof(GC3Dbyte);
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ return sizeof(GC3Dubyte);
+ case GraphicsContext3D::SHORT:
+ return sizeof(GC3Dshort);
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ return sizeof(GC3Dushort);
+ case GraphicsContext3D::INT:
+ return sizeof(GC3Dint);
+ case GraphicsContext3D::UNSIGNED_INT:
+ return sizeof(GC3Duint);
+ case GraphicsContext3D::FLOAT:
+ return sizeof(GC3Dfloat);
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void WebGLRenderingContextBase::activeTexture(GC3Denum texture)
+{
+ if (isContextLostOrPending())
+ return;
+ if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range");
+ return;
+ }
+ m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
+ m_context->activeTexture(texture);
+}
+
+void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
+ return;
+ if (!program->attachShader(shader)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
+ return;
+ }
+ m_context->attachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onAttached();
+}
+
+void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("bindAttribLocation", program))
+ return;
+ if (!validateLocationLength("bindAttribLocation", name))
+ return;
+ if (!validateString("bindAttribLocation", name))
+ return;
+ if (isPrefixReserved(name)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bindAttribLocation", "index out of range");
+ return;
+ }
+ m_context->bindAttribLocation(objectOrZero(program), index, name);
+}
+
+bool WebGLRenderingContextBase::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
+{
+ deleted = false;
+ if (isContextLostOrPending())
+ return false;
+ if (object) {
+ if (!object->validate(contextGroup(), *this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
+ return false;
+ }
+ deleted = !object->object();
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::bindBuffer(GC3Denum target, WebGLBuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = nullptr;
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
+ return;
+ }
+ if (target == GraphicsContext3D::ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+ else {
+ bool success = false;
+#if ENABLE(WEBGL2)
+ if (isWebGL2()) {
+ success = true;
+ switch (target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ m_boundCopyReadBuffer = buffer;
+ break;
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ m_boundCopyWriteBuffer = buffer;
+ break;
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ m_boundPixelPackBuffer = buffer;
+ break;
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ m_boundPixelUnpackBuffer = buffer;
+ break;
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ m_boundTransformFeedbackBuffer = buffer;
+ break;
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ m_boundUniformBuffer = buffer;
+ break;
+ default:
+ success = false;
+ break;
+ }
+ }
+#endif
+ if (!success) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target");
+ return;
+ }
+ }
+
+ m_context->bindBuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setTarget(target, isWebGL2());
+}
+
+void WebGLRenderingContextBase::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target");
+ return;
+ }
+ m_framebufferBinding = buffer;
+ m_context->bindFramebuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setHasEverBeenBound();
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
+ return;
+ if (deleted)
+ renderBuffer = 0;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target");
+ return;
+ }
+ m_renderbufferBinding = renderBuffer;
+ m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
+}
+
+void WebGLRenderingContextBase::bindTexture(GC3Denum target, WebGLTexture* texture)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindTexture", texture, deleted))
+ return;
+ if (deleted)
+ texture = nullptr;
+ if (texture && texture->getTarget() && texture->getTarget() != target) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
+ return;
+ }
+ GC3Dint maxLevel = 0;
+ auto& textureUnit = m_textureUnits[m_activeTextureUnit];
+ if (target == GraphicsContext3D::TEXTURE_2D) {
+ textureUnit.texture2DBinding = texture;
+ maxLevel = m_maxTextureLevel;
+ if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+ m_unrenderableTextureUnits.add(m_activeTextureUnit);
+ else
+ m_unrenderableTextureUnits.remove(m_activeTextureUnit);
+ } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ textureUnit.textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+ m_unrenderableTextureUnits.add(m_activeTextureUnit);
+ else
+ m_unrenderableTextureUnits.remove(m_activeTextureUnit);
+ } else {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
+ return;
+ }
+ m_context->bindTexture(target, objectOrZero(texture));
+ if (texture)
+ texture->setTarget(target, maxLevel);
+
+ // Note: previously we used to automatically set the TEXTURE_WRAP_R
+ // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
+ // ES 2.0 doesn't expose this flag (a bug in the specification) and
+ // otherwise the application has no control over the seams in this
+ // dimension. However, it appears that supporting this properly on all
+ // platforms is fairly involved (will require a HashMap from texture ID
+ // in all ports), and we have not had any complaints, so the logic has
+ // been removed.
+}
+
+void WebGLRenderingContextBase::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->blendColor(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::blendEquation(GC3Denum mode)
+{
+ if (isContextLostOrPending() || !validateBlendEquation("blendEquation", mode))
+ return;
+ m_context->blendEquation(mode);
+}
+
+void WebGLRenderingContextBase::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
+{
+ if (isContextLostOrPending() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha))
+ return;
+ m_context->blendEquationSeparate(modeRGB, modeAlpha);
+}
+
+
+void WebGLRenderingContextBase::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+ if (isContextLostOrPending() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
+ return;
+ m_context->blendFunc(sfactor, dfactor);
+}
+
+void WebGLRenderingContextBase::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
+{
+ // Note: Alpha does not have the same restrictions as RGB.
+ if (isContextLostOrPending() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB))
+ return;
+ m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void WebGLRenderingContextBase::bufferData(GC3Denum target, long long size, GC3Denum usage)
+{
+ if (isContextLostOrPending())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+ if (!buffer)
+ return;
+ if (size < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0");
+ return;
+ }
+ if (!size) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size == 0");
+ return;
+ }
+ if (!buffer->associateBufferData(static_cast<GC3Dsizeiptr>(size))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
+ return;
+ }
+
+ m_context->moveErrorsToSyntheticErrorList();
+ m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The bufferData function failed. Tell the buffer it doesn't have the data it thinks it does.
+ buffer->disassociateBufferData();
+ }
+}
+
+void WebGLRenderingContextBase::bufferData(GC3Denum target, std::optional<BufferDataSource>&& data, GC3Denum usage)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!data) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "null data");
+ return;
+ }
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+ if (!buffer)
+ return;
+
+ WTF::visit([&](auto& data) {
+ if (!buffer->associateBufferData(data.get())) {
+ this->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
+ return;
+ }
+
+ m_context->moveErrorsToSyntheticErrorList();
+ m_context->bufferData(target, data->byteLength(), data->data(), usage);
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The bufferData function failed. Tell the buffer it doesn't have the data it thinks it does.
+ buffer->disassociateBufferData();
+ }
+ }, data.value());
+}
+
+void WebGLRenderingContextBase::bufferSubData(GC3Denum target, long long offset, std::optional<BufferDataSource>&& data)
+{
+ if (isContextLostOrPending())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
+ return;
+ }
+ if (!data)
+ return;
+
+ WTF::visit([&](auto& data) {
+ if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data.get())) {
+ this->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
+ return;
+ }
+
+ m_context->moveErrorsToSyntheticErrorList();
+ m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does.
+ buffer->disassociateBufferData();
+ }
+ }, data.value());
+}
+
+GC3Denum WebGLRenderingContextBase::checkFramebufferStatus(GC3Denum target)
+{
+ if (isContextLostOrPending())
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+ const char* reason = "framebuffer incomplete";
+ GC3Denum result = m_framebufferBinding->checkStatus(&reason);
+ if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ printGLWarningToConsole("checkFramebufferStatus", reason);
+ return result;
+ }
+ result = m_context->checkFramebufferStatus(target);
+ return result;
+}
+
+void WebGLRenderingContextBase::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
+{
+ if (isContextLostOrPending())
+ return;
+ if (std::isnan(r))
+ r = 0;
+ if (std::isnan(g))
+ g = 0;
+ if (std::isnan(b))
+ b = 0;
+ if (std::isnan(a))
+ a = 1;
+ m_clearColor[0] = r;
+ m_clearColor[1] = g;
+ m_clearColor[2] = b;
+ m_clearColor[3] = a;
+ m_context->clearColor(r, g, b, a);
+}
+
+void WebGLRenderingContextBase::clearDepth(GC3Dfloat depth)
+{
+ if (isContextLostOrPending())
+ return;
+ m_clearDepth = depth;
+ m_context->clearDepth(depth);
+}
+
+void WebGLRenderingContextBase::clearStencil(GC3Dint s)
+{
+ if (isContextLostOrPending())
+ return;
+ m_clearStencil = s;
+ m_context->clearStencil(s);
+}
+
+void WebGLRenderingContextBase::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
+{
+ if (isContextLostOrPending())
+ return;
+ m_colorMask[0] = red;
+ m_colorMask[1] = green;
+ m_colorMask[2] = blue;
+ m_colorMask[3] = alpha;
+ m_context->colorMask(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::compileShader(WebGLShader* shader)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("compileShader", shader))
+ return;
+ m_context->compileShader(objectOrZero(shader));
+ GC3Dint value;
+ m_context->getShaderiv(objectOrZero(shader), GraphicsContext3D::COMPILE_STATUS, &value);
+ shader->setValid(value);
+}
+
+void WebGLRenderingContextBase::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, ArrayBufferView& data)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateTexFuncLevel("compressedTexImage2D", target, level))
+ return;
+
+ if (!validateCompressedTexFormat(internalformat)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+ return;
+ }
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "border not 0");
+ return;
+ }
+ if (!validateCompressedTexDimensions("compressedTexImage2D", target, level, width, height, internalformat))
+ return;
+ if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!validateNPOTTextureLevel(width, height, level, "compressedTexImage2D"))
+ return;
+ m_context->moveErrorsToSyntheticErrorList();
+ m_context->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data.byteLength(), data.baseAddress());
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The compressedTexImage2D function failed. Tell the WebGLTexture it doesn't have the data for this level.
+ tex->markInvalid(target, level);
+ return;
+ }
+
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ tex->setCompressed();
+}
+
+void WebGLRenderingContextBase::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& data)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
+ return;
+ if (!validateCompressedTexFormat(format)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+ return;
+ }
+ if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
+ if (!tex)
+ return;
+
+ if (format != tex->getInternalFormat(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
+ return;
+ }
+
+ if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
+ return;
+
+ graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data.byteLength(), data.baseAddress());
+ tex->setCompressed();
+}
+
+bool WebGLRenderingContextBase::validateSettableTexInternalFormat(const char* functionName, GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ case GraphicsContext3D::DEPTH_STENCIL:
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ case GraphicsContext3D::STENCIL_INDEX8:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format can not be set, only rendered to");
+ return false;
+ default:
+ return true;
+ }
+}
+
+void WebGLRenderingContextBase::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
+ if (!tex)
+ return;
+ if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
+ return;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
+ return;
+ }
+ GC3Denum internalFormat = tex->getInternalFormat(target, level);
+ if (!validateSettableTexInternalFormat("copyTexSubImage2D", internalFormat))
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ GC3Denum format;
+ GC3Denum type;
+ if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(tex->getInternalFormat(target, level), format, type)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "copyTexSubImage2D", "Texture has unknown internal format");
+ return;
+ }
+ std::unique_ptr<unsigned char[]> zero;
+ if (width && height) {
+ unsigned size;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ zero = std::make_unique<unsigned char[]>(size);
+ if (!zero) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory");
+ return;
+ }
+ memset(zero.get(), 0, size);
+ }
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
+ if (clippedWidth > 0 && clippedHeight > 0)
+ m_context->copyTexSubImage2D(target, level, xoffset + clippedX - x, yoffset + clippedY - y, clippedX, clippedY, clippedWidth, clippedHeight);
+ } else
+ m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+RefPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ auto buffer = WebGLBuffer::create(*this);
+ addSharedObject(buffer.get());
+ return WTFMove(buffer);
+}
+
+RefPtr<WebGLFramebuffer> WebGLRenderingContextBase::createFramebuffer()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ auto buffer = WebGLFramebuffer::create(*this);
+ addContextObject(buffer.get());
+ return WTFMove(buffer);
+}
+
+RefPtr<WebGLTexture> WebGLRenderingContextBase::createTexture()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ auto texture = WebGLTexture::create(*this);
+ addSharedObject(texture.get());
+ return WTFMove(texture);
+}
+
+RefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ auto program = WebGLProgram::create(*this);
+ addSharedObject(program.get());
+ return WTFMove(program);
+}
+
+RefPtr<WebGLRenderbuffer> WebGLRenderingContextBase::createRenderbuffer()
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ auto buffer = WebGLRenderbuffer::create(*this);
+ addSharedObject(buffer.get());
+ return WTFMove(buffer);
+}
+
+RefPtr<WebGLShader> WebGLRenderingContextBase::createShader(GC3Denum type)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type");
+ return nullptr;
+ }
+
+ auto shader = WebGLShader::create(*this, type);
+ addSharedObject(shader.get());
+ return WTFMove(shader);
+}
+
+void WebGLRenderingContextBase::cullFace(GC3Denum mode)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->cullFace(mode);
+}
+
+bool WebGLRenderingContextBase::deleteObject(WebGLObject* object)
+{
+ if (isContextLostOrPending() || !object)
+ return false;
+ if (!object->validate(contextGroup(), *this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
+ return false;
+ }
+ if (object->object())
+ // We need to pass in context here because we want
+ // things in this context unbound.
+ object->deleteObject(graphicsContext3D());
+ return true;
+}
+
+void WebGLRenderingContextBase::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (!deleteObject(buffer))
+ return;
+ if (m_boundArrayBuffer == buffer)
+ m_boundArrayBuffer = nullptr;
+
+ m_boundVertexArrayObject->unbindBuffer(*buffer);
+}
+
+void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!deleteObject(framebuffer))
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = nullptr;
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ }
+}
+
+void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
+{
+ deleteObject(program);
+ // We don't reset m_currentProgram to 0 here because the deletion of the
+ // current program is delayed.
+}
+
+void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!deleteObject(renderbuffer))
+ return;
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = nullptr;
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
+}
+
+void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
+{
+ deleteObject(shader);
+}
+
+void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
+{
+ if (!deleteObject(texture))
+ return;
+
+ unsigned current = 0;
+ for (auto& textureUnit : m_textureUnits) {
+ if (texture == textureUnit.texture2DBinding) {
+ textureUnit.texture2DBinding = nullptr;
+ m_unrenderableTextureUnits.remove(current);
+ }
+ if (texture == textureUnit.textureCubeMapBinding) {
+ textureUnit.textureCubeMapBinding = nullptr;
+ m_unrenderableTextureUnits.remove(current);
+ }
+ ++current;
+ }
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
+}
+
+void WebGLRenderingContextBase::depthFunc(GC3Denum func)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->depthFunc(func);
+}
+
+void WebGLRenderingContextBase::depthMask(GC3Dboolean flag)
+{
+ if (isContextLostOrPending())
+ return;
+ m_depthMask = flag;
+ m_context->depthMask(flag);
+}
+
+void WebGLRenderingContextBase::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
+{
+ if (isContextLostOrPending())
+ return;
+ if (zNear > zFar) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar");
+ return;
+ }
+ m_context->depthRange(zNear, zFar);
+}
+
+void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
+ return;
+ if (!program->detachShader(shader)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
+ return;
+ }
+ m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached(graphicsContext3D());
+}
+
+void WebGLRenderingContextBase::disable(GC3Denum cap)
+{
+ if (isContextLostOrPending() || !validateCapability("disable", cap))
+ return;
+ if (cap == GraphicsContext3D::STENCIL_TEST) {
+ m_stencilEnabled = false;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GraphicsContext3D::SCISSOR_TEST)
+ m_scissorEnabled = false;
+ m_context->disable(cap);
+}
+
+void WebGLRenderingContextBase::disableVertexAttribArray(GC3Duint index)
+{
+ if (isContextLostOrPending())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = false;
+
+ if (index > 0 || isGLES2Compliant())
+ m_context->disableVertexAttribArray(index);
+}
+
+bool WebGLRenderingContextBase::validateNPOTTextureLevel(GC3Dsizei width, GC3Dsizei height, GC3Dint level, const char* functionName)
+{
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
+{
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ return false;
+
+ if (offset < 0)
+ return false;
+
+ if (type == GraphicsContext3D::UNSIGNED_INT) {
+ // For an unsigned int array, offset must be divisible by 4 for alignment reasons.
+ if (offset % 4)
+ return false;
+
+ // Make uoffset an element offset.
+ offset /= 4;
+
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 4;
+ if (offset > n || count > n - offset)
+ return false;
+ } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
+ if (offset % 2)
+ return false;
+
+ // Make uoffset an element offset.
+ offset /= 2;
+
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 2;
+ if (offset > n || count > n - offset)
+ return false;
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength();
+ if (offset > n || count > n - offset)
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired)
+{
+ ASSERT(count >= 0 && offset >= 0);
+ unsigned lastIndex = 0;
+
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ return false;
+
+ if (!count) {
+ numElementsRequired = 0;
+ return true;
+ }
+
+ if (!elementArrayBuffer->elementArrayBuffer())
+ return false;
+
+ unsigned long uoffset = offset;
+ unsigned long n = count;
+
+ if (type == GraphicsContext3D::UNSIGNED_INT) {
+ // Make uoffset an element offset.
+ uoffset /= sizeof(GC3Duint);
+ const GC3Duint* p = static_cast<const GC3Duint*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // Make uoffset an element offset.
+ uoffset /= sizeof(GC3Dushort);
+ const GC3Dushort* p = static_cast<const GC3Dushort*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ const GC3Dubyte* p = static_cast<const GC3Dubyte*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ }
+
+ // Then set the last index in the index array and make sure it is valid.
+ numElementsRequired = lastIndex + 1;
+ return numElementsRequired > 0;
+}
+
+bool WebGLRenderingContextBase::validateVertexAttributes(unsigned elementCount, unsigned primitiveCount)
+{
+ if (!m_currentProgram)
+ return false;
+
+ // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+ for (unsigned i = 0; i < m_maxVertexAttribs; ++i) {
+ if (!m_boundVertexArrayObject->getVertexAttribState(i).validateBinding())
+ return false;
+ }
+
+ if (!elementCount)
+ return true;
+
+ // Look in each consumed vertex attrib (by the current program).
+ bool sawNonInstancedAttrib = false;
+ bool sawEnabledAttrib = false;
+ int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
+ for (int i = 0; i < numActiveAttribLocations; ++i) {
+ int loc = m_currentProgram->getActiveAttribLocation(i);
+ if (loc >= 0 && loc < static_cast<int>(m_maxVertexAttribs)) {
+ const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(loc);
+ if (state.enabled) {
+ sawEnabledAttrib = true;
+ // Avoid off-by-one errors in numElements computation.
+ // For the last element, we will only touch the data for the
+ // element and nothing beyond it.
+ int bytesRemaining = static_cast<int>(state.bufferBinding->byteLength() - state.offset);
+ unsigned numElements = 0;
+ ASSERT(state.stride > 0);
+ if (bytesRemaining >= state.bytesPerElement)
+ numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
+ unsigned instancesRequired = 0;
+ if (state.divisor) {
+ instancesRequired = ceil(static_cast<float>(primitiveCount) / state.divisor);
+ if (instancesRequired > numElements)
+ return false;
+ } else {
+ sawNonInstancedAttrib = true;
+ if (elementCount > numElements)
+ return false;
+ }
+ }
+ }
+ }
+
+ if (!sawNonInstancedAttrib && sawEnabledAttrib)
+ return false;
+
+ bool usingSimulatedArrayBuffer = m_currentProgram->isUsingVertexAttrib0();
+
+ // Guard against access into non-existent buffers.
+ if (elementCount && !sawEnabledAttrib && !usingSimulatedArrayBuffer)
+ return false;
+
+ if (elementCount && sawEnabledAttrib) {
+ if (!m_boundArrayBuffer && !m_boundVertexArrayObject->getElementArrayBuffer()) {
+ if (usingSimulatedArrayBuffer) {
+ auto& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (state.enabled && state.isBound()) {
+ if (state.bufferBinding->getTarget() == GraphicsContext3D::ARRAY_BUFFER || state.bufferBinding->getTarget() == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ return !!state.bufferBinding->byteLength();
+ }
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateWebGLObject(const char* functionName, WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
+ return false;
+ }
+ if (!object->validate(contextGroup(), *this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primitiveCount)
+{
+ if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ if (first < 0 || count < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "first or count < 0");
+ return false;
+ }
+
+ if (!count) {
+ markContextChanged();
+ return false;
+ }
+
+ if (primitiveCount < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
+ return false;
+ }
+
+ // Ensure we have a valid rendering state.
+ Checked<GC3Dint, RecordOverflow> checkedFirst(first);
+ Checked<GC3Dint, RecordOverflow> checkedCount(count);
+ Checked<GC3Dint, RecordOverflow> checkedSum = checkedFirst + checkedCount;
+ Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
+ if (checkedSum.hasOverflowed() || checkedPrimitiveCount.hasOverflowed() || !validateVertexAttributes(checkedSum.unsafeGet(), checkedPrimitiveCount.unsafeGet())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
+ return false;
+ }
+ if (!validateSimulatedVertexAttrib0(checkedSum.unsafeGet() - 1)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access outside the bounds of the simulated vertexAttrib0 array");
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primitiveCount)
+{
+ if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ break;
+ case GraphicsContext3D::UNSIGNED_INT:
+ if (m_oesElementIndexUint || isWebGL2())
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
+ return false;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
+ return false;
+ }
+
+ if (count < 0 || offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "count or offset < 0");
+ return false;
+ }
+
+ if (!count) {
+ markContextChanged();
+ return false;
+ }
+
+ if (primitiveCount < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
+ return false;
+ }
+
+ if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
+ return false;
+ }
+
+ // Ensure we have a valid rendering state.
+ if (!validateElementArraySize(count, type, static_cast<GC3Dintptr>(offset))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "request out of bounds for current ELEMENT_ARRAY_BUFFER");
+ return false;
+ }
+ if (!count)
+ return false;
+
+ Checked<GC3Dint, RecordOverflow> checkedCount(count);
+ Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
+ if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
+ return false;
+ }
+
+ if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+ if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast<GC3Dintptr>(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
+ return false;
+ }
+ }
+
+ if (!validateSimulatedVertexAttrib0(numElements)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access outside the bounds of the simulated vertexAttrib0 array");
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+void WebGLRenderingContextBase::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
+{
+ if (!validateDrawArrays("drawArrays", mode, first, count, 0))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ bool usesFallbackTexture = false;
+ if (!isGLES2NPOTStrict())
+ usesFallbackTexture = checkTextureCompleteness("drawArrays", true);
+
+ m_context->drawArrays(mode, first, count);
+
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (usesFallbackTexture)
+ checkTextureCompleteness("drawArrays", false);
+ markContextChanged();
+}
+
+void WebGLRenderingContextBase::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset)
+{
+ unsigned numElements = 0;
+ if (!validateDrawElements("drawElements", mode, count, type, offset, numElements, 0))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+
+ bool usesFallbackTexture = false;
+ if (!isGLES2NPOTStrict())
+ usesFallbackTexture = checkTextureCompleteness("drawElements", true);
+
+ m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
+
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (usesFallbackTexture)
+ checkTextureCompleteness("drawElements", false);
+ markContextChanged();
+}
+
+void WebGLRenderingContextBase::enable(GC3Denum cap)
+{
+ if (isContextLostOrPending() || !validateCapability("enable", cap))
+ return;
+ if (cap == GraphicsContext3D::STENCIL_TEST) {
+ m_stencilEnabled = true;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GraphicsContext3D::SCISSOR_TEST)
+ m_scissorEnabled = true;
+ m_context->enable(cap);
+}
+
+void WebGLRenderingContextBase::enableVertexAttribArray(GC3Duint index)
+{
+ if (isContextLostOrPending())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = true;
+
+ m_context->enableVertexAttribArray(index);
+}
+
+void WebGLRenderingContextBase::finish()
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->finish();
+}
+
+void WebGLRenderingContextBase::flush()
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->flush();
+}
+
+void WebGLRenderingContextBase::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer)
+{
+ if (isContextLostOrPending() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
+ return;
+ if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
+ return;
+ }
+ if (buffer && !buffer->validate(contextGroup(), *this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+ break;
+ default:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level)
+{
+ if (isContextLostOrPending() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
+ return;
+ if (level) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
+ return;
+ }
+ if (texture && !texture->validate(contextGroup(), *this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject textureObject = objectOrZero(texture);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_context->framebufferTexture2D(target, GraphicsContext3D::DEPTH_ATTACHMENT, textarget, textureObject, level);
+ m_context->framebufferTexture2D(target, GraphicsContext3D::STENCIL_ATTACHMENT, textarget, textureObject, level);
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ default:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::frontFace(GC3Denum mode)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->frontFace(mode);
+}
+
+void WebGLRenderingContextBase::generateMipmap(GC3Denum target)
+{
+ if (isContextLostOrPending())
+ return;
+ WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
+ return;
+ }
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=123916. Compressed textures should be allowed in WebGL 2:
+ if (tex->isCompressed()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "trying to generate mipmaps from compressed texture");
+ return;
+ }
+ if (!validateSettableTexInternalFormat("generateMipmap", tex->getInternalFormat(target, 0)))
+ return;
+
+ // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
+ // on Mac. Remove the hack once this driver bug is fixed.
+#if OS(DARWIN)
+ bool needToResetMinFilter = false;
+ if (tex->getMinFilter() != GraphicsContext3D::NEAREST_MIPMAP_LINEAR) {
+ m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST_MIPMAP_LINEAR);
+ needToResetMinFilter = true;
+ }
+#endif
+ m_context->generateMipmap(target);
+#if OS(DARWIN)
+ if (needToResetMinFilter)
+ m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, tex->getMinFilter());
+#endif
+ tex->generateMipmapLevelInfo();
+}
+
+RefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* program, GC3Duint index)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getActiveAttrib", program))
+ return nullptr;
+ ActiveInfo info;
+ if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
+ return nullptr;
+
+ LOG(WebGL, "Returning active attribute %d: %s", index, info.name.utf8().data());
+
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+RefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveUniform(WebGLProgram* program, GC3Duint index)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getActiveUniform", program))
+ return nullptr;
+ ActiveInfo info;
+ if (!m_context->getActiveUniform(objectOrZero(program), index, info))
+ return nullptr;
+ if (!isGLES2Compliant())
+ if (info.size > 1 && !info.name.endsWith("[0]"))
+ info.name.append("[0]");
+
+ LOG(WebGL, "Returning active uniform %d: %s", index, info.name.utf8().data());
+
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+std::optional<Vector<RefPtr<WebGLShader>>> WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getAttachedShaders", program))
+ return std::nullopt;
+
+ const GC3Denum shaderTypes[] = {
+ GraphicsContext3D::VERTEX_SHADER,
+ GraphicsContext3D::FRAGMENT_SHADER
+ };
+ Vector<RefPtr<WebGLShader>> shaderObjects;
+ for (auto shaderType : shaderTypes) {
+ WebGLShader* shader = program->getAttachedShader(shaderType);
+ if (shader)
+ shaderObjects.append(shader);
+ }
+ return shaderObjects;
+}
+
+GC3Dint WebGLRenderingContextBase::getAttribLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getAttribLocation", program))
+ return -1;
+ if (!validateLocationLength("getAttribLocation", name))
+ return -1;
+ if (!validateString("getAttribLocation", name))
+ return -1;
+ if (isPrefixReserved(name))
+ return -1;
+ if (!program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getAttribLocation", "program not linked");
+ return -1;
+ }
+ return m_context->getAttribLocation(objectOrZero(program), name);
+}
+
+WebGLAny WebGLRenderingContextBase::getBufferParameter(GC3Denum target, GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+
+ bool valid = false;
+ if (target == GraphicsContext3D::ARRAY_BUFFER || target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ valid = true;
+#if ENABLE(WEBGL2)
+ if (isWebGL2()) {
+ switch (target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ valid = true;
+ }
+ }
+#endif
+ if (!valid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
+ return nullptr;
+ }
+
+ if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name");
+ return nullptr;
+ }
+
+ GC3Dint value = 0;
+ m_context->getBufferParameteriv(target, pname, &value);
+ if (pname == GraphicsContext3D::BUFFER_SIZE)
+ return value;
+ return static_cast<unsigned>(value);
+}
+
+std::optional<WebGLContextAttributes> WebGLRenderingContextBase::getContextAttributes()
+{
+ if (isContextLostOrPending())
+ return std::nullopt;
+
+ // Also, we need to enforce requested values of "false" for depth
+ // and stencil, regardless of the properties of the underlying
+ // GraphicsContext3D.
+
+ auto attributes = m_context->getContextAttributes();
+ if (!m_attributes.depth)
+ attributes.depth = false;
+ if (!m_attributes.stencil)
+ attributes.stencil = false;
+ return WTFMove(attributes);
+}
+
+GC3Denum WebGLRenderingContextBase::getError()
+{
+ if (m_isPendingPolicyResolution)
+ return GraphicsContext3D::NO_ERROR;
+ return m_context->getError();
+}
+
+WebGLAny WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GC3Denum pname)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getProgramParameter", program))
+ return nullptr;
+
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::DELETE_STATUS:
+ return program->isDeleted();
+ case GraphicsContext3D::VALIDATE_STATUS:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return static_cast<bool>(value);
+ case GraphicsContext3D::LINK_STATUS:
+ return program->getLinkStatus();
+ case GraphicsContext3D::ATTACHED_SHADERS:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return value;
+ case GraphicsContext3D::ACTIVE_ATTRIBUTES:
+ case GraphicsContext3D::ACTIVE_UNIFORMS:
+ m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), pname, &value);
+ return value;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+String WebGLRenderingContextBase::getProgramInfoLog(WebGLProgram* program)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getProgramInfoLog", program))
+ return String();
+ return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
+}
+
+WebGLAny WebGLRenderingContextBase::getRenderbufferParameter(GC3Denum target, GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target");
+ return nullptr;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
+ return nullptr;
+ }
+
+ if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
+ && !m_renderbufferBinding->isValid()) {
+ ASSERT(!isDepthStencilSupported());
+ int value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ value = m_renderbufferBinding->getWidth();
+ break;
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ value = m_renderbufferBinding->getHeight();
+ break;
+ case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
+ value = 0;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
+ value = 24;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
+ value = 8;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return m_renderbufferBinding->getInternalFormat();
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return nullptr;
+ }
+ return value;
+ }
+
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
+ m_context->getRenderbufferParameteriv(target, pname, &value);
+ return value;
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return m_renderbufferBinding->getInternalFormat();
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+WebGLAny WebGLRenderingContextBase::getShaderParameter(WebGLShader* shader, GC3Denum pname)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getShaderParameter", shader))
+ return nullptr;
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::DELETE_STATUS:
+ return shader->isDeleted();
+ case GraphicsContext3D::COMPILE_STATUS:
+ m_context->getShaderiv(objectOrZero(shader), pname, &value);
+ return static_cast<bool>(value);
+ case GraphicsContext3D::SHADER_TYPE:
+ m_context->getShaderiv(objectOrZero(shader), pname, &value);
+ return static_cast<unsigned>(value);
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+String WebGLRenderingContextBase::getShaderInfoLog(WebGLShader* shader)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getShaderInfoLog", shader))
+ return String();
+ return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
+}
+
+RefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContextBase::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ switch (shaderType) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
+ return nullptr;
+ }
+ switch (precisionType) {
+ case GraphicsContext3D::LOW_FLOAT:
+ case GraphicsContext3D::MEDIUM_FLOAT:
+ case GraphicsContext3D::HIGH_FLOAT:
+ case GraphicsContext3D::LOW_INT:
+ case GraphicsContext3D::MEDIUM_INT:
+ case GraphicsContext3D::HIGH_INT:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
+ return nullptr;
+ }
+
+ GC3Dint range[2] = {0, 0};
+ GC3Dint precision = 0;
+ m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
+ return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
+}
+
+String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getShaderSource", shader))
+ return String();
+ return ensureNotNull(shader->getSource());
+}
+
+WebGLAny WebGLRenderingContextBase::getTexParameter(GC3Denum target, GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+ WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
+ if (!tex)
+ return nullptr;
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ m_context->getTexParameteriv(target, pname, &value);
+ return static_cast<unsigned>(value);
+ case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (m_extTextureFilterAnisotropic) {
+ m_context->getTexParameteriv(target, pname, &value);
+ return static_cast<unsigned>(value);
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return nullptr;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+WebGLAny WebGLRenderingContextBase::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getUniform", program))
+ return nullptr;
+ if (!uniformLocation || uniformLocation->program() != program) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
+ return nullptr;
+ }
+ GC3Dint location = uniformLocation->location();
+
+ GC3Denum baseType;
+ unsigned length;
+ switch (uniformLocation->type()) {
+ case GraphicsContext3D::BOOL:
+ baseType = GraphicsContext3D::BOOL;
+ length = 1;
+ break;
+ case GraphicsContext3D::BOOL_VEC2:
+ baseType = GraphicsContext3D::BOOL;
+ length = 2;
+ break;
+ case GraphicsContext3D::BOOL_VEC3:
+ baseType = GraphicsContext3D::BOOL;
+ length = 3;
+ break;
+ case GraphicsContext3D::BOOL_VEC4:
+ baseType = GraphicsContext3D::BOOL;
+ length = 4;
+ break;
+ case GraphicsContext3D::INT:
+ baseType = GraphicsContext3D::INT;
+ length = 1;
+ break;
+ case GraphicsContext3D::INT_VEC2:
+ baseType = GraphicsContext3D::INT;
+ length = 2;
+ break;
+ case GraphicsContext3D::INT_VEC3:
+ baseType = GraphicsContext3D::INT;
+ length = 3;
+ break;
+ case GraphicsContext3D::INT_VEC4:
+ baseType = GraphicsContext3D::INT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 1;
+ break;
+ case GraphicsContext3D::FLOAT_VEC2:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 2;
+ break;
+ case GraphicsContext3D::FLOAT_VEC3:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 3;
+ break;
+ case GraphicsContext3D::FLOAT_VEC4:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT_MAT2:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT_MAT3:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 9;
+ break;
+ case GraphicsContext3D::FLOAT_MAT4:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 16;
+ break;
+ case GraphicsContext3D::SAMPLER_2D:
+ case GraphicsContext3D::SAMPLER_CUBE:
+ baseType = GraphicsContext3D::INT;
+ length = 1;
+ break;
+ default:
+ // Can't handle this type
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type");
+ return nullptr;
+ }
+ switch (baseType) {
+ case GraphicsContext3D::FLOAT: {
+ GC3Dfloat value[16] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions().getnUniformfvEXT(objectOrZero(program), location, 16 * sizeof(GC3Dfloat), value);
+ else
+ m_context->getUniformfv(objectOrZero(program), location, value);
+ if (length == 1)
+ return value[0];
+ return Float32Array::create(value, length);
+ }
+ case GraphicsContext3D::INT: {
+ GC3Dint value[4] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions().getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
+ else
+ m_context->getUniformiv(objectOrZero(program), location, value);
+ if (length == 1)
+ return value[0];
+ return Int32Array::create(value, length);
+ }
+ case GraphicsContext3D::BOOL: {
+ GC3Dint value[4] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions().getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
+ else
+ m_context->getUniformiv(objectOrZero(program), location, value);
+ if (length > 1) {
+ Vector<bool> vector(length);
+ for (unsigned j = 0; j < length; j++)
+ vector[j] = value[j];
+ return WTFMove(vector);
+ }
+ return static_cast<bool>(value[0]);
+ }
+ default:
+ notImplemented();
+ }
+
+ // If we get here, something went wrong in our unfortunately complex logic above
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error");
+ return nullptr;
+}
+
+RefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("getUniformLocation", program))
+ return nullptr;
+ if (!validateLocationLength("getUniformLocation", name))
+ return nullptr;
+ if (!validateString("getUniformLocation", name))
+ return nullptr;
+ if (isPrefixReserved(name))
+ return nullptr;
+ if (!program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniformLocation", "program not linked");
+ return nullptr;
+ }
+ GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
+ if (uniformLocation == -1)
+ return nullptr;
+
+ GC3Dint activeUniforms = 0;
+ m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
+ for (GC3Dint i = 0; i < activeUniforms; i++) {
+ ActiveInfo info;
+ if (!m_context->getActiveUniform(objectOrZero(program), i, info))
+ return nullptr;
+ // Strip "[0]" from the name if it's an array.
+ if (info.name.endsWith("[0]"))
+ info.name = info.name.left(info.name.length() - 3);
+ // If it's an array, we need to iterate through each element, appending "[index]" to the name.
+ for (GC3Dint index = 0; index < info.size; ++index) {
+ String uniformName = info.name + "[" + String::number(index) + "]";
+
+ if (name == uniformName || name == info.name)
+ return WebGLUniformLocation::create(program, uniformLocation, info.type);
+ }
+ }
+ return nullptr;
+}
+
+WebGLAny WebGLRenderingContextBase::getVertexAttrib(GC3Duint index, GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return nullptr;
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range");
+ return nullptr;
+ }
+
+ const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+
+ if ((isWebGL2() || m_angleInstancedArrays) && pname == GraphicsContext3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
+ return state.divisor;
+
+ switch (pname) {
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ if ((!isGLES2Compliant() && !index && m_boundVertexArrayObject->getVertexAttribState(0).bufferBinding == m_vertexAttrib0Buffer)
+ || !state.bufferBinding
+ || !state.bufferBinding->object())
+ return nullptr;
+ return state.bufferBinding;
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
+ return state.enabled;
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ return state.normalized;
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
+ return state.size;
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
+ return state.originalStride;
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
+ return state.type;
+ case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
+ return Float32Array::create(m_vertexAttribValue[index].value, 4);
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
+ return nullptr;
+ }
+}
+
+long long WebGLRenderingContextBase::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+{
+ if (isContextLostOrPending())
+ return 0;
+ return m_context->getVertexAttribOffset(index, pname);
+}
+
+GC3Dboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
+{
+ if (!buffer || isContextLostOrPending())
+ return 0;
+
+ if (!buffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContextBase::isContextLost() const
+{
+ return m_contextLost;
+}
+
+bool WebGLRenderingContextBase::isContextLostOrPending()
+{
+ if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution) {
+ LOG(WebGL, "Context is being used. Attempt to resolve the policy.");
+ Document& document = canvas().document().topDocument();
+ Page* page = document.page();
+ if (page && !document.url().isLocalFile())
+ page->mainFrame().loader().client().resolveWebGLPolicyForURL(document.url());
+ // FIXME: We don't currently do anything with the result from resolution. A more
+ // complete implementation might try to construct a real context, etc and proceed
+ // with normal operation.
+ // https://bugs.webkit.org/show_bug.cgi?id=129122
+ m_hasRequestedPolicyResolution = true;
+ }
+
+ return m_contextLost || m_isPendingPolicyResolution;
+}
+
+GC3Dboolean WebGLRenderingContextBase::isEnabled(GC3Denum cap)
+{
+ if (isContextLostOrPending() || !validateCapability("isEnabled", cap))
+ return 0;
+ if (cap == GraphicsContext3D::STENCIL_TEST)
+ return m_stencilEnabled;
+ return m_context->isEnabled(cap);
+}
+
+GC3Dboolean WebGLRenderingContextBase::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!framebuffer || isContextLostOrPending())
+ return 0;
+
+ if (!framebuffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isFramebuffer(framebuffer->object());
+}
+
+GC3Dboolean WebGLRenderingContextBase::isProgram(WebGLProgram* program)
+{
+ if (!program || isContextLostOrPending())
+ return 0;
+
+ return m_context->isProgram(program->object());
+}
+
+GC3Dboolean WebGLRenderingContextBase::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer || isContextLostOrPending())
+ return 0;
+
+ if (!renderbuffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isRenderbuffer(renderbuffer->object());
+}
+
+GC3Dboolean WebGLRenderingContextBase::isShader(WebGLShader* shader)
+{
+ if (!shader || isContextLostOrPending())
+ return 0;
+
+ return m_context->isShader(shader->object());
+}
+
+GC3Dboolean WebGLRenderingContextBase::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLostOrPending())
+ return 0;
+
+ if (!texture->hasEverBeenBound())
+ return 0;
+
+ return m_context->isTexture(texture->object());
+}
+
+void WebGLRenderingContextBase::lineWidth(GC3Dfloat width)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->lineWidth(width);
+}
+
+void WebGLRenderingContextBase::linkProgram(WebGLProgram* program)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("linkProgram", program))
+ return;
+ WebGLShader* vertexShader = program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER);
+ WebGLShader* fragmentShader = program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER);
+ if (!vertexShader || !vertexShader->isValid() || !fragmentShader || !fragmentShader->isValid() || !m_context->precisionsMatch(objectOrZero(vertexShader), objectOrZero(fragmentShader)) || !m_context->checkVaryingsPacking(objectOrZero(vertexShader), objectOrZero(fragmentShader))) {
+ program->setLinkStatus(false);
+ return;
+ }
+
+ m_context->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+}
+
+void WebGLRenderingContextBase::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+ if (isContextLostOrPending())
+ return;
+ switch (pname) {
+ case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
+ m_unpackFlipY = param;
+ break;
+ case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ m_unpackPremultiplyAlpha = param;
+ break;
+ case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE)
+ m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
+ else {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
+ return;
+ }
+ break;
+ case GraphicsContext3D::PACK_ALIGNMENT:
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ if (param == 1 || param == 2 || param == 4 || param == 8) {
+ if (pname == GraphicsContext3D::PACK_ALIGNMENT)
+ m_packAlignment = param;
+ else // GraphicsContext3D::UNPACK_ALIGNMENT:
+ m_unpackAlignment = param;
+ m_context->pixelStorei(pname, param);
+ } else {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name");
+ return;
+ }
+}
+
+void WebGLRenderingContextBase::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->polygonOffset(factor, units);
+}
+
+enum class InternalFormatTheme {
+ None,
+ NormalizedFixedPoint,
+ Packed,
+ SignedNormalizedFixedPoint,
+ FloatingPoint,
+ SignedInteger,
+ UnsignedInteger
+};
+
+static InternalFormatTheme internalFormatTheme(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::SRGB_ALPHA:
+ return InternalFormatTheme::NormalizedFixedPoint;
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB10_A2UI:
+ return InternalFormatTheme::Packed;
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::RGBA8_SNORM:
+ return InternalFormatTheme::SignedNormalizedFixedPoint;
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ return InternalFormatTheme::FloatingPoint;
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA32I:
+ return InternalFormatTheme::SignedInteger;
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA32UI:
+ return InternalFormatTheme::UnsignedInteger;
+ default:
+ return InternalFormatTheme::None;
+ }
+}
+
+static int numberOfComponentsForFormat(GC3Denum format)
+{
+ switch (format) {
+ case GraphicsContext3D::RED:
+ case GraphicsContext3D::RED_INTEGER:
+ return 1;
+ case GraphicsContext3D::RG:
+ case GraphicsContext3D::RG_INTEGER:
+ return 2;
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGB_INTEGER:
+ return 3;
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::RGBA_INTEGER:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+static int numberOfComponentsForInternalFormat(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ return 1;
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ return 2;
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB32I:
+ return 3;
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::SRGB_ALPHA:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::RGBA32I:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+void WebGLRenderingContextBase::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView& pixels)
+{
+ if (isContextLostOrPending())
+ return;
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas().originClean());
+
+ GC3Denum internalFormat = 0;
+ if (m_framebufferBinding) {
+ const char* reason = "framebuffer incomplete";
+ if (!m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
+ return;
+ }
+ // FIXME: readBuffer() should affect this
+ internalFormat = m_framebufferBinding->getColorBufferFormat();
+ } else {
+ if (m_attributes.alpha)
+ internalFormat = GraphicsContext3D::RGB8;
+ else
+ internalFormat = GraphicsContext3D::RGBA8;
+ }
+
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Incorrect internal format");
+ return;
+ }
+
+ if (isWebGL1()) {
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format");
+ return;
+ }
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type");
+ return;
+ }
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
+ return;
+ }
+ }
+
+ InternalFormatTheme internalFormatTheme = WebCore::internalFormatTheme(internalFormat);
+ int internalFormatComponentCount = numberOfComponentsForInternalFormat(internalFormat);
+ if (internalFormatTheme == InternalFormatTheme::None || !internalFormatComponentCount) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Incorrect internal format");
+ return;
+ }
+
+#define INTERNAL_FORMAT_CHECK(themeMacro, typeMacro, pixelTypeMacro) case InternalFormatTheme::themeMacro: \
+ if (type != GraphicsContext3D::typeMacro || pixels.getType() != JSC::pixelTypeMacro) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "type does not match internal format"); \
+ return; \
+ } \
+ if (format != GraphicsContext3D::RED && format != GraphicsContext3D::RG && format != GraphicsContext3D::RGB && format != GraphicsContext3D::RGBA) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Unknown format"); \
+ return; \
+ } \
+ if (numberOfComponentsForFormat(format) < internalFormatComponentCount) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Not enough components in format"); \
+ return; \
+ } \
+ break;
+
+#define INTERNAL_FORMAT_INTEGER_CHECK(themeMacro, typeMacro, pixelTypeMacro) case InternalFormatTheme::themeMacro: \
+ if (type != GraphicsContext3D::typeMacro || pixels.getType() != JSC::pixelTypeMacro) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "type does not match internal format"); \
+ return; \
+ } \
+ if (format != GraphicsContext3D::RED_INTEGER && format != GraphicsContext3D::RG_INTEGER && format != GraphicsContext3D::RGB_INTEGER && format != GraphicsContext3D::RGBA_INTEGER) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Unknown format"); \
+ return; \
+ } \
+ if (numberOfComponentsForFormat(format) < internalFormatComponentCount) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Not enough components in format"); \
+ return; \
+ } \
+ break;
+
+#define PACKED_INTERNAL_FORMAT_CHECK(internalFormatMacro, formatMacro, type0Macro, pixelType0Macro, type1Macro, pixelType1Macro) case GraphicsContext3D::internalFormatMacro: \
+ if (!(type == GraphicsContext3D::type0Macro && pixels.getType() == JSC::pixelType0Macro) \
+ && !(type == GraphicsContext3D::type1Macro && pixels.getType() == JSC::pixelType1Macro)) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "type does not match internal format"); \
+ return; \
+ } \
+ if (format != GraphicsContext3D::formatMacro) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "Invalid format"); \
+ return; \
+ } \
+ break;
+
+ switch (internalFormatTheme) {
+ INTERNAL_FORMAT_CHECK (NormalizedFixedPoint , UNSIGNED_BYTE, TypeUint8 );
+ INTERNAL_FORMAT_CHECK (SignedNormalizedFixedPoint, BYTE , TypeInt8 );
+ INTERNAL_FORMAT_CHECK (FloatingPoint , FLOAT , TypeFloat32);
+ INTERNAL_FORMAT_INTEGER_CHECK(SignedInteger , INT , TypeInt32 );
+ INTERNAL_FORMAT_INTEGER_CHECK(UnsignedInteger , UNSIGNED_INT , TypeUint32 );
+ case InternalFormatTheme::Packed:
+ switch (internalFormat) {
+ PACKED_INTERNAL_FORMAT_CHECK(RGB565 , RGB , UNSIGNED_SHORT_5_6_5 , TypeUint16, UNSIGNED_BYTE , TypeUint8 );
+ PACKED_INTERNAL_FORMAT_CHECK(RGB5_A1 , RGBA , UNSIGNED_SHORT_5_5_5_1 , TypeUint16, UNSIGNED_BYTE , TypeUint8 );
+ PACKED_INTERNAL_FORMAT_CHECK(RGBA4 , RGBA , UNSIGNED_SHORT_4_4_4_4 , TypeUint16, UNSIGNED_BYTE , TypeUint8 );
+ PACKED_INTERNAL_FORMAT_CHECK(RGB9_E5 , RGB , UNSIGNED_INT_5_9_9_9_REV , TypeUint32, UNSIGNED_INT_5_9_9_9_REV , TypeUint32 );
+ PACKED_INTERNAL_FORMAT_CHECK(RGB10_A2 , RGBA , UNSIGNED_INT_2_10_10_10_REV , TypeUint32, UNSIGNED_INT_2_10_10_10_REV, TypeUint32 );
+ PACKED_INTERNAL_FORMAT_CHECK(R11F_G11F_B10F, RGB , UNSIGNED_INT_10F_11F_11F_REV, TypeUint32, FLOAT , TypeFloat32);
+ PACKED_INTERNAL_FORMAT_CHECK(RGB10_A2UI , RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV , TypeUint32, UNSIGNED_INT_2_10_10_10_REV, TypeUint32 );
+ }
+ break;
+ case InternalFormatTheme::None:
+ ASSERT_NOT_REACHED();
+ }
+#undef INTERNAL_FORMAT_CHECK
+#undef INTERNAL_FORMAT_INTEGER_CHECK
+#undef PACKED_INTERNAL_FORMAT_CHECK
+
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned totalBytesRequired = 0;
+ unsigned padding = 0;
+ if (!m_isRobustnessEXTSupported) {
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "readPixels", "invalid dimensions");
+ return;
+ }
+ if (pixels.byteLength() < totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
+ return;
+ }
+ }
+
+ clearIfComposited();
+ void* data = pixels.baseAddress();
+
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions().readnPixelsEXT(x, y, width, height, format, type, pixels.byteLength(), data);
+ else
+ m_context->readPixels(x, y, width, height, format, type, data);
+}
+
+void WebGLRenderingContextBase::releaseShaderCompiler()
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->releaseShaderCompiler();
+}
+
+void WebGLRenderingContextBase::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->sampleCoverage(value, invert);
+}
+
+void WebGLRenderingContextBase::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateSize("scissor", width, height))
+ return;
+ m_context->scissor(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, const String& string)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("shaderSource", shader))
+ return;
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString("shaderSource", stringWithoutComments))
+ return;
+ shader->setSource(string);
+ m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
+}
+
+void WebGLRenderingContextBase::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateStencilFunc("stencilFunc", func))
+ return;
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ m_context->stencilFunc(func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateStencilFunc("stencilFuncSeparate", func))
+ return;
+ switch (face) {
+ case GraphicsContext3D::FRONT_AND_BACK:
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ break;
+ case GraphicsContext3D::FRONT:
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
+ break;
+ case GraphicsContext3D::BACK:
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face");
+ return;
+ }
+ m_context->stencilFuncSeparate(face, func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilMask(GC3Duint mask)
+{
+ if (isContextLostOrPending())
+ return;
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ m_context->stencilMask(mask);
+}
+
+void WebGLRenderingContextBase::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
+{
+ if (isContextLostOrPending())
+ return;
+ switch (face) {
+ case GraphicsContext3D::FRONT_AND_BACK:
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ break;
+ case GraphicsContext3D::FRONT:
+ m_stencilMask = mask;
+ break;
+ case GraphicsContext3D::BACK:
+ m_stencilMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face");
+ return;
+ }
+ m_context->stencilMaskSeparate(face, mask);
+}
+
+void WebGLRenderingContextBase::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->stencilOp(fail, zfail, zpass);
+}
+
+void WebGLRenderingContextBase::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+ if (isContextLostOrPending())
+ return;
+ m_context->stencilOpSeparate(face, fail, zfail, zpass);
+}
+
+void WebGLRenderingContextBase::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
+{
+ // FIXME: For now we ignore any errors returned.
+ WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
+ ASSERT(validateTexFuncParameters("texImage2D", TexImage, target, level, internalFormat, width, height, border, format, type));
+ ASSERT(tex);
+ ASSERT(validateNPOTTextureLevel(width, height, level, "texImage2D"));
+ if (!pixels) {
+ if (!m_context->texImage2DResourceSafe(target, level, internalFormat, width, height, border, format, type, m_unpackAlignment))
+ return;
+ } else {
+ ASSERT(validateSettableTexInternalFormat("texImage2D", internalFormat));
+ m_context->moveErrorsToSyntheticErrorList();
+ m_context->texImage2D(target, level, internalFormat, width, height,
+ border, format, type, pixels);
+ if (m_context->moveErrorsToSyntheticErrorList()) {
+ // The texImage2D function failed. Tell the WebGLTexture it doesn't have the data for this level.
+ tex->markInvalid(target, level);
+ return;
+ }
+ }
+ tex->setLevelInfo(target, level, internalFormat, width, height, type);
+}
+
+void WebGLRenderingContextBase::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
+{
+ Vector<uint8_t> data;
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "packImage error");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
+{
+ if (!validateTexFuncParameters(functionName, functionType, target, level, internalFormat, width, height, border, format, type))
+ return false;
+
+ WebGLTexture* texture = validateTextureBinding(functionName, target, true);
+ if (!texture)
+ return false;
+
+ if (functionType != TexSubImage) {
+ if (functionType == TexImage && texture->immutable()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "texStorage() called on this texture previously");
+ return false;
+ }
+ if (!validateNPOTTextureLevel(width, height, level, functionName))
+ return false;
+ // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
+ // by checking if the ArrayBufferView is null or not.
+ if (sourceType != SourceArrayBufferView) {
+ if (!validateSettableTexInternalFormat(functionName, internalFormat))
+ return false;
+ }
+ } else {
+ if (!validateSettableTexInternalFormat(functionName, internalFormat))
+ return false;
+ if (!validateSize(functionName, xoffset, yoffset))
+ return false;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "bad dimensions");
+ return false;
+ }
+ if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
+ return false;
+ }
+ if (texture->getInternalFormat(target, level) != internalFormat || (isWebGL1() && texture->getType(target, level) != type)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels)
+{
+ if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, internalFormat, format, type, pixels.get(), NullAllowed)
+ || !validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalFormat, width, height, border, format, type, 0, 0))
+ return;
+ void* data = pixels ? pixels->baseAddress() : 0;
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!m_context->extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalFormat, width, height, border, format, type, data);
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
+{
+ Vector<uint8_t> data;
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
+ return;
+ }
+ GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, format, type, needConversion ? data.data() : imagePixelData);
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels)
+{
+ if (isContextLostOrPending())
+ return;
+
+ WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return;
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return;
+ }
+
+ if (!validateTexFuncData("texSubImage2D", level, width, height, internalFormat, format, type, pixels.get(), NullNotAllowed))
+ return;
+
+ if (!validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, internalFormat, width, height, 0, format, type, xoffset, yoffset))
+ return;
+
+ void* data = pixels->baseAddress();
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!m_context->extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalFormat, format, type, data);
+
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+ExceptionOr<void> WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, std::optional<TexImageSource>&& source)
+{
+ if (!source) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "source is null");
+ return { };
+ }
+
+ if (isContextLostOrPending())
+ return { };
+
+ auto visitor = WTF::makeVisitor([&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
+ WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return { };
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return { };
+ }
+
+ if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, internalFormat, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ return { };
+
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+ needConversion = false;
+ else {
+ if (!m_context->extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
+ return { };
+ }
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, format, type, needConversion ? data.data() : pixels->data()->data());
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+
+ return { };
+ } , [&](const RefPtr<HTMLImageElement>& image) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image.get(), ec))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (!imageForRender)
+ return { };
+
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(*imageForRender, image->width(), image->height(), 1);
+
+ WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return { };
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return { };
+ }
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, internalFormat, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ return { };
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<HTMLCanvasElement>& canvas) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas.get(), ec))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return { };
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return { };
+ }
+
+ if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, internalFormat, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ return { };
+
+ RefPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texSubImage2D(target, level, xoffset, yoffset, format, type, TexImageSource(imageData.get()));
+ else
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<HTMLVideoElement>& video) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video.get(), ec))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return { };
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return { };
+ }
+
+ if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, internalFormat, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ return { };
+
+ RefPtr<Image> image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return { };
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ });
+
+ return WTF::visit(visitor, source.value());
+}
+
+bool WebGLRenderingContextBase::validateArrayBufferType(const char* functionName, GC3Denum type, std::optional<JSC::TypedArrayType> arrayType)
+{
+#define TYPE_VALIDATION_CASE(arrayTypeMacro) if (arrayType && arrayType.value() != JSC::arrayTypeMacro) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not " #arrayTypeMacro); \
+ return false; \
+ } \
+ break;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ TYPE_VALIDATION_CASE(TypeUint8);
+ case GraphicsContext3D::BYTE:
+ TYPE_VALIDATION_CASE(TypeInt8);
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ TYPE_VALIDATION_CASE(TypeUint16);
+ case GraphicsContext3D::SHORT:
+ TYPE_VALIDATION_CASE(TypeInt16);
+ case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+ case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+ case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+ case GraphicsContext3D::UNSIGNED_INT_24_8:
+ case GraphicsContext3D::UNSIGNED_INT:
+ TYPE_VALIDATION_CASE(TypeUint32);
+ case GraphicsContext3D::INT:
+ TYPE_VALIDATION_CASE(TypeInt32);
+ case GraphicsContext3D::FLOAT: // OES_texture_float
+ TYPE_VALIDATION_CASE(TypeFloat32);
+ case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
+ case GraphicsContext3D::HALF_FLOAT:
+ case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+ // As per the specification, ArrayBufferView should be null when
+ // OES_texture_half_float is enabled.
+ if (arrayType) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+#undef TYPE_VALIDATION_CASE
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalFormat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+ if (!pixels) {
+ if (disposition == NullAllowed)
+ return true;
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+
+ if (!validateTexFuncFormatAndType(functionName, internalFormat, format, type, level))
+ return false;
+ if (!validateSettableTexInternalFormat(functionName, internalFormat))
+ return false;
+ if (!validateArrayBufferType(functionName, type, pixels ? std::optional<JSC::TypedArrayType>(pixels->getType()) : std::nullopt))
+ return false;
+
+ unsigned totalBytesRequired;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, nullptr);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType functionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type)
+{
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage && width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalFormat, GC3Denum format, GC3Denum type, GC3Dint level)
+{
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ if (!m_webglDepthTexture && isWebGL1()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for depth formats");
+ return false;
+ }
+ break;
+ case Extensions3D::SRGB_EXT:
+ case Extensions3D::SRGB_ALPHA_EXT:
+ if (!m_extsRGB) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "sRGB texture formats not enabled");
+ return false;
+ }
+ break;
+ default:
+#if ENABLE(WEBGL2)
+ if (!isWebGL1()) {
+ switch (format) {
+ case GraphicsContext3D::RED:
+ case GraphicsContext3D::RED_INTEGER:
+ case GraphicsContext3D::RG:
+ case GraphicsContext3D::RG_INTEGER:
+ case GraphicsContext3D::RGB_INTEGER:
+ case GraphicsContext3D::RGBA_INTEGER:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+ } else
+#endif
+ {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+ }
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ break;
+ case GraphicsContext3D::FLOAT:
+ if (!m_oesTextureFloat && isWebGL1()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::HALF_FLOAT:
+ case GraphicsContext3D::HALF_FLOAT_OES:
+ if (!m_oesTextureHalfFloat && isWebGL1()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::UNSIGNED_INT:
+ case GraphicsContext3D::UNSIGNED_INT_24_8:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ if (!m_webglDepthTexture && isWebGL1()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+ break;
+ default:
+#if ENABLE(WEBGL2)
+ if (!isWebGL1()) {
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ case GraphicsContext3D::SHORT:
+ case GraphicsContext3D::INT:
+ case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+ case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+ case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+ case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+ } else
+#endif
+ {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+ }
+
+ // Verify that the combination of internalformat, format, and type is supported.
+#define INTERNAL_FORMAT_CASE(internalFormatMacro, formatMacro, type0, type1, type2, type3, type4) case GraphicsContext3D::internalFormatMacro: \
+ if (format != GraphicsContext3D::formatMacro) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format for internalformat"); \
+ return false; \
+ } \
+ if (type != type0 && type != type1 && type != type2 && type != type3 && type != type4) { \
+ if (type != GraphicsContext3D::HALF_FLOAT_OES || (type0 != GraphicsContext3D::HALF_FLOAT && type1 != GraphicsContext3D::HALF_FLOAT && type2 != GraphicsContext3D::HALF_FLOAT && type3 != GraphicsContext3D::HALF_FLOAT)) { \
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for internalformat"); \
+ return false; \
+ } \
+ } \
+ break;
+ switch (internalFormat) {
+ INTERNAL_FORMAT_CASE(RGB , RGB , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::UNSIGNED_SHORT_5_6_5 , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 );
+ INTERNAL_FORMAT_CASE(RGBA , RGBA , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4, GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 , GraphicsContext3D::HALF_FLOAT, GraphicsContext3D::FLOAT);
+ INTERNAL_FORMAT_CASE(LUMINANCE_ALPHA , LUMINANCE_ALPHA, GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 );
+ INTERNAL_FORMAT_CASE(LUMINANCE , LUMINANCE , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 );
+ INTERNAL_FORMAT_CASE(ALPHA , ALPHA , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R8 , RED , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R8_SNORM , RED , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R16F , RED , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R32F , RED , GraphicsContext3D::FLOAT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R8UI , RED_INTEGER , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R8I , RED_INTEGER , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R16UI , RED_INTEGER , GraphicsContext3D::UNSIGNED_SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R16I , RED_INTEGER , GraphicsContext3D::SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R32UI , RED_INTEGER , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R32I , RED_INTEGER , GraphicsContext3D::INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG8 , RG , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG8_SNORM , RG , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG16F , RG , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG32F , RG , GraphicsContext3D::FLOAT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG8UI , RG_INTEGER , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG8I , RG_INTEGER , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG16UI , RG_INTEGER , GraphicsContext3D::UNSIGNED_SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG16I , RG_INTEGER , GraphicsContext3D::SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG32UI , RG_INTEGER , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RG32I , RG_INTEGER , GraphicsContext3D::INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB8 , RGB , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(SRGB8 , RGB , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB565 , RGB , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::UNSIGNED_SHORT_5_6_5 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB8_SNORM , RGB , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(R11F_G11F_B10F , RGB , GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB9_E5 , RGB , GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB16F , RGB , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB32F , RGB , GraphicsContext3D::FLOAT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB8UI , RGB_INTEGER , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB8I , RGB_INTEGER , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB16UI , RGB_INTEGER , GraphicsContext3D::UNSIGNED_SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB16I , RGB_INTEGER , GraphicsContext3D::SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB32UI , RGB_INTEGER , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB32I , RGB_INTEGER , GraphicsContext3D::INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA8 , RGBA , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(SRGB8_ALPHA8 , RGBA , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA8_SNORM , RGBA , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB5_A1 , RGBA , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1, GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA4 , RGBA , GraphicsContext3D::UNSIGNED_BYTE , GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4, 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB10_A2 , RGBA , GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA16F , RGBA , GraphicsContext3D::HALF_FLOAT , GraphicsContext3D::FLOAT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA32F , RGBA , GraphicsContext3D::FLOAT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA8UI , RGBA_INTEGER , GraphicsContext3D::UNSIGNED_BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA8I , RGBA_INTEGER , GraphicsContext3D::BYTE , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGB10_A2UI , RGBA_INTEGER , GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA16UI , RGBA_INTEGER , GraphicsContext3D::UNSIGNED_SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA16I , RGBA_INTEGER , GraphicsContext3D::SHORT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA32I , RGBA_INTEGER , GraphicsContext3D::INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(RGBA32UI , RGBA_INTEGER , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH_COMPONENT , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_SHORT , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH_COMPONENT16 , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_SHORT , GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH_COMPONENT24 , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_INT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH_COMPONENT32F, DEPTH_COMPONENT, GraphicsContext3D::FLOAT , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH_STENCIL , DEPTH_STENCIL , GraphicsContext3D::UNSIGNED_INT_24_8 , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH24_STENCIL8 , DEPTH_STENCIL , GraphicsContext3D::UNSIGNED_INT_24_8 , 0 , 0 , 0 , 0 );
+ INTERNAL_FORMAT_CASE(DEPTH32F_STENCIL8 , DEPTH_STENCIL , GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV, 0 , 0 , 0 , 0 );
+ case Extensions3D::SRGB_EXT:
+ if (format != internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format and internalformat must match");
+ return false;
+ }
+ if (type != GraphicsContext3D::UNSIGNED_BYTE && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5 && type != GraphicsContext3D::FLOAT && type != GraphicsContext3D::HALF_FLOAT_OES && type != GraphicsContext3D::HALF_FLOAT) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for internal format");
+ return false;
+ }
+ break;
+ case Extensions3D::SRGB_ALPHA_EXT:
+ if (format != internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format and internalformat must match");
+ return false;
+ }
+ if (type != GraphicsContext3D::UNSIGNED_BYTE && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 && type != GraphicsContext3D::FLOAT && type != GraphicsContext3D::HALF_FLOAT_OES && type != GraphicsContext3D::HALF_FLOAT) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for internal format");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "Unknown internal format");
+ return false;
+ }
+#undef INTERNAL_FORMAT_CASE
+
+ return true;
+}
+
+void WebGLRenderingContextBase::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalFormat, GC3Denum format, GC3Denum type, const void* pixels)
+{
+ ASSERT(!isContextLost());
+ ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, internalFormat, width, height, 0, format, type));
+ ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+ ASSERT(validateSettableTexInternalFormat("texSubImage2D", internalFormat));
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ if (!tex) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT((xoffset + width) >= 0);
+ ASSERT((yoffset + height) >= 0);
+ ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+ ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+ ASSERT_UNUSED(internalFormat, tex->getInternalFormat(target, level) == internalFormat);
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContextBase::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalFormat, width, height, border, internalFormat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexInternalFormat("copyTexImage2D", internalFormat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ m_context->texImage2DResourceSafe(target, level, internalFormat, width, height, border,
+ internalFormat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
+ if (clippedWidth > 0 && clippedHeight > 0) {
+ m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+ clippedX, clippedY, clippedWidth, clippedHeight);
+ }
+ } else
+ m_context->copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
+
+ // FIXME: if the framebuffer is not complete, none of the below should be executed.
+ tex->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+}
+
+static bool isRGBFormat(GC3Denum internalFormat)
+{
+ return internalFormat == GraphicsContext3D::RGB
+ || internalFormat == GraphicsContext3D::RGBA
+ || internalFormat == GraphicsContext3D::RGB8
+ || internalFormat == GraphicsContext3D::RGBA8;
+}
+
+ExceptionOr<void> WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, std::optional<TexImageSource> source)
+{
+ if (!source) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "source is null");
+ return { };
+ }
+
+ auto visitor = WTF::makeVisitor([&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
+ if (isContextLostOrPending() || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
+ return { };
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
+ needConversion = false;
+ else {
+ if (!m_context->extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return { };
+ }
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data());
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+ return { };
+ }, [&](const RefPtr<HTMLImageElement>& image) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLImageElement("texImage2D", image.get(), ec))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (!imageForRender)
+ return { };
+
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(*imageForRender, image->width(), image->height(), 1);
+
+ if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
+ return { };
+
+ texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<HTMLCanvasElement>& canvas) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas.get(), ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ // If possible, copy from the canvas element directly to the texture
+ // via the GPU, without a read-back to system memory.
+ //
+ // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
+ // ImageBuffer::copyToPlatformTexture implementations are fully functional.
+ if (texture
+ && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
+ && type == GraphicsContext3D::UNSIGNED_BYTE) {
+ auto textureInternalFormat = texture->getInternalFormat(target, level);
+ if (isRGBFormat(textureInternalFormat) || !texture->isValid(target, level)) {
+ ImageBuffer* buffer = canvas->buffer();
+ if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return { };
+ }
+ }
+ }
+
+ RefPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texImage2D(target, level, internalformat, format, type, TexImageSource(imageData.get()));
+ else
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<HTMLVideoElement>& video) -> ExceptionOr<void> {
+ ExceptionCode ec = 0;
+ if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video.get(), ec)
+ || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
+ return ec ? Exception { ec } : ExceptionOr<void> { };
+
+ // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+ // Otherwise, it will fall back to the normal SW path.
+ // FIXME: The current restrictions require that format shoud be RGB or RGBA,
+ // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ if (GraphicsContext3D::TEXTURE_2D == target && texture
+ && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
+ && type == GraphicsContext3D::UNSIGNED_BYTE
+ && !level) {
+ auto textureInternalFormat = texture->getInternalFormat(target, level);
+ if (isRGBFormat(textureInternalFormat) || !texture->isValid(target, level)) {
+ if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), target, level, internalformat, format, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+ return { };
+ }
+ }
+ }
+
+ // Normal pure SW path.
+ RefPtr<Image> image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return { };
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ });
+
+ return WTF::visit(visitor, source.value());
+}
+
+RefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(Image& image, int width, int height, int deviceScaleFactor)
+{
+ IntSize size(width, height);
+ size.scale(deviceScaleFactor);
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return nullptr;
+ }
+
+ FloatRect srcRect(FloatPoint(), image.size());
+ FloatRect destRect(FloatPoint(), size);
+ buf->context().drawImage(image, destRect, srcRect);
+ return buf->copyImage(ImageBuffer::fastCopyImageMode());
+}
+
+#if ENABLE(VIDEO)
+
+RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
+{
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return nullptr;
+ }
+ FloatRect destRect(0, 0, size.width(), size.height());
+ // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+ video->paintCurrentFrameInContext(buf->context(), destRect);
+ return buf->copyImage(backingStoreCopy);
+}
+
+#endif
+
+void WebGLRenderingContextBase::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
+{
+ if (isContextLostOrPending())
+ return;
+ WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
+ if (!tex)
+ return;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT)
+ || (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter");
+ return;
+ }
+ break;
+ case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (!m_extTextureFilterAnisotropic) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name");
+ return;
+ }
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
+ m_context->texParameterf(target, pname, paramf);
+ } else {
+ tex->setParameteri(pname, parami);
+ m_context->texParameteri(target, pname, parami);
+ }
+}
+
+void WebGLRenderingContextBase::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
+{
+ texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContextBase::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
+{
+ texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform1f(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform2f(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform3f(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform4f(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location, GC3Dint x)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program");
+ return;
+ }
+
+ if ((location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE) && x >= (int)m_textureUnits.size()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1i", "invalid texture unit");
+ return;
+ }
+
+ m_context->uniform1i(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform2i(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform3i(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
+{
+ if (isContextLostOrPending() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform4i(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform1fv", location, v, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v.length(), v.data());
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform2fv", location, v, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v.length() / 2, v.data());
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform3fv", location, v, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v.length() / 3, v.data());
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform4fv", location, v, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v.length() / 4, v.data());
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, Int32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform1iv", location, v, 1))
+ return;
+
+ auto data = v.data();
+ auto length = v.length();
+
+ if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE) {
+ for (auto i = 0; i < length; ++i) {
+ if (data[i] >= static_cast<int>(m_textureUnits.size())) {
+ LOG(WebGL, "Texture unit size=%zu, v[%d]=%d. Location type = %04X.", m_textureUnits.size(), i, data[i], location->type());
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
+ return;
+ }
+ }
+ }
+
+ m_context->uniform1iv(location->location(), length, data);
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, Int32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform2iv", location, v, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v.length() / 2, v.data());
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, Int32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform3iv", location, v, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v.length() / 3, v.data());
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, Int32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformParameters("uniform4iv", location, v, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v.length() / 4, v.data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), v.length() / 4, transpose, v.data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), v.length() / 9, transpose, v.data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32List&& v)
+{
+ if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), v.length() / 16, transpose, v.data());
+}
+
+void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("useProgram", program, deleted))
+ return;
+ if (deleted)
+ program = 0;
+ if (program && !program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached(graphicsContext3D());
+ m_currentProgram = program;
+ m_context->useProgram(objectOrZero(program));
+ if (program)
+ program->onAttached();
+ }
+}
+
+void WebGLRenderingContextBase::validateProgram(WebGLProgram* program)
+{
+ if (isContextLostOrPending() || !validateWebGLObject("validateProgram", program))
+ return;
+ m_context->validateProgram(objectOrZero(program));
+}
+
+void WebGLRenderingContextBase::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
+{
+ vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
+{
+ vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
+{
+ vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GC3Duint index, Float32List&& v)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, WTFMove(v), 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GC3Duint index, Float32List&& v)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, WTFMove(v), 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GC3Duint index, Float32List&& v)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, WTFMove(v), 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GC3Duint index, Float32List&& v)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, WTFMove(v), 4);
+}
+
+void WebGLRenderingContextBase::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset)
+{
+ if (isContextLostOrPending())
+ return;
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::SHORT:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ case GraphicsContext3D::FLOAT:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range");
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
+ return;
+ }
+ if (!m_boundArrayBuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
+ return;
+ }
+ // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+ auto typeSize = sizeInBytes(type);
+ if (!typeSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
+ return;
+ }
+ GC3Dsizei bytesPerElement = size * typeSize;
+
+ m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), *m_boundArrayBuffer);
+ m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
+}
+
+void WebGLRenderingContextBase::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateSize("viewport", width, height))
+ return;
+ m_context->viewport(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
+{
+ if (isContextLostOrPending()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost");
+ return;
+ }
+
+ m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContextBase::recycleContext()
+{
+ printWarningToConsole("There are too many active WebGL contexts on this page, the oldest context will be lost.");
+ // Using SyntheticLostContext means the developer won't be able to force the restoration
+ // of the context by calling preventDefault() in a "webglcontextlost" event handler.
+ forceLostContext(SyntheticLostContext);
+ destroyGraphicsContext3D();
+}
+
+void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
+{
+ if (isContextLost())
+ return;
+
+ m_contextLost = true;
+ m_contextLostMode = mode;
+
+ if (mode == RealLostContext) {
+ // Inform the embedder that a lost context was received. In response, the embedder might
+ // decide to take action such as asking the user for permission to use WebGL again.
+ if (Frame* frame = canvas().document().frame())
+ frame->loader().client().didLoseWebGLContext(m_context->getExtensions().getGraphicsResetStatusARB());
+ }
+
+ detachAndRemoveAllObjects();
+
+ // There is no direct way to clear errors from a GL implementation and
+ // looping until getError() becomes NO_ERROR might cause an infinite loop if
+ // the driver or context implementation had a bug. So, loop a reasonably
+ // large number of times to clear any existing errors.
+ for (int i = 0; i < 100; ++i) {
+ if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+ break;
+ }
+ ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
+ synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
+
+ // Don't allow restoration unless the context lost event has both been
+ // dispatched and its default behavior prevented.
+ m_restoreAllowed = false;
+
+ // Always defer the dispatch of the context lost event, to implement
+ // the spec behavior of queueing a task.
+ m_dispatchContextLostEventTimer.startOneShot(0);
+}
+
+void WebGLRenderingContextBase::forceRestoreContext()
+{
+ if (!isContextLostOrPending()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost");
+ return;
+ }
+
+ if (!m_restoreAllowed) {
+ if (m_contextLostMode == SyntheticLostContext)
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+ return;
+ }
+
+ if (!m_restoreTimer.isActive())
+ m_restoreTimer.startOneShot(0);
+}
+
+PlatformLayer* WebGLRenderingContextBase::platformLayer() const
+{
+ return (!isContextLost() && !m_isPendingPolicyResolution) ? m_context->platformLayer() : 0;
+}
+
+void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject& object)
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ m_contextGroup->removeObject(object);
+}
+
+void WebGLRenderingContextBase::addSharedObject(WebGLSharedObject& object)
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ ASSERT(!isContextLost());
+ m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContextBase::removeContextObject(WebGLContextObject& object)
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ m_contextObjects.remove(&object);
+}
+
+void WebGLRenderingContextBase::addContextObject(WebGLContextObject& object)
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ ASSERT(!isContextLost());
+ m_contextObjects.add(&object);
+}
+
+void WebGLRenderingContextBase::detachAndRemoveAllObjects()
+{
+ if (m_isPendingPolicyResolution)
+ return;
+
+ while (m_contextObjects.size() > 0) {
+ HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
+ (*it)->detachContext();
+ }
+}
+
+bool WebGLRenderingContextBase::hasPendingActivity() const
+{
+ return false;
+}
+
+void WebGLRenderingContextBase::stop()
+{
+ if (!isContextLost() && !m_isPendingPolicyResolution) {
+ forceLostContext(SyntheticLostContext);
+ destroyGraphicsContext3D();
+ }
+}
+
+const char* WebGLRenderingContextBase::activeDOMObjectName() const
+{
+ return "WebGLRenderingContext";
+}
+
+bool WebGLRenderingContextBase::canSuspendForDocumentSuspension() const
+{
+ // FIXME: We should try and do better here.
+ return false;
+}
+
+bool WebGLRenderingContextBase::getBooleanParameter(GC3Denum pname)
+{
+ GC3Dboolean value = 0;
+ m_context->getBooleanv(pname, &value);
+ return value;
+}
+
+Vector<bool> WebGLRenderingContextBase::getBooleanArrayParameter(GC3Denum pname)
+{
+ if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
+ notImplemented();
+ return { };
+ }
+ GC3Dboolean value[4] = { 0 };
+ m_context->getBooleanv(pname, value);
+ Vector<bool> vector(4);
+ for (unsigned i = 0; i < 4; ++i)
+ vector[i] = value[i];
+ return vector;
+}
+
+float WebGLRenderingContextBase::getFloatParameter(GC3Denum pname)
+{
+ GC3Dfloat value = 0;
+ m_context->getFloatv(pname, &value);
+ return value;
+}
+
+int WebGLRenderingContextBase::getIntParameter(GC3Denum pname)
+{
+ GC3Dint value = 0;
+ m_context->getIntegerv(pname, &value);
+ return value;
+}
+
+unsigned WebGLRenderingContextBase::getUnsignedIntParameter(GC3Denum pname)
+{
+ GC3Dint value = 0;
+ m_context->getIntegerv(pname, &value);
+ return value;
+}
+
+long long WebGLRenderingContextBase::getInt64Parameter(GC3Denum pname)
+{
+ GC3Dint64 value = 0;
+ m_context->getInteger64v(pname, &value);
+ return value;
+}
+
+RefPtr<Float32Array> WebGLRenderingContextBase::getWebGLFloatArrayParameter(GC3Denum pname)
+{
+ GC3Dfloat value[4] = {0};
+ m_context->getFloatv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
+ case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
+ case GraphicsContext3D::DEPTH_RANGE:
+ length = 2;
+ break;
+ case GraphicsContext3D::BLEND_COLOR:
+ case GraphicsContext3D::COLOR_CLEAR_VALUE:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return Float32Array::create(value, length);
+}
+
+RefPtr<Int32Array> WebGLRenderingContextBase::getWebGLIntArrayParameter(GC3Denum pname)
+{
+ GC3Dint value[4] = {0};
+ m_context->getIntegerv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GraphicsContext3D::MAX_VIEWPORT_DIMS:
+ length = 2;
+ break;
+ case GraphicsContext3D::SCISSOR_BOX:
+ case GraphicsContext3D::VIEWPORT:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return Int32Array::create(value, length);
+}
+
+bool WebGLRenderingContextBase::checkTextureCompleteness(const char* functionName, bool prepareToDraw)
+{
+ bool resetActiveUnit = false;
+ bool usesAtLeastOneBlackTexture = false;
+ WebGLTexture::TextureExtensionFlag extensions = textureExtensionFlags();
+
+ Vector<unsigned> noLongerUnrenderable;
+ for (unsigned badTexture : m_unrenderableTextureUnits) {
+ ASSERT(badTexture < m_textureUnits.size());
+ auto& textureUnit = m_textureUnits[badTexture];
+ bool needsToUseBlack2DTexture = textureUnit.texture2DBinding && textureUnit.texture2DBinding->needToUseBlackTexture(extensions);
+ bool needsToUseBlack3DTexture = textureUnit.textureCubeMapBinding && textureUnit.textureCubeMapBinding->needToUseBlackTexture(extensions);
+
+ if (!needsToUseBlack2DTexture && !needsToUseBlack3DTexture) {
+ noLongerUnrenderable.append(badTexture);
+ continue;
+ }
+
+ usesAtLeastOneBlackTexture = true;
+
+ if (badTexture != m_activeTextureUnit) {
+ m_context->activeTexture(badTexture + GraphicsContext3D::TEXTURE0);
+ resetActiveUnit = true;
+ } else if (resetActiveUnit) {
+ m_context->activeTexture(badTexture + GraphicsContext3D::TEXTURE0);
+ resetActiveUnit = false;
+ }
+ WebGLTexture* tex2D;
+ WebGLTexture* texCubeMap;
+ if (prepareToDraw) {
+ String msg(String("texture bound to texture unit ") + String::number(badTexture)
+ + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
+ + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
+ printGLWarningToConsole(functionName, msg.utf8().data());
+ tex2D = m_blackTexture2D.get();
+ texCubeMap = m_blackTextureCubeMap.get();
+ } else {
+ tex2D = textureUnit.texture2DBinding.get();
+ texCubeMap = textureUnit.textureCubeMapBinding.get();
+ }
+ if (needsToUseBlack2DTexture)
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
+ if (needsToUseBlack3DTexture)
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+ }
+ if (resetActiveUnit)
+ m_context->activeTexture(m_activeTextureUnit + GraphicsContext3D::TEXTURE0);
+
+ for (unsigned renderable : noLongerUnrenderable)
+ m_unrenderableTextureUnits.remove(renderable);
+
+ return usesAtLeastOneBlackTexture;
+}
+
+void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
+{
+ unsigned char black[] = {0, 0, 0, 255};
+ m_blackTexture2D = createTexture();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D->object());
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+ m_blackTextureCubeMap = createTexture();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
+}
+
+bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
+ GC3Denum colorBufferFormat)
+{
+ unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
+ unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
+ return (need & have) == need;
+}
+
+GC3Denum WebGLRenderingContextBase::getBoundFramebufferColorFormat()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferFormat();
+ if (m_attributes.alpha)
+ return GraphicsContext3D::RGBA;
+ return GraphicsContext3D::RGB;
+}
+
+int WebGLRenderingContextBase::getBoundFramebufferWidth()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferWidth();
+ return m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContextBase::getBoundFramebufferHeight()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferHeight();
+ return m_context->getInternalFramebufferSize().height();
+}
+
+WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* texture = nullptr;
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (!useSixEnumsForCubeMap) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
+ }
+ texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
+ }
+ texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
+ }
+
+ if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+ m_unrenderableTextureUnits.add(m_activeTextureUnit);
+
+ if (!texture)
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
+ return texture;
+}
+
+bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
+{
+ if (x < 0 || y < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateString(const char* functionName, const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
+{
+ if (level < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0");
+ return false;
+ }
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (level >= m_maxTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (level >= m_maxCubeMapTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ }
+ // This function only checks if level is legal, so we return true and don't
+ // generate INVALID_ENUM if target is illegal.
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFormat(GC3Denum format)
+{
+ return m_compressedTextureFormats.contains(format);
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& pixels)
+{
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ unsigned bytesRequired = 0;
+
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_ATC_RGB_AMD:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ {
+ const int kBlockSize = 16;
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 8;
+ const int kBlockHeight = 8;
+ bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 4 + 7) / kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 16;
+ const int kBlockHeight = 8;
+ bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 2 + 7) / kBlockSize;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format");
+ return false;
+ }
+
+ if (pixels.byteLength() != bytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
+{
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const GC3Dsizei kBlockWidth = 4;
+ const GC3Dsizei kBlockHeight = 4;
+ const GC3Dint maxTextureSize = target ? m_maxTextureSize : m_maxCubeMapTextureSize;
+ const GC3Dsizei maxCompressedDimension = maxTextureSize >> level;
+ bool widthValid = (level && width == 1) || (level && width == 2) || (!(width % kBlockWidth) && width <= maxCompressedDimension);
+ bool heightValid = (level && height == 1) || (level && height == 2) || (!(height % kBlockHeight) && height <= maxCompressedDimension);
+ if (!widthValid || !heightValid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
+ return false;
+ }
+ return true;
+ }
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ // Height and width must be powers of 2.
+ if ((width & (width - 1)) || (height & (height - 1))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
+ return false;
+ }
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
+{
+ if (xoffset < 0 || yoffset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "xoffset or yoffset < 0");
+ return false;
+ }
+
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
+ return false;
+ }
+ if (width - xoffset > tex->getWidth(target, level)
+ || height - yoffset > tex->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions out of range");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, target, level, width, height, format);
+ }
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
+ if (xoffset || yoffset) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset and yoffset must be zero");
+ return false;
+ }
+ if (width != tex->getWidth(target, level)
+ || height != tex->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions must match existing level");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, target, level, width, height, format);
+ }
+ default:
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateDrawMode(const char* functionName, GC3Denum mode)
+{
+ switch (mode) {
+ case GraphicsContext3D::POINTS:
+ case GraphicsContext3D::LINE_STRIP:
+ case GraphicsContext3D::LINE_LOOP:
+ case GraphicsContext3D::LINES:
+ case GraphicsContext3D::TRIANGLE_STRIP:
+ case GraphicsContext3D::TRIANGLE_FAN:
+ case GraphicsContext3D::TRIANGLES:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateStencilSettings(const char* functionName)
+{
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateStencilFunc(const char* functionName, GC3Denum func)
+{
+ switch (func) {
+ case GraphicsContext3D::NEVER:
+ case GraphicsContext3D::LESS:
+ case GraphicsContext3D::LEQUAL:
+ case GraphicsContext3D::GREATER:
+ case GraphicsContext3D::GEQUAL:
+ case GraphicsContext3D::EQUAL:
+ case GraphicsContext3D::NOTEQUAL:
+ case GraphicsContext3D::ALWAYS:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function");
+ return false;
+ }
+}
+
+void WebGLRenderingContextBase::printGLErrorToConsole(const String& message)
+{
+ if (!m_numGLErrorsToConsoleAllowed)
+ return;
+
+ --m_numGLErrorsToConsoleAllowed;
+ printWarningToConsole(message);
+
+ if (!m_numGLErrorsToConsoleAllowed)
+ printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
+}
+
+void WebGLRenderingContextBase::printWarningToConsole(const String& message)
+{
+ canvas().document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Warning, message);
+}
+
+bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
+{
+ if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
+ || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, const Float32List& v, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v.data(), v.length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, const Int32List& v, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v.data(), v.length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, const Float32List& v, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, transpose, v.data(), v.length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
+ return false;
+ }
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ if (transpose) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE");
+ return false;
+ }
+ if (size < requiredMinSize || (size % requiredMinSize)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContextBase::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
+{
+ std::optional<WebGLBuffer*> buffer;
+ switch (target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundVertexArrayObject->getElementArrayBuffer();
+ break;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+#if ENABLE(WEBGL2)
+ if (isWebGL2()) {
+ switch (target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ buffer = m_boundCopyReadBuffer.get();
+ break;
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ buffer = m_boundCopyWriteBuffer.get();
+ break;
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ buffer = m_boundPixelPackBuffer.get();
+ break;
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ buffer = m_boundPixelUnpackBuffer.get();
+ break;
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ buffer = m_boundTransformFeedbackBuffer.get();
+ break;
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ buffer = m_boundUniformBuffer.get();
+ break;
+ }
+ if (buffer)
+ break;
+ }
+#endif
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return nullptr;
+ }
+ if (!buffer || !buffer.value()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
+ return nullptr;
+ }
+ switch (usage) {
+ case GraphicsContext3D::STREAM_DRAW:
+ case GraphicsContext3D::STATIC_DRAW:
+ case GraphicsContext3D::DYNAMIC_DRAW:
+ return buffer.value();
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage");
+ return nullptr;
+}
+
+bool WebGLRenderingContextBase::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionCode& ec)
+{
+ if (!image || !image->cachedImage()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image");
+ return false;
+ }
+ const URL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image");
+ return false;
+ }
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ if (!canvas || !canvas->buffer()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no canvas");
+ return false;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+#if ENABLE(VIDEO)
+
+bool WebGLRenderingContextBase::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no video");
+ return false;
+ }
+ if (wouldTaintOrigin(video)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+void WebGLRenderingContextBase::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ if (isContextLostOrPending())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ if (index || isGLES2Compliant()) {
+ switch (expectedSize) {
+ case 1:
+ m_context->vertexAttrib1f(index, v0);
+ break;
+ case 2:
+ m_context->vertexAttrib2f(index, v0, v1);
+ break;
+ case 3:
+ m_context->vertexAttrib3f(index, v0, v1, v2);
+ break;
+ case 4:
+ m_context->vertexAttrib4f(index, v0, v1, v2, v3);
+ break;
+ }
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.value[0] = v0;
+ attribValue.value[1] = v1;
+ attribValue.value[2] = v2;
+ attribValue.value[3] = v3;
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32List&& list, GC3Dsizei expectedSize)
+{
+ if (isContextLostOrPending())
+ return;
+
+ auto data = list.data();
+ if (!data) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return;
+ }
+
+ int size = list.length();
+ if (size < expectedSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ if (index || isGLES2Compliant()) {
+ switch (expectedSize) {
+ case 1:
+ m_context->vertexAttrib1fv(index, data);
+ break;
+ case 2:
+ m_context->vertexAttrib2fv(index, data);
+ break;
+ case 3:
+ m_context->vertexAttrib3fv(index, data);
+ break;
+ case 4:
+ m_context->vertexAttrib4fv(index, data);
+ break;
+ }
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.initValue();
+ for (int ii = 0; ii < expectedSize; ++ii)
+ attribValue.value[ii] = data[ii];
+}
+
+void WebGLRenderingContextBase::initVertexAttrib0()
+{
+ WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+
+ m_vertexAttrib0Buffer = createBuffer();
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
+ m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
+ state.bufferBinding = m_vertexAttrib0Buffer;
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
+ m_context->enableVertexAttribArray(0);
+ m_vertexAttrib0BufferSize = 0;
+ m_vertexAttrib0BufferValue[0] = 0.0f;
+ m_vertexAttrib0BufferValue[1] = 0.0f;
+ m_vertexAttrib0BufferValue[2] = 0.0f;
+ m_vertexAttrib0BufferValue[3] = 1.0f;
+ m_forceAttrib0BufferRefill = false;
+ m_vertexAttrib0UsedBefore = false;
+}
+
+bool WebGLRenderingContextBase::validateSimulatedVertexAttrib0(GC3Dsizei numVertex)
+{
+ if (numVertex < 0)
+ return false;
+
+ if (!m_currentProgram)
+ return true;
+
+ bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
+ if (!usingVertexAttrib0)
+ return true;
+
+ auto& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (state.enabled)
+ return true;
+
+ Checked<GC3Dsizei, RecordOverflow> bufferSize(numVertex);
+ bufferSize += 1;
+ bufferSize *= Checked<GC3Dsizei>(4);
+ Checked<GC3Dsizeiptr, RecordOverflow> bufferDataSize(bufferSize);
+ bufferDataSize *= Checked<GC3Dsizeiptr>(sizeof(GC3Dfloat));
+ return !bufferDataSize.hasOverflowed();
+}
+
+bool WebGLRenderingContextBase::simulateVertexAttrib0(GC3Dsizei numVertex)
+{
+ if (!m_currentProgram)
+ return false;
+ bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
+ if (usingVertexAttrib0)
+ m_vertexAttrib0UsedBefore = true;
+
+ auto& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (state.enabled && usingVertexAttrib0)
+ return false;
+ if (!usingVertexAttrib0 && !m_vertexAttrib0UsedBefore)
+ return false;
+ m_vertexAttrib0UsedBefore = true;
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
+
+ Checked<GC3Dsizei> bufferSize(numVertex);
+ bufferSize += 1;
+ bufferSize *= Checked<GC3Dsizei>(4);
+
+ Checked<GC3Dsizeiptr> bufferDataSize(bufferSize);
+ bufferDataSize *= Checked<GC3Dsizeiptr>(sizeof(GC3Dfloat));
+
+ if (bufferDataSize.unsafeGet() > m_vertexAttrib0BufferSize) {
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize.unsafeGet(), 0, GraphicsContext3D::DYNAMIC_DRAW);
+ m_vertexAttrib0BufferSize = bufferDataSize.unsafeGet();
+ m_forceAttrib0BufferRefill = true;
+ }
+
+ auto& attribValue = m_vertexAttribValue[0];
+
+ if (usingVertexAttrib0
+ && (m_forceAttrib0BufferRefill
+ || attribValue.value[0] != m_vertexAttrib0BufferValue[0]
+ || attribValue.value[1] != m_vertexAttrib0BufferValue[1]
+ || attribValue.value[2] != m_vertexAttrib0BufferValue[2]
+ || attribValue.value[3] != m_vertexAttrib0BufferValue[3])) {
+
+ auto bufferData = std::make_unique<GC3Dfloat[]>(bufferSize.unsafeGet());
+ for (GC3Dsizei ii = 0; ii < numVertex + 1; ++ii) {
+ bufferData[ii * 4] = attribValue.value[0];
+ bufferData[ii * 4 + 1] = attribValue.value[1];
+ bufferData[ii * 4 + 2] = attribValue.value[2];
+ bufferData[ii * 4 + 3] = attribValue.value[3];
+ }
+ m_vertexAttrib0BufferValue[0] = attribValue.value[0];
+ m_vertexAttrib0BufferValue[1] = attribValue.value[1];
+ m_vertexAttrib0BufferValue[2] = attribValue.value[2];
+ m_vertexAttrib0BufferValue[3] = attribValue.value[3];
+ m_forceAttrib0BufferRefill = false;
+ m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, bufferDataSize.unsafeGet(), bufferData.get());
+ }
+ m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, 0, 0, 0);
+ return true;
+}
+
+void WebGLRenderingContextBase::restoreStatesAfterVertexAttrib0Simulation()
+{
+ const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (state.bufferBinding != m_vertexAttrib0Buffer) {
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(state.bufferBinding.get()));
+ m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
+ }
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
+}
+
+void WebGLRenderingContextBase::dispatchContextLostEvent()
+{
+ Ref<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, emptyString());
+ canvas().dispatchEvent(event);
+ m_restoreAllowed = event->defaultPrevented();
+ if (m_contextLostMode == RealLostContext && m_restoreAllowed)
+ m_restoreTimer.startOneShot(0);
+}
+
+void WebGLRenderingContextBase::maybeRestoreContext()
+{
+ ASSERT(m_contextLost);
+ if (!m_contextLost)
+ return;
+
+ // The rendering context is not restored unless the default behavior of the
+ // webglcontextlost event was prevented earlier.
+ //
+ // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+ // context events, we don't have to worry about this test short-circuiting
+ // the retry loop for real context lost events.
+ if (!m_restoreAllowed)
+ return;
+
+ int contextLostReason = m_context->getExtensions().getGraphicsResetStatusARB();
+
+ switch (contextLostReason) {
+ case GraphicsContext3D::NO_ERROR:
+ // The GraphicsContext3D implementation might not fully
+ // support GL_ARB_robustness semantics yet. Alternatively, the
+ // WEBGL_lose_context extension might have been used to force
+ // a lost context.
+ break;
+ case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
+ // The rendering context is not restored if this context was
+ // guilty of causing the graphics reset.
+ printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
+ return;
+ case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
+ // Always allow the context to be restored.
+ break;
+ case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
+ // Warn. Ideally, prompt the user telling them that WebGL
+ // content on the page might have caused the graphics card to
+ // reset and ask them whether they want to continue running
+ // the content. Only if they say "yes" should we start
+ // attempting to restore the context.
+ printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
+ break;
+ }
+
+ Frame* frame = canvas().document().frame();
+ if (!frame)
+ return;
+
+ if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled()))
+ return;
+
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+ ScrollView* root = view->root();
+ if (!root)
+ return;
+ HostWindow* hostWindow = root->hostWindow();
+ if (!hostWindow)
+ return;
+
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, hostWindow));
+ if (!context) {
+ if (m_contextLostMode == RealLostContext)
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+ else
+ // This likely shouldn't happen but is the best way to report it to the WebGL app.
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context");
+ return;
+ }
+
+ m_context = context;
+ addActivityStateChangeObserverIfNecessary();
+ m_contextLost = false;
+ setupFlags();
+ initializeNewContext();
+ initializeVertexArrayObjects();
+ canvas().dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, emptyString()));
+}
+
+String WebGLRenderingContextBase::ensureNotNull(const String& text) const
+{
+ if (text.isNull())
+ return WTF::emptyString();
+ return text;
+}
+
+WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(std::make_unique<std::unique_ptr<ImageBuffer>[]>(capacity))
+ , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+ int i;
+ for (i = 0; i < m_capacity; ++i) {
+ ImageBuffer* buf = m_buffers[i].get();
+ if (!buf)
+ break;
+ if (buf->logicalSize() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ // FIXME (149423): Should this ImageBuffer be unconditionally unaccelerated?
+ std::unique_ptr<ImageBuffer> temp = ImageBuffer::create(size, Unaccelerated);
+ if (!temp)
+ return nullptr;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = WTFMove(temp);
+
+ ImageBuffer* buf = m_buffers[i].get();
+ bubbleToFront(i);
+ return buf;
+}
+
+void WebGLRenderingContextBase::LRUImageBufferCache::bubbleToFront(int idx)
+{
+ for (int i = idx; i > 0; --i)
+ m_buffers[i].swap(m_buffers[i-1]);
+}
+
+namespace {
+
+ String GetErrorString(GC3Denum error)
+ {
+ switch (error) {
+ case GraphicsContext3D::INVALID_ENUM:
+ return ASCIILiteral("INVALID_ENUM");
+ case GraphicsContext3D::INVALID_VALUE:
+ return ASCIILiteral("INVALID_VALUE");
+ case GraphicsContext3D::INVALID_OPERATION:
+ return ASCIILiteral("INVALID_OPERATION");
+ case GraphicsContext3D::OUT_OF_MEMORY:
+ return ASCIILiteral("OUT_OF_MEMORY");
+ case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION:
+ return ASCIILiteral("INVALID_FRAMEBUFFER_OPERATION");
+ case GraphicsContext3D::CONTEXT_LOST_WEBGL:
+ return ASCIILiteral("CONTEXT_LOST_WEBGL");
+ default:
+ return String::format("WebGL ERROR(%04x)", error);
+ }
+ }
+
+} // namespace anonymous
+
+void WebGLRenderingContextBase::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+{
+ if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
+ String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(str);
+ }
+ m_context->synthesizeGLError(error);
+}
+
+
+void WebGLRenderingContextBase::printGLWarningToConsole(const char* functionName, const char* description)
+{
+ if (m_synthesizedErrorsToConsole) {
+ String str = String("WebGL: ") + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(str);
+ }
+}
+
+void WebGLRenderingContextBase::applyStencilTest()
+{
+ bool haveStencilBuffer = false;
+
+ if (m_framebufferBinding)
+ haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
+ else {
+ auto attributes = getContextAttributes();
+ ASSERT(attributes);
+ haveStencilBuffer = attributes->stencil;
+ }
+ enableOrDisable(GraphicsContext3D::STENCIL_TEST, m_stencilEnabled && haveStencilBuffer);
+}
+
+void WebGLRenderingContextBase::enableOrDisable(GC3Denum capability, bool enable)
+{
+ if (enable)
+ m_context->enable(capability);
+ else
+ m_context->disable(capability);
+}
+
+IntSize WebGLRenderingContextBase::clampedCanvasSize()
+{
+ return IntSize(clamp(canvas().width(), 1, m_maxViewportDims[0]),
+ clamp(canvas().height(), 1, m_maxViewportDims[1]));
+}
+
+GC3Dint WebGLRenderingContextBase::getMaxDrawBuffers()
+{
+ if (!supportsDrawBuffers())
+ return 0;
+ if (!m_maxDrawBuffers)
+ m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+ return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+}
+
+GC3Dint WebGLRenderingContextBase::getMaxColorAttachments()
+{
+ if (!supportsDrawBuffers())
+ return 0;
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ return m_maxColorAttachments;
+}
+
+void WebGLRenderingContextBase::setBackDrawBuffer(GC3Denum buf)
+{
+ m_backDrawBuffer = buf;
+}
+
+void WebGLRenderingContextBase::restoreCurrentFramebuffer()
+{
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get());
+}
+
+void WebGLRenderingContextBase::restoreCurrentTexture2D()
+{
+ auto texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
+ bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
+ if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+ m_unrenderableTextureUnits.add(m_activeTextureUnit);
+}
+
+bool WebGLRenderingContextBase::supportsDrawBuffers()
+{
+ if (!m_drawBuffersWebGLRequirementsChecked) {
+ m_drawBuffersWebGLRequirementsChecked = true;
+ m_drawBuffersSupported = WebGLDrawBuffers::supported(*this);
+ }
+ return m_drawBuffersSupported;
+}
+
+void WebGLRenderingContextBase::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ if (!primcount) {
+ markContextChanged();
+ return;
+ }
+
+ if (!validateDrawArrays("drawArraysInstanced", mode, first, count, primcount))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArraysInstanced", true);
+
+ m_context->drawArraysInstanced(mode, first, count, primcount);
+
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArraysInstanced", false);
+ markContextChanged();
+}
+
+void WebGLRenderingContextBase::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
+{
+ if (!primcount) {
+ markContextChanged();
+ return;
+ }
+
+ unsigned numElements = 0;
+ if (!validateDrawElements("drawElementsInstanced", mode, count, type, offset, numElements, primcount))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElementsInstanced", true);
+
+ m_context->drawElementsInstanced(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
+
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElementsInstanced", false);
+ markContextChanged();
+}
+
+void WebGLRenderingContextBase::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ if (isContextLostOrPending())
+ return;
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribDivisor", "index out of range");
+ return;
+ }
+
+ m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
+ m_context->vertexAttribDivisor(index, divisor);
+}
+
+bool WebGLRenderingContextBase::enableSupportedExtension(const char* extensionNameLiteral)
+{
+ ASSERT(m_context);
+ auto& extensions = m_context->getExtensions();
+ String extensionName { ASCIILiteral { extensionNameLiteral } };
+ if (!extensions.supports(extensionName))
+ return false;
+ extensions.ensureEnabled(extensionName);
+ return true;
+}
+
+void WebGLRenderingContextBase::activityStateDidChange(ActivityState::Flags oldActivityState, ActivityState::Flags newActivityState)
+{
+ if (!m_context)
+ return;
+
+ ActivityState::Flags changed = oldActivityState ^ newActivityState;
+ if (changed & ActivityState::IsVisible)
+ m_context->setContextVisibility(newActivityState & ActivityState::IsVisible);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.h b/Source/WebCore/html/canvas/WebGLRenderingContextBase.h
new file mode 100644
index 000000000..31e5542e6
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.h
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGL)
+
+#include "ActiveDOMObject.h"
+#include "ActivityStateChangeObserver.h"
+#include "CanvasRenderingContext.h"
+#include "GraphicsContext3D.h"
+#include "ImageBuffer.h"
+#include "Timer.h"
+#include "WebGLAny.h"
+#include "WebGLBuffer.h"
+#include "WebGLContextAttributes.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLStateTracker.h"
+#include "WebGLTexture.h"
+#include "WebGLVertexArrayObjectOES.h"
+#include <memory>
+
+#if ENABLE(WEBGL2)
+#include "WebGLVertexArrayObject.h"
+#endif
+
+namespace WebCore {
+
+class ANGLEInstancedArrays;
+class EXTBlendMinMax;
+class EXTTextureFilterAnisotropic;
+class EXTShaderTextureLOD;
+class EXTsRGB;
+class EXTFragDepth;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageData;
+class IntSize;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESTextureFloatLinear;
+class OESTextureHalfFloat;
+class OESTextureHalfFloatLinear;
+class OESVertexArrayObject;
+class OESElementIndexUint;
+class WebGLActiveInfo;
+class WebGLContextGroup;
+class WebGLContextObject;
+class WebGLCompressedTextureATC;
+class WebGLCompressedTexturePVRTC;
+class WebGLCompressedTextureS3TC;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLDepthTexture;
+class WebGLDrawBuffers;
+class WebGLExtension;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLShader;
+class WebGLSharedObject;
+class WebGLShaderPrecisionFormat;
+class WebGLUniformLocation;
+
+inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
+{
+ ASSERT(clippedStart && clippedRange);
+ if (start < 0) {
+ range += start;
+ start = 0;
+ }
+ GC3Dint end = start + range;
+ if (end > sourceRange)
+ range -= end - sourceRange;
+ *clippedStart = start;
+ *clippedRange = range;
+}
+
+// Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
+inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+ GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
+ GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
+{
+ ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
+ clip1D(x, width, sourceWidth, clippedX, clippedWidth);
+ clip1D(y, height, sourceHeight, clippedY, clippedHeight);
+ return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
+}
+
+class WebGLRenderingContextBase : public CanvasRenderingContext, private ActivityStateChangeObserver, public ActiveDOMObject {
+public:
+ static std::unique_ptr<WebGLRenderingContextBase> create(HTMLCanvasElement&, WebGLContextAttributes&, const String&);
+ virtual ~WebGLRenderingContextBase();
+
+#if PLATFORM(WIN)
+ // FIXME: Implement accelerated 3d canvas on Windows.
+ bool isAccelerated() const override { return false; }
+#else
+ bool isAccelerated() const override { return true; }
+#endif
+
+ int drawingBufferWidth() const;
+ int drawingBufferHeight() const;
+
+ void activeTexture(GC3Denum texture);
+ void attachShader(WebGLProgram*, WebGLShader*);
+ void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name);
+ void bindBuffer(GC3Denum target, WebGLBuffer*);
+ void bindFramebuffer(GC3Denum target, WebGLFramebuffer*);
+ void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*);
+ void bindTexture(GC3Denum target, WebGLTexture*);
+ void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
+ void blendEquation(GC3Denum mode);
+ void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
+ void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
+ void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
+
+ using BufferDataSource = WTF::Variant<RefPtr<ArrayBuffer>, RefPtr<ArrayBufferView>>;
+ void bufferData(GC3Denum target, long long size, GC3Denum usage);
+ void bufferData(GC3Denum target, std::optional<BufferDataSource>&&, GC3Denum usage);
+ void bufferSubData(GC3Denum target, long long offset, std::optional<BufferDataSource>&&);
+
+ GC3Denum checkFramebufferStatus(GC3Denum target);
+ virtual void clear(GC3Dbitfield mask) = 0;
+ void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
+ void clearDepth(GC3Dfloat);
+ void clearStencil(GC3Dint);
+ void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
+ void compileShader(WebGLShader*);
+
+ void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, ArrayBufferView& data);
+ void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& data);
+
+ void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
+ void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+
+ RefPtr<WebGLBuffer> createBuffer();
+ RefPtr<WebGLFramebuffer> createFramebuffer();
+ RefPtr<WebGLProgram> createProgram();
+ RefPtr<WebGLRenderbuffer> createRenderbuffer();
+ RefPtr<WebGLShader> createShader(GC3Denum type);
+ RefPtr<WebGLTexture> createTexture();
+
+ void cullFace(GC3Denum mode);
+
+ void deleteBuffer(WebGLBuffer*);
+ void deleteFramebuffer(WebGLFramebuffer*);
+ void deleteProgram(WebGLProgram*);
+ void deleteRenderbuffer(WebGLRenderbuffer*);
+ void deleteShader(WebGLShader*);
+ void deleteTexture(WebGLTexture*);
+
+ void depthFunc(GC3Denum);
+ void depthMask(GC3Dboolean);
+ void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
+ void detachShader(WebGLProgram*, WebGLShader*);
+ void disable(GC3Denum cap);
+ void disableVertexAttribArray(GC3Duint index);
+ void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
+ void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
+
+ void enable(GC3Denum cap);
+ void enableVertexAttribArray(GC3Duint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*);
+ void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level);
+ void frontFace(GC3Denum mode);
+ void generateMipmap(GC3Denum target);
+
+ RefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index);
+ RefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index);
+ std::optional<Vector<RefPtr<WebGLShader>>> getAttachedShaders(WebGLProgram*);
+ GC3Dint getAttribLocation(WebGLProgram*, const String& name);
+ WebGLAny getBufferParameter(GC3Denum target, GC3Denum pname);
+ std::optional<WebGLContextAttributes> getContextAttributes();
+ GC3Denum getError();
+ virtual WebGLExtension* getExtension(const String& name) = 0;
+ virtual WebGLAny getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname) = 0;
+ virtual WebGLAny getParameter(GC3Denum pname) = 0;
+ WebGLAny getProgramParameter(WebGLProgram*, GC3Denum pname);
+ String getProgramInfoLog(WebGLProgram*);
+ WebGLAny getRenderbufferParameter(GC3Denum target, GC3Denum pname);
+ WebGLAny getShaderParameter(WebGLShader*, GC3Denum pname);
+ String getShaderInfoLog(WebGLShader*);
+ RefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType);
+ String getShaderSource(WebGLShader*);
+ virtual std::optional<Vector<String>> getSupportedExtensions() = 0;
+ WebGLAny getTexParameter(GC3Denum target, GC3Denum pname);
+ WebGLAny getUniform(WebGLProgram*, const WebGLUniformLocation*);
+ RefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
+ WebGLAny getVertexAttrib(GC3Duint index, GC3Denum pname);
+ long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
+
+ virtual void hint(GC3Denum target, GC3Denum mode) = 0;
+ GC3Dboolean isBuffer(WebGLBuffer*);
+ bool isContextLost() const;
+ GC3Dboolean isEnabled(GC3Denum cap);
+ GC3Dboolean isFramebuffer(WebGLFramebuffer*);
+ GC3Dboolean isProgram(WebGLProgram*);
+ GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
+ GC3Dboolean isShader(WebGLShader*);
+ GC3Dboolean isTexture(WebGLTexture*);
+
+ void lineWidth(GC3Dfloat);
+ void linkProgram(WebGLProgram*);
+ void pixelStorei(GC3Denum pname, GC3Dint param);
+ void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
+ void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView& pixels);
+ void releaseShaderCompiler();
+ virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) = 0;
+ void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
+ void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+ void shaderSource(WebGLShader*, const String&);
+ void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
+ void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
+ void stencilMask(GC3Duint);
+ void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
+ void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
+ void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
+
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&);
+
+ using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
+ ExceptionOr<void> texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, std::optional<TexImageSource>);
+
+ void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
+ void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
+
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&);
+ ExceptionOr<void> texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, std::optional<TexImageSource>&&);
+
+ template <class TypedArray, class DataType>
+ class TypedList {
+ public:
+ using VariantType = Variant<RefPtr<TypedArray>, Vector<DataType>>;
+
+ TypedList(VariantType&& variant)
+ : m_variant(WTFMove(variant))
+ {
+ }
+
+ DataType* data() const
+ {
+ return WTF::switchOn(m_variant,
+ [] (const RefPtr<TypedArray>& typedArray) -> DataType* { return typedArray->data(); },
+ [] (const Vector<DataType>& vector) -> DataType* { return const_cast<Vector<DataType>&>(vector).data(); }
+ );
+ }
+
+ GC3Dsizei length() const
+ {
+ return WTF::switchOn(m_variant,
+ [] (const RefPtr<TypedArray>& typedArray) -> GC3Dsizei { return typedArray->length(); },
+ [] (const Vector<DataType>& vector) -> GC3Dsizei { return vector.size(); }
+ );
+ }
+
+ private:
+ VariantType m_variant;
+ };
+
+ using Float32List = TypedList<Float32Array, float>;
+ using Int32List = TypedList<Int32Array, int>;
+
+ void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
+ void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y);
+ void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
+ void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
+
+ void uniform1i(const WebGLUniformLocation*, GC3Dint x);
+ void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y);
+ void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z);
+ void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
+
+ void uniform1fv(const WebGLUniformLocation*, Float32List&&);
+ void uniform2fv(const WebGLUniformLocation*, Float32List&&);
+ void uniform3fv(const WebGLUniformLocation*, Float32List&&);
+ void uniform4fv(const WebGLUniformLocation*, Float32List&&);
+
+ void uniform1iv(const WebGLUniformLocation*, Int32List&&);
+ void uniform2iv(const WebGLUniformLocation*, Int32List&&);
+ void uniform3iv(const WebGLUniformLocation*, Int32List&&);
+ void uniform4iv(const WebGLUniformLocation*, Int32List&&);
+
+ void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
+ void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
+ void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32List&&);
+
+ void useProgram(WebGLProgram*);
+ void validateProgram(WebGLProgram*);
+
+ void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
+ void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
+ void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
+ void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
+
+ void vertexAttrib1fv(GC3Duint index, Float32List&&);
+ void vertexAttrib2fv(GC3Duint index, Float32List&&);
+ void vertexAttrib3fv(GC3Duint index, Float32List&&);
+ void vertexAttrib4fv(GC3Duint index, Float32List&&);
+
+ void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
+ GC3Dsizei stride, long long offset);
+
+ void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+
+ // WEBKIT_lose_context support
+ enum LostContextMode {
+ // Lost context occurred at the graphics system level.
+ RealLostContext,
+
+ // Lost context provoked by WEBKIT_lose_context.
+ SyntheticLostContext
+ };
+ void forceLostContext(LostContextMode);
+ void recycleContext();
+ void forceRestoreContext();
+ void loseContextImpl(LostContextMode);
+
+ GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+ WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
+ PlatformLayer* platformLayer() const override;
+
+ void reshape(int width, int height);
+
+ void markLayerComposited();
+ void paintRenderingResultsToCanvas() override;
+ RefPtr<ImageData> paintRenderingResultsToImageData();
+
+ void removeSharedObject(WebGLSharedObject&);
+ void removeContextObject(WebGLContextObject&);
+
+ unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
+
+ // Instanced Array helper functions.
+ void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
+ void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
+ void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+
+protected:
+ WebGLRenderingContextBase(HTMLCanvasElement&, WebGLContextAttributes);
+ WebGLRenderingContextBase(HTMLCanvasElement&, Ref<GraphicsContext3D>&&, WebGLContextAttributes);
+
+ friend class WebGLDrawBuffers;
+ friend class WebGLFramebuffer;
+ friend class WebGLObject;
+ friend class OESVertexArrayObject;
+ friend class WebGLDebugShaders;
+ friend class WebGLCompressedTextureATC;
+ friend class WebGLCompressedTexturePVRTC;
+ friend class WebGLCompressedTextureS3TC;
+ friend class WebGLRenderingContextErrorMessageCallback;
+ friend class WebGLVertexArrayObjectOES;
+ friend class WebGLVertexArrayObject;
+ friend class WebGLVertexArrayObjectBase;
+
+ virtual void initializeNewContext();
+ virtual void initializeVertexArrayObjects() = 0;
+ void setupFlags();
+
+ // ActiveDOMObject
+ bool hasPendingActivity() const override;
+ void stop() override;
+ const char* activeDOMObjectName() const override;
+ bool canSuspendForDocumentSuspension() const override;
+
+ void addSharedObject(WebGLSharedObject&);
+ void addContextObject(WebGLContextObject&);
+ void detachAndRemoveAllObjects();
+
+ void destroyGraphicsContext3D();
+ void markContextChanged();
+
+ void addActivityStateChangeObserverIfNecessary();
+ void removeActivityStateChangeObserver();
+
+ // Query whether it is built on top of compliant GLES2 implementation.
+ bool isGLES2Compliant() { return m_isGLES2Compliant; }
+ // Query if the GL implementation is NPOT strict.
+ bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
+ // Query if depth_stencil buffer is supported.
+ bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
+
+ // Helper to return the size in bytes of OpenGL data types
+ // like GL_FLOAT, GL_INT, etc.
+ unsigned int sizeInBytes(GC3Denum type);
+
+ // Basic validation of count and offset against number of elements in element array buffer
+ bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
+
+ // Conservative but quick index validation
+ virtual bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) = 0;
+
+ // Precise but slow index validation -- only done if conservative checks fail
+ bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired);
+ bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);
+
+ bool validateWebGLObject(const char*, WebGLObject*);
+
+ bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
+ bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primcount);
+ bool validateNPOTTextureLevel(GC3Dsizei width, GC3Dsizei height, GC3Dint level, const char* functionName);
+
+ // Adds a compressed texture format.
+ void addCompressedTextureFormat(GC3Denum);
+
+ RefPtr<Image> drawImageIntoBuffer(Image&, int width, int height, int deviceScaleFactor);
+
+#if ENABLE(VIDEO)
+ RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
+#endif
+
+ WebGLTexture::TextureExtensionFlag textureExtensionFlags() const;
+
+ bool enableSupportedExtension(const char* extensionNameLiteral);
+
+ RefPtr<GraphicsContext3D> m_context;
+ RefPtr<WebGLContextGroup> m_contextGroup;
+
+ // Dispatches a context lost event once it is determined that one is needed.
+ // This is used both for synthetic 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.
+ Timer m_dispatchContextLostEventTimer;
+ bool m_restoreAllowed { false };
+ Timer m_restoreTimer;
+
+ bool m_needsUpdate;
+ bool m_markedCanvasDirty;
+ HashSet<WebGLContextObject*> m_contextObjects;
+
+ // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
+ RefPtr<WebGLBuffer> m_boundArrayBuffer;
+ RefPtr<WebGLBuffer> m_boundCopyReadBuffer;
+ RefPtr<WebGLBuffer> m_boundCopyWriteBuffer;
+ RefPtr<WebGLBuffer> m_boundPixelPackBuffer;
+ RefPtr<WebGLBuffer> m_boundPixelUnpackBuffer;
+ RefPtr<WebGLBuffer> m_boundTransformFeedbackBuffer;
+ RefPtr<WebGLBuffer> m_boundUniformBuffer;
+
+ RefPtr<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
+ RefPtr<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;
+
+ void setBoundVertexArrayObject(WebGLVertexArrayObjectBase* arrayObject)
+ {
+ m_boundVertexArrayObject = arrayObject ? arrayObject : m_defaultVertexArrayObject;
+ }
+
+ class VertexAttribValue {
+ public:
+ VertexAttribValue()
+ {
+ initValue();
+ }
+
+ void initValue()
+ {
+ value[0] = 0.0f;
+ value[1] = 0.0f;
+ value[2] = 0.0f;
+ value[3] = 1.0f;
+ }
+
+ GC3Dfloat value[4];
+ };
+ Vector<VertexAttribValue> m_vertexAttribValue;
+ unsigned m_maxVertexAttribs;
+ RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+ long m_vertexAttrib0BufferSize;
+ GC3Dfloat m_vertexAttrib0BufferValue[4];
+ bool m_forceAttrib0BufferRefill;
+ bool m_vertexAttrib0UsedBefore;
+
+ RefPtr<WebGLProgram> m_currentProgram;
+ RefPtr<WebGLFramebuffer> m_framebufferBinding;
+ RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
+ struct TextureUnitState {
+ RefPtr<WebGLTexture> texture2DBinding;
+ RefPtr<WebGLTexture> textureCubeMapBinding;
+ };
+ Vector<TextureUnitState> m_textureUnits;
+ HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_unrenderableTextureUnits;
+
+ unsigned long m_activeTextureUnit;
+
+ RefPtr<WebGLTexture> m_blackTexture2D;
+ RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+ Vector<GC3Denum> m_compressedTextureFormats;
+
+ // Fixed-size cache of reusable image buffers for video texImage2D calls.
+ class LRUImageBufferCache {
+ public:
+ LRUImageBufferCache(int capacity);
+ // The pointer returned is owned by the image buffer map.
+ ImageBuffer* imageBuffer(const IntSize& size);
+ private:
+ void bubbleToFront(int idx);
+ std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_generatedImageCache { 0 };
+
+ GC3Dint m_maxTextureSize;
+ GC3Dint m_maxCubeMapTextureSize;
+ GC3Dint m_maxRenderbufferSize;
+ GC3Dint m_maxViewportDims[2] { 0, 0 };
+ GC3Dint m_maxTextureLevel;
+ GC3Dint m_maxCubeMapTextureLevel;
+
+ GC3Dint m_maxDrawBuffers;
+ GC3Dint m_maxColorAttachments;
+ GC3Denum m_backDrawBuffer;
+ bool m_drawBuffersWebGLRequirementsChecked;
+ bool m_drawBuffersSupported;
+
+ GC3Dint m_packAlignment;
+ GC3Dint m_unpackAlignment;
+ bool m_unpackFlipY;
+ bool m_unpackPremultiplyAlpha;
+ GC3Denum m_unpackColorspaceConversion;
+ bool m_contextLost { false };
+ LostContextMode m_contextLostMode { SyntheticLostContext };
+ WebGLContextAttributes m_attributes;
+
+ bool m_layerCleared;
+ GC3Dfloat m_clearColor[4];
+ bool m_scissorEnabled;
+ GC3Dfloat m_clearDepth;
+ GC3Dint m_clearStencil;
+ GC3Dboolean m_colorMask[4];
+ GC3Dboolean m_depthMask;
+
+ bool m_stencilEnabled;
+ GC3Duint m_stencilMask, m_stencilMaskBack;
+ GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+ GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
+
+ bool m_isGLES2Compliant;
+ bool m_isGLES2NPOTStrict;
+ bool m_isDepthStencilSupported;
+ bool m_isRobustnessEXTSupported;
+
+ bool m_synthesizedErrorsToConsole { true };
+ int m_numGLErrorsToConsoleAllowed;
+
+ // A WebGLRenderingContext can be created in a state where it appears as
+ // a valid and active context, but will not execute any important operations
+ // until its load policy is completely resolved.
+ bool m_isPendingPolicyResolution { false };
+ bool m_hasRequestedPolicyResolution { false };
+ bool isContextLostOrPending();
+
+ // Enabled extension objects.
+ // FIXME: Move some of these to WebGLRenderingContext, the ones not needed for WebGL2
+ std::unique_ptr<EXTFragDepth> m_extFragDepth;
+ std::unique_ptr<EXTBlendMinMax> m_extBlendMinMax;
+ std::unique_ptr<EXTsRGB> m_extsRGB;
+ std::unique_ptr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
+ std::unique_ptr<EXTShaderTextureLOD> m_extShaderTextureLOD;
+ std::unique_ptr<OESTextureFloat> m_oesTextureFloat;
+ std::unique_ptr<OESTextureFloatLinear> m_oesTextureFloatLinear;
+ std::unique_ptr<OESTextureHalfFloat> m_oesTextureHalfFloat;
+ std::unique_ptr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
+ std::unique_ptr<OESStandardDerivatives> m_oesStandardDerivatives;
+ std::unique_ptr<OESVertexArrayObject> m_oesVertexArrayObject;
+ std::unique_ptr<OESElementIndexUint> m_oesElementIndexUint;
+ std::unique_ptr<WebGLLoseContext> m_webglLoseContext;
+ std::unique_ptr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
+ std::unique_ptr<WebGLDebugShaders> m_webglDebugShaders;
+ std::unique_ptr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
+ std::unique_ptr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
+ std::unique_ptr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
+ std::unique_ptr<WebGLDepthTexture> m_webglDepthTexture;
+ std::unique_ptr<WebGLDrawBuffers> m_webglDrawBuffers;
+ std::unique_ptr<ANGLEInstancedArrays> m_angleInstancedArrays;
+
+ // Helpers for getParameter and other similar functions.
+ bool getBooleanParameter(GC3Denum);
+ Vector<bool> getBooleanArrayParameter(GC3Denum);
+ float getFloatParameter(GC3Denum);
+ int getIntParameter(GC3Denum);
+ unsigned getUnsignedIntParameter(GC3Denum);
+ long long getInt64Parameter(GC3Denum);
+ RefPtr<Float32Array> getWebGLFloatArrayParameter(GC3Denum);
+ RefPtr<Int32Array> getWebGLIntArrayParameter(GC3Denum);
+
+ // 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 true if that clear is now unnecessary.
+ bool clearIfComposited(GC3Dbitfield clearMask = 0);
+
+ // Helper to restore state that clearing the framebuffer may destroy.
+ void restoreStateAfterClear();
+
+ void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
+ void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
+ void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels);
+ void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
+
+ bool checkTextureCompleteness(const char*, bool);
+
+ void createFallbackBlackTextures1x1();
+
+ // 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(GC3Denum texInternalFormat,
+ GC3Denum colorBufferFormat);
+
+ // Helper function to get the bound framebuffer's color buffer format.
+ GC3Denum getBoundFramebufferColorFormat();
+
+ // Helper function to get the bound framebuffer's width.
+ int getBoundFramebufferWidth();
+
+ // Helper function to get the bound framebuffer's height.
+ int getBoundFramebufferHeight();
+
+ // Helper function to verify limits on the length of uniform and attribute locations.
+ bool validateLocationLength(const char* functionName, 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* functionName, GC3Dint x, GC3Dint y);
+
+ // 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* functionName, const String&);
+
+ // Helper function to check 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* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
+
+ // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level);
+
+ // 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* functionName, GC3Denum target, GC3Dint level);
+
+ enum TexFuncValidationFunctionType {
+ TexImage,
+ TexSubImage,
+ CopyTexImage
+ };
+
+ enum TexFuncValidationSourceType {
+ SourceArrayBufferView,
+ SourceImageData,
+ SourceHTMLImageElement,
+ SourceHTMLCanvasElement,
+ SourceHTMLVideoElement,
+ };
+
+ // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
+ // Otherwise, it would return quickly without doing other work.
+ bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
+
+ // 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* functionName,
+ TexFuncValidationFunctionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type);
+
+ enum NullDisposition {
+ NullAllowed,
+ NullNotAllowed
+ };
+
+ // 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* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum internalformat, GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition);
+
+ // 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 validateSettableTexInternalFormat(const char* functionName, GC3Denum format);
+
+ // Helper function to validate compressed texture data is correct size
+ // for the given format and dimensions.
+ bool validateCompressedTexFuncData(const char* functionName, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& pixels);
+
+ // Helper function for validating compressed texture formats.
+ bool validateCompressedTexFormat(GC3Denum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(const char* functionName, GC3Denum);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings(const char* functionName);
+
+ // Helper function to validate stencil func.
+ bool validateStencilFunc(const char* functionName, GC3Denum);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
+
+ // Helper function to print GL errors to console.
+ void printGLErrorToConsole(const String&);
+ void printGLWarningToConsole(const char* function, const char* reason);
+
+ // 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 input parameters for framebuffer functions.
+ // Generate GL error if parameters are illegal.
+ virtual bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) = 0;
+
+ // Helper function to validate blend equation mode.
+ virtual bool validateBlendEquation(const char* functionName, GC3Denum) = 0;
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
+
+ // Helper function to validate a GL capability.
+ virtual bool validateCapability(const char* functionName, GC3Denum) = 0;
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, const Float32List&, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, const Int32List&, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, const Float32List&, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
+
+ // Helper function to validate parameters for bufferData.
+ // Return the current bound buffer to target, or 0 if parameters are invalid.
+ WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
+
+ // Helper function for tex{Sub}Image2D to make sure image is ready.
+ bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionCode&);
+ bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionCode&);
+#if ENABLE(VIDEO)
+ bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionCode&);
+#endif
+
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
+ void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32List&&, GC3Dsizei expectedSize);
+
+ // 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* functionName, WebGLObject*, bool& deleted);
+
+ // Helpers for simulating vertexAttrib0.
+ void initVertexAttrib0();
+ bool simulateVertexAttrib0(GC3Dsizei numVertex);
+ bool validateSimulatedVertexAttrib0(GC3Dsizei numVertex);
+ void restoreStatesAfterVertexAttrib0Simulation();
+
+ void dispatchContextLostEvent();
+ // Helper for restoration after context lost.
+ void maybeRestoreContext();
+
+ // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message to the JavaScript console.
+ enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };
+ void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+
+ 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(GC3Denum capability, bool enable);
+
+ // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
+ IntSize clampedCanvasSize();
+
+ virtual GC3Dint getMaxDrawBuffers() = 0;
+ virtual GC3Dint getMaxColorAttachments() = 0;
+
+ void setBackDrawBuffer(GC3Denum);
+
+ void restoreCurrentFramebuffer();
+ void restoreCurrentTexture2D();
+
+ // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
+ bool supportsDrawBuffers();
+
+private:
+ bool validateArrayBufferType(const char* functionName, GC3Denum type, std::optional<JSC::TypedArrayType>);
+ void registerWithWebGLStateTracker();
+ void checkForContextLossHandling();
+
+ void activityStateDidChange(ActivityState::Flags oldActivityState, ActivityState::Flags newActivityState) override;
+
+ WebGLStateTracker::Token m_trackerToken;
+ Timer m_checkForContextLossHandlingTimer;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::WebGLRenderingContextBase, is3d())
+
+#endif
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl b/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl
new file mode 100644
index 000000000..63b64cdeb
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+typedef unsigned long GLenum;
+typedef boolean GLboolean;
+typedef unsigned long GLbitfield;
+typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
+typedef short GLshort;
+typedef long GLint;
+typedef long GLsizei;
+typedef long long GLintptr;
+typedef long long GLsizeiptr;
+typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
+typedef unsigned short GLushort;
+typedef unsigned long GLuint;
+typedef unrestricted float GLfloat;
+typedef unrestricted float GLclampf;
+typedef (ArrayBuffer or ArrayBufferView) BufferDataSource;
+typedef (Float32Array or sequence<GLfloat>) Float32List;
+typedef (Int32Array or sequence<GLint>) Int32List;
+
+// FIXME: Should allow ImageBitmap too.
+typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
+
+[
+ Conditional=WEBGL,
+ CustomIsReachable,
+ CustomToJSObject,
+ DoNotCheckConstants,
+ JSCustomMarkFunction,
+ NoInterfaceObject,
+] interface WebGLRenderingContextBase {
+
+ // back-reference to the canvas
+ readonly attribute HTMLCanvasElement canvas;
+
+ /* ClearBufferMask */
+ const GLenum DEPTH_BUFFER_BIT = 0x00000100;
+ const GLenum STENCIL_BUFFER_BIT = 0x00000400;
+ const GLenum COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const GLenum POINTS = 0x0000;
+ const GLenum LINES = 0x0001;
+ const GLenum LINE_LOOP = 0x0002;
+ const GLenum LINE_STRIP = 0x0003;
+ const GLenum TRIANGLES = 0x0004;
+ const GLenum TRIANGLE_STRIP = 0x0005;
+ const GLenum TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const GLenum ZERO = 0;
+ const GLenum ONE = 1;
+ const GLenum SRC_COLOR = 0x0300;
+ const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
+ const GLenum SRC_ALPHA = 0x0302;
+ const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
+ const GLenum DST_ALPHA = 0x0304;
+ const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const GLenum DST_COLOR = 0x0306;
+ const GLenum ONE_MINUS_DST_COLOR = 0x0307;
+ const GLenum SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const GLenum FUNC_ADD = 0x8006;
+ const GLenum BLEND_EQUATION = 0x8009;
+ const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const GLenum BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const GLenum FUNC_SUBTRACT = 0x800A;
+ const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const GLenum BLEND_DST_RGB = 0x80C8;
+ const GLenum BLEND_SRC_RGB = 0x80C9;
+ const GLenum BLEND_DST_ALPHA = 0x80CA;
+ const GLenum BLEND_SRC_ALPHA = 0x80CB;
+ const GLenum CONSTANT_COLOR = 0x8001;
+ const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const GLenum CONSTANT_ALPHA = 0x8003;
+ const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const GLenum BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const GLenum ARRAY_BUFFER = 0x8892;
+ const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
+ const GLenum ARRAY_BUFFER_BINDING = 0x8894;
+ const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const GLenum STREAM_DRAW = 0x88E0;
+ const GLenum STATIC_DRAW = 0x88E4;
+ const GLenum DYNAMIC_DRAW = 0x88E8;
+
+ const GLenum BUFFER_SIZE = 0x8764;
+ const GLenum BUFFER_USAGE = 0x8765;
+
+ const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const GLenum FRONT = 0x0404;
+ const GLenum BACK = 0x0405;
+ const GLenum FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const GLenum TEXTURE_2D = 0x0DE1;
+ const GLenum CULL_FACE = 0x0B44;
+ const GLenum BLEND = 0x0BE2;
+ const GLenum DITHER = 0x0BD0;
+ const GLenum STENCIL_TEST = 0x0B90;
+ const GLenum DEPTH_TEST = 0x0B71;
+ const GLenum SCISSOR_TEST = 0x0C11;
+ const GLenum POLYGON_OFFSET_FILL = 0x8037;
+ const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const GLenum SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const GLenum NO_ERROR = 0;
+ const GLenum INVALID_ENUM = 0x0500;
+ const GLenum INVALID_VALUE = 0x0501;
+ const GLenum INVALID_OPERATION = 0x0502;
+ const GLenum OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const GLenum CW = 0x0900;
+ const GLenum CCW = 0x0901;
+
+ /* GetPName */
+ const GLenum LINE_WIDTH = 0x0B21;
+ const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const GLenum CULL_FACE_MODE = 0x0B45;
+ const GLenum FRONT_FACE = 0x0B46;
+ const GLenum DEPTH_RANGE = 0x0B70;
+ const GLenum DEPTH_WRITEMASK = 0x0B72;
+ const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
+ const GLenum DEPTH_FUNC = 0x0B74;
+ const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
+ const GLenum STENCIL_FUNC = 0x0B92;
+ const GLenum STENCIL_FAIL = 0x0B94;
+ const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const GLenum STENCIL_REF = 0x0B97;
+ const GLenum STENCIL_VALUE_MASK = 0x0B93;
+ const GLenum STENCIL_WRITEMASK = 0x0B98;
+ const GLenum STENCIL_BACK_FUNC = 0x8800;
+ const GLenum STENCIL_BACK_FAIL = 0x8801;
+ const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const GLenum STENCIL_BACK_REF = 0x8CA3;
+ const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const GLenum VIEWPORT = 0x0BA2;
+ const GLenum SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const GLenum COLOR_CLEAR_VALUE = 0x0C22;
+ const GLenum COLOR_WRITEMASK = 0x0C23;
+ const GLenum UNPACK_ALIGNMENT = 0x0CF5;
+ const GLenum PACK_ALIGNMENT = 0x0D05;
+ const GLenum MAX_TEXTURE_SIZE = 0x0D33;
+ const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
+ const GLenum SUBPIXEL_BITS = 0x0D50;
+ const GLenum RED_BITS = 0x0D52;
+ const GLenum GREEN_BITS = 0x0D53;
+ const GLenum BLUE_BITS = 0x0D54;
+ const GLenum ALPHA_BITS = 0x0D55;
+ const GLenum DEPTH_BITS = 0x0D56;
+ const GLenum STENCIL_BITS = 0x0D57;
+ const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
+ const GLenum TEXTURE_BINDING_2D = 0x8069;
+ const GLenum SAMPLE_BUFFERS = 0x80A8;
+ const GLenum SAMPLES = 0x80A9;
+ const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const GLenum DONT_CARE = 0x1100;
+ const GLenum FASTEST = 0x1101;
+ const GLenum NICEST = 0x1102;
+
+ /* HintTarget */
+ const GLenum GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const GLenum BYTE = 0x1400;
+ const GLenum UNSIGNED_BYTE = 0x1401;
+ const GLenum SHORT = 0x1402;
+ const GLenum UNSIGNED_SHORT = 0x1403;
+ const GLenum INT = 0x1404;
+ const GLenum UNSIGNED_INT = 0x1405;
+ const GLenum FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const GLenum DEPTH_COMPONENT = 0x1902;
+ const GLenum ALPHA = 0x1906;
+ const GLenum RGB = 0x1907;
+ const GLenum RGBA = 0x1908;
+ const GLenum LUMINANCE = 0x1909;
+ const GLenum LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const GLenum FRAGMENT_SHADER = 0x8B30;
+ const GLenum VERTEX_SHADER = 0x8B31;
+ const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
+ const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const GLenum MAX_VARYING_VECTORS = 0x8DFC;
+ const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const GLenum SHADER_TYPE = 0x8B4F;
+ const GLenum DELETE_STATUS = 0x8B80;
+ const GLenum LINK_STATUS = 0x8B82;
+ const GLenum VALIDATE_STATUS = 0x8B83;
+ const GLenum ATTACHED_SHADERS = 0x8B85;
+ const GLenum ACTIVE_UNIFORMS = 0x8B86;
+ const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
+ const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const GLenum CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const GLenum NEVER = 0x0200;
+ const GLenum LESS = 0x0201;
+ const GLenum EQUAL = 0x0202;
+ const GLenum LEQUAL = 0x0203;
+ const GLenum GREATER = 0x0204;
+ const GLenum NOTEQUAL = 0x0205;
+ const GLenum GEQUAL = 0x0206;
+ const GLenum ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const GLenum KEEP = 0x1E00;
+ const GLenum REPLACE = 0x1E01;
+ const GLenum INCR = 0x1E02;
+ const GLenum DECR = 0x1E03;
+ const GLenum INVERT = 0x150A;
+ const GLenum INCR_WRAP = 0x8507;
+ const GLenum DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const GLenum VENDOR = 0x1F00;
+ const GLenum RENDERER = 0x1F01;
+ const GLenum VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const GLenum NEAREST = 0x2600;
+ const GLenum LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
+ const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
+ const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
+ const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const GLenum TEXTURE_MAG_FILTER = 0x2800;
+ const GLenum TEXTURE_MIN_FILTER = 0x2801;
+ const GLenum TEXTURE_WRAP_S = 0x2802;
+ const GLenum TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const GLenum TEXTURE = 0x1702;
+
+ const GLenum TEXTURE_CUBE_MAP = 0x8513;
+ const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const GLenum TEXTURE0 = 0x84C0;
+ const GLenum TEXTURE1 = 0x84C1;
+ const GLenum TEXTURE2 = 0x84C2;
+ const GLenum TEXTURE3 = 0x84C3;
+ const GLenum TEXTURE4 = 0x84C4;
+ const GLenum TEXTURE5 = 0x84C5;
+ const GLenum TEXTURE6 = 0x84C6;
+ const GLenum TEXTURE7 = 0x84C7;
+ const GLenum TEXTURE8 = 0x84C8;
+ const GLenum TEXTURE9 = 0x84C9;
+ const GLenum TEXTURE10 = 0x84CA;
+ const GLenum TEXTURE11 = 0x84CB;
+ const GLenum TEXTURE12 = 0x84CC;
+ const GLenum TEXTURE13 = 0x84CD;
+ const GLenum TEXTURE14 = 0x84CE;
+ const GLenum TEXTURE15 = 0x84CF;
+ const GLenum TEXTURE16 = 0x84D0;
+ const GLenum TEXTURE17 = 0x84D1;
+ const GLenum TEXTURE18 = 0x84D2;
+ const GLenum TEXTURE19 = 0x84D3;
+ const GLenum TEXTURE20 = 0x84D4;
+ const GLenum TEXTURE21 = 0x84D5;
+ const GLenum TEXTURE22 = 0x84D6;
+ const GLenum TEXTURE23 = 0x84D7;
+ const GLenum TEXTURE24 = 0x84D8;
+ const GLenum TEXTURE25 = 0x84D9;
+ const GLenum TEXTURE26 = 0x84DA;
+ const GLenum TEXTURE27 = 0x84DB;
+ const GLenum TEXTURE28 = 0x84DC;
+ const GLenum TEXTURE29 = 0x84DD;
+ const GLenum TEXTURE30 = 0x84DE;
+ const GLenum TEXTURE31 = 0x84DF;
+ const GLenum ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const GLenum REPEAT = 0x2901;
+ const GLenum CLAMP_TO_EDGE = 0x812F;
+ const GLenum MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const GLenum FLOAT_VEC2 = 0x8B50;
+ const GLenum FLOAT_VEC3 = 0x8B51;
+ const GLenum FLOAT_VEC4 = 0x8B52;
+ const GLenum INT_VEC2 = 0x8B53;
+ const GLenum INT_VEC3 = 0x8B54;
+ const GLenum INT_VEC4 = 0x8B55;
+ const GLenum BOOL = 0x8B56;
+ const GLenum BOOL_VEC2 = 0x8B57;
+ const GLenum BOOL_VEC3 = 0x8B58;
+ const GLenum BOOL_VEC4 = 0x8B59;
+ const GLenum FLOAT_MAT2 = 0x8B5A;
+ const GLenum FLOAT_MAT3 = 0x8B5B;
+ const GLenum FLOAT_MAT4 = 0x8B5C;
+ const GLenum SAMPLER_2D = 0x8B5E;
+ const GLenum SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Read Format */
+ const GLenum IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+ const GLenum IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+
+ /* Shader Source */
+ const GLenum COMPILE_STATUS = 0x8B81;
+
+ /* Shader Precision-Specified Types */
+ const GLenum LOW_FLOAT = 0x8DF0;
+ const GLenum MEDIUM_FLOAT = 0x8DF1;
+ const GLenum HIGH_FLOAT = 0x8DF2;
+ const GLenum LOW_INT = 0x8DF3;
+ const GLenum MEDIUM_INT = 0x8DF4;
+ const GLenum HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const GLenum FRAMEBUFFER = 0x8D40;
+ const GLenum RENDERBUFFER = 0x8D41;
+
+ const GLenum RGBA4 = 0x8056;
+ const GLenum RGB5_A1 = 0x8057;
+ const GLenum RGB565 = 0x8D62;
+ const GLenum DEPTH_COMPONENT16 = 0x81A5;
+ const GLenum STENCIL_INDEX = 0x1901;
+ const GLenum STENCIL_INDEX8 = 0x8D48;
+ const GLenum DEPTH_STENCIL = 0x84F9;
+
+ const GLenum RENDERBUFFER_WIDTH = 0x8D42;
+ const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
+ const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
+ const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
+ const GLenum DEPTH_ATTACHMENT = 0x8D00;
+ const GLenum STENCIL_ATTACHMENT = 0x8D20;
+ const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const GLenum NONE = 0;
+
+ const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
+ const GLenum RENDERBUFFER_BINDING = 0x8CA7;
+ const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const GLenum CONTEXT_LOST_WEBGL = 0x9242;
+ const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ readonly attribute GLsizei drawingBufferWidth;
+ readonly attribute GLsizei drawingBufferHeight;
+
+ void activeTexture(GLenum texture);
+ void attachShader(WebGLProgram? program, WebGLShader? shader);
+ void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
+ void bindBuffer(GLenum target, WebGLBuffer? buffer);
+ void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
+ void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
+ void bindTexture(GLenum target, WebGLTexture? texture);
+ void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void bufferData(GLenum target, BufferDataSource? data, GLenum usage);
+ void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ void bufferSubData(GLenum target, GLintptr offset, BufferDataSource? data);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void clear(GLbitfield mask);
+ void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void clearDepth(GLclampf depth);
+ void clearStencil(GLint s);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void compileShader(WebGLShader? shader);
+
+ void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
+ void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, ArrayBufferView 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? buffer);
+ void deleteFramebuffer(WebGLFramebuffer? framebuffer);
+ void deleteProgram(WebGLProgram? program);
+ void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ void deleteShader(WebGLShader? shader);
+ void deleteTexture(WebGLTexture? texture);
+
+ void depthFunc(GLenum func);
+ void depthMask(GLboolean flag);
+ void depthRange(GLclampf zNear, GLclampf zFar);
+ void detachShader(WebGLProgram? program, WebGLShader? shader);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
+
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer);
+ void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level);
+ void frontFace(GLenum mode);
+ void generateMipmap(GLenum target);
+
+ WebGLActiveInfo getActiveAttrib(WebGLProgram? program, GLuint index);
+ WebGLActiveInfo getActiveUniform(WebGLProgram? program, GLuint index);
+
+ // FIXME: The spec says this should not take a nullable WebGLProgram.
+ sequence<WebGLShader>? getAttachedShaders(WebGLProgram? program);
+
+ GLint getAttribLocation(WebGLProgram? program, DOMString name);
+
+ [OverrideIDLType=IDLWebGLAny] any getBufferParameter(GLenum target, GLenum pname);
+
+ WebGLContextAttributes? getContextAttributes();
+
+ GLenum getError();
+
+ sequence<DOMString>? getSupportedExtensions();
+ [Custom] object? getExtension(DOMString name);
+
+ [OverrideIDLType=IDLWebGLAny] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ [OverrideIDLType=IDLWebGLAny] any getParameter(GLenum pname);
+ [OverrideIDLType=IDLWebGLAny] any getProgramParameter(WebGLProgram? program, GLenum pname);
+ DOMString? getProgramInfoLog(WebGLProgram? program);
+ [OverrideIDLType=IDLWebGLAny] any getRenderbufferParameter(GLenum target, GLenum pname);
+ [OverrideIDLType=IDLWebGLAny] any getShaderParameter(WebGLShader? shader, GLenum pname);
+
+ DOMString? getShaderInfoLog(WebGLShader? shader);
+
+ WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
+
+ DOMString? getShaderSource(WebGLShader? shader);
+
+ [OverrideIDLType=IDLWebGLAny] any getTexParameter(GLenum target, GLenum pname);
+
+ [OverrideIDLType=IDLWebGLAny] any getUniform(WebGLProgram? program, WebGLUniformLocation? location);
+
+ WebGLUniformLocation getUniformLocation(WebGLProgram? program, DOMString name);
+
+ [OverrideIDLType=IDLWebGLAny] any getVertexAttrib(GLuint index, GLenum pname);
+
+ GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
+
+ void hint(GLenum target, GLenum mode);
+ GLboolean isBuffer(WebGLBuffer? buffer);
+ GLboolean isContextLost();
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
+ GLboolean isProgram(WebGLProgram? program);
+ GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ GLboolean isShader(WebGLShader? shader);
+ GLboolean isTexture(WebGLTexture? texture);
+ void lineWidth(GLfloat width);
+ void linkProgram(WebGLProgram? program);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
+
+ void releaseShaderCompiler();
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void sampleCoverage(GLclampf value, GLboolean invert);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void shaderSource(WebGLShader? shader, DOMString string);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint mask);
+ 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 texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ // Supported forms:
+ void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
+ [MayThrowException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, TexImageSource? source);
+
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
+ [MayThrowException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource? source);
+
+ void uniform1f(WebGLUniformLocation? location, GLfloat x);
+ void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
+ void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
+ void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+ void uniform1i(WebGLUniformLocation? location, GLint x);
+ void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
+ void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
+ void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
+
+ void uniform1fv(WebGLUniformLocation? location, Float32List v);
+ void uniform2fv(WebGLUniformLocation? location, Float32List v);
+ void uniform3fv(WebGLUniformLocation? location, Float32List v);
+ void uniform4fv(WebGLUniformLocation? location, Float32List v);
+
+ void uniform1iv(WebGLUniformLocation? location, Int32List v);
+ void uniform2iv(WebGLUniformLocation? location, Int32List v);
+ void uniform3iv(WebGLUniformLocation? location, Int32List v);
+ void uniform4iv(WebGLUniformLocation? location, Int32List v);
+
+ void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List array);
+ void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List array);
+ void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List array);
+
+ void useProgram(WebGLProgram? program);
+ void validateProgram(WebGLProgram? program);
+
+ void vertexAttrib1f(GLuint index, GLfloat x);
+ void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+ void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+ void vertexAttrib1fv(GLuint index, Float32List values);
+ void vertexAttrib2fv(GLuint index, Float32List values);
+ void vertexAttrib3fv(GLuint index, Float32List values);
+ void vertexAttrib4fv(GLuint index, Float32List values);
+
+ void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
+
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+};
diff --git a/Source/WebCore/html/canvas/WebGLSampler.cpp b/Source/WebCore/html/canvas/WebGLSampler.cpp
new file mode 100644
index 000000000..0ca795b8b
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSampler.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "WebGLSampler.h"
+
+#include "WebGLContextGroup.h"
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+Ref<WebGLSampler> WebGLSampler::create(WebGLRenderingContextBase& ctx)
+{
+ return adoptRef(*new WebGLSampler(ctx));
+}
+
+WebGLSampler::~WebGLSampler()
+{
+ deleteObject(0);
+}
+
+WebGLSampler::WebGLSampler(WebGLRenderingContextBase& ctx)
+ : WebGLSharedObject(ctx)
+{
+ // FIXME: Call createSampler from GraphicsContext3D.
+}
+
+void WebGLSampler::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ UNUSED_PARAM(context3d);
+ UNUSED_PARAM(object);
+ // FIXME: Call deleteSampler from GraphicsContext3D.
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLSampler.h b/Source/WebCore/html/canvas/WebGLSampler.h
new file mode 100644
index 000000000..a0531ff27
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSampler.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#include "WebGLSharedObject.h"
+
+namespace WebCore {
+
+class WebGLSampler final : public WebGLSharedObject {
+public:
+ static Ref<WebGLSampler> create(WebGLRenderingContextBase&);
+ virtual ~WebGLSampler();
+
+protected:
+ explicit WebGLSampler(WebGLRenderingContextBase&);
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) final;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLSampler.idl b/Source/WebCore/html/canvas/WebGLSampler.idl
new file mode 100644
index 000000000..4e544ca6e
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSampler.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+[
+ Conditional=WEBGL
+] interface WebGLSampler {
+};
diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp
index 0f3315676..7faed2408 100644
--- a/Source/WebCore/html/canvas/WebGLShader.cpp
+++ b/Source/WebCore/html/canvas/WebGLShader.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -30,22 +30,22 @@
#include "WebGLShader.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type)
+Ref<WebGLShader> WebGLShader::create(WebGLRenderingContextBase& ctx, GC3Denum type)
{
- return adoptRef(new WebGLShader(ctx, type));
+ return adoptRef(*new WebGLShader(ctx, type));
}
-WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
+WebGLShader::WebGLShader(WebGLRenderingContextBase& ctx, GC3Denum type)
: WebGLSharedObject(ctx)
, m_type(type)
- , m_source("")
+ , m_source(emptyString())
, m_isValid(false)
{
- setObject(ctx->graphicsContext3D()->createShader(type));
+ setObject(ctx.graphicsContext3D()->createShader(type));
}
WebGLShader::~WebGLShader()
diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h
index 7ed00e321..952cdcc65 100644
--- a/Source/WebCore/html/canvas/WebGLShader.h
+++ b/Source/WebCore/html/canvas/WebGLShader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,21 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLShader_h
-#define WebGLShader_h
+#pragma once
#include "WebGLSharedObject.h"
-#include <wtf/PassRefPtr.h>
-
namespace WebCore {
-class WebGLShader : public WebGLSharedObject {
+class WebGLShader final : public WebGLSharedObject {
public:
+ static Ref<WebGLShader> create(WebGLRenderingContextBase&, GC3Denum);
virtual ~WebGLShader();
- static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
-
GC3Denum getType() const { return m_type; }
const String& getSource() const { return m_source; }
@@ -47,11 +43,9 @@ public:
void setValid(bool valid) { m_isValid = valid; }
private:
- WebGLShader(WebGLRenderingContext*, GC3Denum);
+ WebGLShader(WebGLRenderingContextBase&, GC3Denum);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
- virtual bool isShader() const override { return true; }
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) final;
GC3Denum m_type;
String m_source;
@@ -59,5 +53,3 @@ private:
};
} // namespace WebCore
-
-#endif // WebGLShader_h
diff --git a/Source/WebCore/html/canvas/WebGLShader.idl b/Source/WebCore/html/canvas/WebGLShader.idl
index 0ebae3829..52f962025 100644
--- a/Source/WebCore/html/canvas/WebGLShader.idl
+++ b/Source/WebCore/html/canvas/WebGLShader.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
index b9c5163a1..ed63a51cf 100644
--- a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
@@ -33,9 +33,9 @@
namespace WebCore {
// static
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+Ref<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
{
- return adoptRef(new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
+ return adoptRef(*new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
}
GC3Dint WebGLShaderPrecisionFormat::rangeMin() const
diff --git a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
index c4c7b7861..6ff2dd467 100644
--- a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
+++ b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
@@ -24,18 +24,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLShaderPrecisionFormat_h
-#define WebGLShaderPrecisionFormat_h
+#pragma once
#include "GraphicsContext3D.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class WebGLShaderPrecisionFormat : public RefCounted<WebGLShaderPrecisionFormat> {
public:
- static PassRefPtr<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ static Ref<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
GC3Dint rangeMin() const;
GC3Dint rangeMax() const;
@@ -49,6 +47,4 @@ private:
GC3Dint m_precision;
};
-}
-
-#endif // WebGLShaderPrecisionFormat_h
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.cpp b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
index 9f76cae77..1b2236fbd 100644
--- a/Source/WebCore/html/canvas/WebGLSharedObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,41 +24,39 @@
*/
#include "config.h"
+#include "WebGLSharedObject.h"
#if ENABLE(WEBGL)
-#include "WebGLSharedObject.h"
-
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
- : WebGLObject(context),
- m_contextGroup(context->contextGroup())
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContextBase& context)
+ : m_contextGroup(context.contextGroup())
{
}
WebGLSharedObject::~WebGLSharedObject()
{
if (m_contextGroup)
- m_contextGroup->removeObject(this);
+ m_contextGroup->removeObject(*this);
}
void WebGLSharedObject::detachContextGroup()
{
detach();
if (m_contextGroup) {
- deleteObject(0);
- m_contextGroup->removeObject(this);
- m_contextGroup = 0;
+ deleteObject(nullptr);
+ m_contextGroup->removeObject(*this);
+ m_contextGroup = nullptr;
}
}
GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
{
- return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
+ return m_contextGroup ? &m_contextGroup->getAGraphicsContext3D() : nullptr;
}
}
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.h b/Source/WebCore/html/canvas/WebGLSharedObject.h
index a55f64871..972e580ee 100644
--- a/Source/WebCore/html/canvas/WebGLSharedObject.h
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLSharedObject_h
-#define WebGLSharedObject_h
+#pragma once
#include "WebGLObject.h"
@@ -32,24 +31,19 @@ namespace WebCore {
class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-// WebGLSharedObject the base class for objects that can be shared by multiple
-// WebGLRenderingContexts.
+// WebGLSharedObject the base class for objects that can be shared by multiple WebGLRenderingContexts.
class WebGLSharedObject : public WebGLObject {
public:
virtual ~WebGLSharedObject();
WebGLContextGroup* contextGroup() const { return m_contextGroup; }
- virtual bool isBuffer() const { return false; }
- virtual bool isFramebuffer() const { return false; }
- virtual bool isProgram() const { return false; }
virtual bool isRenderbuffer() const { return false; }
- virtual bool isShader() const { return false; }
virtual bool isTexture() const { return false; }
- virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const override
+ bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContextBase&) const override
{
return contextGroup == m_contextGroup;
}
@@ -57,19 +51,17 @@ public:
void detachContextGroup();
protected:
- WebGLSharedObject(WebGLRenderingContext*);
+ WebGLSharedObject(WebGLRenderingContextBase&);
- virtual bool hasGroupOrContext() const override
+ bool hasGroupOrContext() const override
{
return m_contextGroup;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const override;
+ GraphicsContext3D* getAGraphicsContext3D() const override;
private:
WebGLContextGroup* m_contextGroup;
};
} // namespace WebCore
-
-#endif // WebGLSharedObject_h
diff --git a/Source/WebCore/html/canvas/WebGLSync.cpp b/Source/WebCore/html/canvas/WebGLSync.cpp
new file mode 100644
index 000000000..6360fba4e
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSync.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "WebGLSync.h"
+
+#include "WebGLContextGroup.h"
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+Ref<WebGLSync> WebGLSync::create(WebGLRenderingContextBase& ctx)
+{
+ return adoptRef(*new WebGLSync(ctx));
+}
+
+WebGLSync::~WebGLSync()
+{
+ deleteObject(0);
+}
+
+WebGLSync::WebGLSync(WebGLRenderingContextBase& ctx)
+ : WebGLSharedObject(ctx)
+{
+ // FIXME: Call fenceSync from GraphicsContext3D.
+}
+
+void WebGLSync::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ UNUSED_PARAM(context3d);
+ UNUSED_PARAM(object);
+ // FIXME: Call deleteSync from GraphicsContext3D.
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLSync.h b/Source/WebCore/html/canvas/WebGLSync.h
new file mode 100644
index 000000000..f9e718017
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSync.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#include "WebGLSharedObject.h"
+
+namespace WebCore {
+
+class WebGLSync final : public WebGLSharedObject {
+public:
+ virtual ~WebGLSync();
+
+ static Ref<WebGLSync> create(WebGLRenderingContextBase&);
+
+protected:
+ WebGLSync(WebGLRenderingContextBase&);
+
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLSync.idl b/Source/WebCore/html/canvas/WebGLSync.idl
new file mode 100644
index 000000000..e1a994758
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSync.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+[
+ Conditional=WEBGL
+] interface WebGLSync {
+};
diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp
index 0872795ff..9eba972f5 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.cpp
+++ b/Source/WebCore/html/canvas/WebGLTexture.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -31,16 +31,16 @@
#include "WebGLContextGroup.h"
#include "WebGLFramebuffer.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+Ref<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLTexture(ctx));
+ return adoptRef(*new WebGLTexture(ctx));
}
-WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+WebGLTexture::WebGLTexture(WebGLRenderingContextBase& ctx)
: WebGLSharedObject(ctx)
, m_target(0)
, m_minFilter(GraphicsContext3D::NEAREST_MIPMAP_LINEAR)
@@ -53,8 +53,9 @@ WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
, m_isCompressed(false)
, m_isFloatType(false)
, m_isHalfFloatType(false)
+ , m_isForWebGL1(ctx.isWebGL1())
{
- setObject(ctx->graphicsContext3D()->createTexture());
+ setObject(ctx.graphicsContext3D()->createTexture());
}
WebGLTexture::~WebGLTexture()
@@ -188,6 +189,7 @@ GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
{
+ ASSERT(m_isForWebGL1);
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
@@ -218,6 +220,15 @@ bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
return info->valid;
}
+void WebGLTexture::markInvalid(GC3Denum target, GC3Dint level)
+{
+ int index = mapTargetToIndex(target);
+ if (index < 0)
+ return;
+ m_info[index][level].valid = false;
+ update();
+}
+
bool WebGLTexture::isNPOT(GC3Dsizei width, GC3Dsizei height)
{
ASSERT(width >= 0 && height >= 0);
@@ -241,10 +252,12 @@ bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag extensions) const
return false;
if (m_needToUseBlackTexture)
return true;
- if ((m_isFloatType && !(extensions & TextureExtensionFloatLinearEnabled)) || (m_isHalfFloatType && !(extensions & TextureExtensionHalfFloatLinearEnabled))) {
- if (m_magFilter != GraphicsContext3D::NEAREST || (m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::NEAREST_MIPMAP_NEAREST))
- return true;
- }
+ if (m_magFilter == GraphicsContext3D::NEAREST && (m_minFilter == GraphicsContext3D::NEAREST || m_minFilter == GraphicsContext3D::NEAREST_MIPMAP_NEAREST))
+ return false;
+ if (m_isForWebGL1 && m_isHalfFloatType && !(extensions & TextureExtensionHalfFloatLinearEnabled))
+ return true;
+ if (m_isFloatType && !(extensions & TextureExtensionFloatLinearEnabled))
+ return true;
return false;
}
@@ -299,7 +312,7 @@ bool WebGLTexture::canGenerateMipmaps()
const LevelInfo& info = m_info[ii][0];
if (!info.valid
|| info.width != first.width || info.height != first.height
- || info.internalFormat != first.internalFormat || info.type != first.type)
+ || info.internalFormat != first.internalFormat || (m_isForWebGL1 && info.type != first.type))
return false;
}
return true;
@@ -325,6 +338,36 @@ GC3Dint WebGLTexture::computeLevelCount(GC3Dsizei width, GC3Dsizei height)
return log + 1;
}
+static bool internalFormatIsFloatType(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool internalFormatIsHalfFloatType(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGBA16F:
+ return true;
+ default:
+ return false;
+ }
+}
+
void WebGLTexture::update()
{
m_isNPOT = false;
@@ -344,7 +387,7 @@ void WebGLTexture::update()
const LevelInfo& info0 = m_info[ii][0];
if (!info0.valid
|| info0.width != first.width || info0.height != first.height
- || info0.internalFormat != first.internalFormat || info0.type != first.type) {
+ || info0.internalFormat != first.internalFormat || (m_isForWebGL1 && info0.type != first.type)) {
m_isComplete = false;
break;
}
@@ -356,7 +399,7 @@ void WebGLTexture::update()
const LevelInfo& info = m_info[ii][level];
if (!info.valid
|| info.width != width || info.height != height
- || info.internalFormat != info0.internalFormat || info.type != info0.type) {
+ || info.internalFormat != info0.internalFormat || (m_isForWebGL1 && info.type != info0.type)) {
m_isComplete = false;
break;
}
@@ -366,25 +409,37 @@ void WebGLTexture::update()
}
m_isFloatType = false;
- if (m_isComplete)
- m_isFloatType = m_info[0][0].type == GraphicsContext3D::FLOAT;
- else {
- for (size_t ii = 0; ii < m_info.size(); ++ii) {
- if (m_info[ii][0].type == GraphicsContext3D::FLOAT) {
- m_isFloatType = true;
- break;
+ if (m_isForWebGL1) {
+ if (m_isComplete) {
+ if (m_isForWebGL1)
+ m_isFloatType = m_info[0][0].type == GraphicsContext3D::FLOAT;
+ else
+ m_isFloatType = internalFormatIsFloatType(m_info[0][0].internalFormat);
+ } else {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if ((m_isForWebGL1 && m_info[ii][0].type == GraphicsContext3D::FLOAT)
+ || (!m_isForWebGL1 && internalFormatIsFloatType(m_info[ii][0].internalFormat))) {
+ m_isFloatType = true;
+ break;
+ }
}
}
}
m_isHalfFloatType = false;
- if (m_isComplete)
- m_isHalfFloatType = m_info[0][0].type == GraphicsContext3D::HALF_FLOAT_OES;
- else {
- for (size_t ii = 0; ii < m_info.size(); ++ii) {
- if (m_info[ii][0].type == GraphicsContext3D::HALF_FLOAT_OES) {
- m_isHalfFloatType = true;
- break;
+ if (m_isForWebGL1) {
+ if (m_isComplete) {
+ if (m_isForWebGL1)
+ m_isHalfFloatType = internalFormatIsHalfFloatType(m_info[0][0].internalFormat);
+ else
+ m_isHalfFloatType = m_info[0][0].type == GraphicsContext3D::HALF_FLOAT_OES;
+ } else {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if ((m_isForWebGL1 && m_info[ii][0].type == GraphicsContext3D::HALF_FLOAT_OES)
+ || (!m_isForWebGL1 && internalFormatIsHalfFloatType(m_info[ii][0].internalFormat))) {
+ m_isHalfFloatType = true;
+ break;
+ }
}
}
}
diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h
index dcc3d0b45..b266953a5 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.h
+++ b/Source/WebCore/html/canvas/WebGLTexture.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,17 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLTexture_h
-#define WebGLTexture_h
+#pragma once
#include "WebGLSharedObject.h"
-
-#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
-class WebGLTexture : public WebGLSharedObject {
+class WebGLTexture final : public WebGLSharedObject {
public:
enum TextureExtensionFlag {
@@ -44,7 +41,7 @@ public:
virtual ~WebGLTexture();
- static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+ static Ref<WebGLTexture> create(WebGLRenderingContextBase&);
void setTarget(GC3Denum target, GC3Dint maxLevel);
void setParameteri(GC3Denum pname, GC3Dint param);
@@ -65,6 +62,7 @@ public:
GC3Dsizei getWidth(GC3Denum target, GC3Dint level) const;
GC3Dsizei getHeight(GC3Denum target, GC3Dint level) const;
bool isValid(GC3Denum target, GC3Dint level) const;
+ void markInvalid(GC3Denum target, GC3Dint level);
// Whether width/height is NotPowerOfTwo.
static bool isNPOT(GC3Dsizei, GC3Dsizei);
@@ -80,12 +78,14 @@ public:
static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
-protected:
- WebGLTexture(WebGLRenderingContext*);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+ bool immutable() const { return m_immutable; }
+ void setImmutable() { m_immutable = true; }
private:
+ WebGLTexture(WebGLRenderingContextBase&);
+
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+
class LevelInfo {
public:
LevelInfo()
@@ -113,7 +113,7 @@ private:
GC3Denum type;
};
- virtual bool isTexture() const override { return true; }
+ bool isTexture() const override { return true; }
void update();
@@ -136,8 +136,8 @@ private:
bool m_isCompressed;
bool m_isFloatType;
bool m_isHalfFloatType;
+ bool m_isForWebGL1;
+ bool m_immutable { false };
};
} // namespace WebCore
-
-#endif // WebGLTexture_h
diff --git a/Source/WebCore/html/canvas/WebGLTexture.idl b/Source/WebCore/html/canvas/WebGLTexture.idl
index 1ea2f2bca..67dfa3c4f 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.idl
+++ b/Source/WebCore/html/canvas/WebGLTexture.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp b/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp
new file mode 100644
index 000000000..353e4bac1
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "WebGLTransformFeedback.h"
+
+#include "WebGLContextGroup.h"
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+Ref<WebGLTransformFeedback> WebGLTransformFeedback::create(WebGLRenderingContextBase& ctx)
+{
+ return adoptRef(*new WebGLTransformFeedback(ctx));
+}
+
+WebGLTransformFeedback::~WebGLTransformFeedback()
+{
+ deleteObject(0);
+}
+
+WebGLTransformFeedback::WebGLTransformFeedback(WebGLRenderingContextBase& ctx)
+ : WebGLSharedObject(ctx)
+{
+ // FIXME: Call createTransformFeedback from GraphicsContext3D.
+}
+
+void WebGLTransformFeedback::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ UNUSED_PARAM(context3d);
+ UNUSED_PARAM(object);
+ // FIXME: Call deleteTransformFeedback from GraphicsContext3D.
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.h b/Source/WebCore/html/canvas/WebGLTransformFeedback.h
new file mode 100644
index 000000000..714923384
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTransformFeedback.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#include "WebGLSharedObject.h"
+
+namespace WebCore {
+
+class WebGLTransformFeedback final : public WebGLSharedObject {
+public:
+ virtual ~WebGLTransformFeedback();
+
+ static Ref<WebGLTransformFeedback> create(WebGLRenderingContextBase&);
+
+protected:
+ WebGLTransformFeedback(WebGLRenderingContextBase&);
+
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.idl b/Source/WebCore/html/canvas/WebGLTransformFeedback.idl
new file mode 100644
index 000000000..22b8847ed
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTransformFeedback.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+[
+ Conditional=WEBGL
+] interface WebGLTransformFeedback {
+};
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
index b467238b4..f16cae3c1 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -32,9 +32,9 @@
namespace WebCore {
-PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location, GC3Denum type)
+Ref<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location, GC3Denum type)
{
- return adoptRef(new WebGLUniformLocation(program, location, type));
+ return adoptRef(*new WebGLUniformLocation(program, location, type));
}
WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GC3Dint location, GC3Denum type)
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.h b/Source/WebCore/html/canvas/WebGLUniformLocation.h
index a268fa2fa..5130be0dd 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.h
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.h
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,21 +24,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLUniformLocation_h
-#define WebGLUniformLocation_h
+#pragma once
#include "WebGLProgram.h"
-
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLUniformLocation : public RefCounted<WebGLUniformLocation> {
+class WebGLUniformLocation final : public RefCounted<WebGLUniformLocation> {
public:
- virtual ~WebGLUniformLocation() { }
+ ~WebGLUniformLocation() { }
- static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location, GC3Denum type);
+ static Ref<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location, GC3Denum type);
WebGLProgram* program() const;
@@ -57,5 +54,3 @@ private:
};
} // namespace WebCore
-
-#endif // WebGLUniformLocation_h
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.idl b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
index c211189de..a086f5713 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.idl
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -25,6 +25,7 @@
*/
[
- Conditional=WEBGL
+ Conditional=WEBGL,
+ ImplementationLacksVTable,
] interface WebGLUniformLocation {
};
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp
new file mode 100644
index 000000000..89ae21f33
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#include "config.h"
+#include "WebGLVertexArrayObject.h"
+
+#if ENABLE(WEBGL2)
+
+#include "WebGL2RenderingContext.h"
+#include "WebGLContextGroup.h"
+
+namespace WebCore {
+
+Ref<WebGLVertexArrayObject> WebGLVertexArrayObject::create(WebGLRenderingContextBase& context, Type type)
+{
+ return adoptRef(*new WebGLVertexArrayObject(context, type));
+}
+
+WebGLVertexArrayObject::~WebGLVertexArrayObject()
+{
+ deleteObject(nullptr);
+}
+
+WebGLVertexArrayObject::WebGLVertexArrayObject(WebGLRenderingContextBase& context, Type type)
+ : WebGLVertexArrayObjectBase(context, type)
+{
+ switch (m_type) {
+ case Type::Default:
+ break;
+ case Type::User:
+ setObject(this->context()->graphicsContext3D()->createVertexArray());
+ break;
+ }
+}
+
+void WebGLVertexArrayObject::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ switch (m_type) {
+ case Type::Default:
+ break;
+ case Type::User:
+ context3d->deleteVertexArray(object);
+ break;
+ }
+
+ if (m_boundElementArrayBuffer)
+ m_boundElementArrayBuffer->onDetached(context3d);
+
+ for (auto& state : m_vertexAttribState) {
+ if (state.bufferBinding)
+ state.bufferBinding->onDetached(context3d);
+ }
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.h b/Source/WebCore/html/canvas/WebGLVertexArrayObject.h
new file mode 100644
index 000000000..2f7ed3508
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObject.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGL2)
+
+#include "WebGLVertexArrayObjectBase.h"
+
+namespace WebCore {
+
+class WebGL2RenderingContext;
+
+class WebGLVertexArrayObject final : public WebGLVertexArrayObjectBase {
+public:
+ static Ref<WebGLVertexArrayObject> create(WebGLRenderingContextBase&, Type);
+ virtual ~WebGLVertexArrayObject();
+private:
+ WebGLVertexArrayObject(WebGLRenderingContextBase&, Type);
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL2)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl b/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl
new file mode 100644
index 000000000..67a1f9dec
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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 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 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.
+ */
+
+[
+ Conditional=WEBGL2,
+ EnabledAtRuntime=WebGL2
+] interface WebGLVertexArrayObject {
+};
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp
new file mode 100644
index 000000000..58dfa3d73
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#include "config.h"
+#include "WebGLVertexArrayObjectBase.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+WebGLVertexArrayObjectBase::WebGLVertexArrayObjectBase(WebGLRenderingContextBase& context, Type type)
+ : WebGLContextObject(context)
+ , m_type(type)
+{
+ m_vertexAttribState.resize(context.getMaxVertexAttribs());
+}
+
+void WebGLVertexArrayObjectBase::setElementArrayBuffer(WebGLBuffer* buffer)
+{
+ if (buffer)
+ buffer->onAttached();
+ if (m_boundElementArrayBuffer)
+ m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer = buffer;
+
+}
+
+void WebGLVertexArrayObjectBase::setVertexAttribState(GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, WebGLBuffer& buffer)
+{
+ GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
+
+ auto& state = m_vertexAttribState[index];
+
+ buffer.onAttached();
+ if (state.bufferBinding)
+ state.bufferBinding->onDetached(context()->graphicsContext3D());
+
+ state.bufferBinding = &buffer;
+ state.bytesPerElement = bytesPerElement;
+ state.size = size;
+ state.type = type;
+ state.normalized = normalized;
+ state.stride = validatedStride;
+ state.originalStride = stride;
+ state.offset = offset;
+}
+
+void WebGLVertexArrayObjectBase::unbindBuffer(WebGLBuffer& buffer)
+{
+ if (m_boundElementArrayBuffer == &buffer) {
+ m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer = nullptr;
+ }
+
+ for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
+ auto& state = m_vertexAttribState[i];
+ if (state.bufferBinding == &buffer) {
+ buffer.onDetached(context()->graphicsContext3D());
+
+ if (!i && !context()->isGLES2Compliant()) {
+ state.bufferBinding = context()->m_vertexAttrib0Buffer;
+ state.bufferBinding->onAttached();
+ state.bytesPerElement = 0;
+ state.size = 4;
+ state.type = GraphicsContext3D::FLOAT;
+ state.normalized = false;
+ state.stride = 16;
+ state.originalStride = 0;
+ state.offset = 0;
+ } else
+ state.bufferBinding = nullptr;
+ }
+ }
+}
+
+void WebGLVertexArrayObjectBase::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ m_vertexAttribState[index].divisor = divisor;
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h
new file mode 100644
index 000000000..1275533d8
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015-2017 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 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 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.
+ */
+
+#pragma once
+
+#include "WebGLBuffer.h"
+#include "WebGLContextObject.h"
+
+namespace WebCore {
+
+class WebGLVertexArrayObjectBase : public WebGLContextObject {
+public:
+ enum class Type { Default, User };
+
+ // Cached values for vertex attrib range checks
+ struct VertexAttribState {
+ bool isBound() const { return bufferBinding && bufferBinding->object(); }
+ bool validateBinding() const { return !enabled || isBound(); }
+
+ bool enabled { false };
+ RefPtr<WebGLBuffer> bufferBinding;
+ GC3Dsizei bytesPerElement { 0 };
+ GC3Dint size { 4 };
+ GC3Denum type { GraphicsContext3D::FLOAT };
+ bool normalized { false };
+ GC3Dsizei stride { 16 };
+ GC3Dsizei originalStride { 0 };
+ GC3Dintptr offset { 0 };
+ GC3Duint divisor { 0 };
+ };
+
+ bool isDefaultObject() const { return m_type == Type::Default; }
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+ WebGLBuffer* getElementArrayBuffer() const { return m_boundElementArrayBuffer.get(); }
+ void setElementArrayBuffer(WebGLBuffer*);
+
+ VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
+ void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, WebGLBuffer&);
+ void unbindBuffer(WebGLBuffer&);
+
+ void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+
+protected:
+ WebGLVertexArrayObjectBase(WebGLRenderingContextBase&, Type);
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override = 0;
+
+ Type m_type;
+ bool m_hasEverBeenBound { false };
+ RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
+ Vector<VertexAttribState> m_vertexAttribState;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
index ce18a9f18..af5565cd9 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -30,125 +30,50 @@
#include "WebGLVertexArrayObjectOES.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
+Ref<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContextBase& context, Type type)
{
- return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
+ return adoptRef(*new WebGLVertexArrayObjectOES(context, type));
}
-WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
- : WebGLContextObject(ctx)
- , m_type(type)
- , m_hasEverBeenBound(false)
- , m_boundElementArrayBuffer(0)
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase& context, Type type)
+ : WebGLVertexArrayObjectBase(context, type)
{
- m_vertexAttribState.resize(ctx->getMaxVertexAttribs());
-
- Extensions3D* extensions = context()->graphicsContext3D()->getExtensions();
- switch (m_type) {
- case VaoTypeDefault:
+ switch (type) {
+ case Type::Default:
break;
- default:
- setObject(extensions->createVertexArrayOES());
+ case Type::User:
+ setObject(this->context()->graphicsContext3D()->getExtensions().createVertexArrayOES());
break;
}
}
WebGLVertexArrayObjectOES::~WebGLVertexArrayObjectOES()
{
- deleteObject(0);
+ deleteObject(nullptr);
}
void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- Extensions3D* extensions = context3d->getExtensions();
switch (m_type) {
- case VaoTypeDefault:
+ case Type::Default:
break;
- default:
- extensions->deleteVertexArrayOES(object);
+ case Type::User:
+ context3d->getExtensions().deleteVertexArrayOES(object);
break;
}
if (m_boundElementArrayBuffer)
m_boundElementArrayBuffer->onDetached(context3d);
- for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
- VertexAttribState& state = m_vertexAttribState[i];
+ for (auto& state : m_vertexAttribState) {
if (state.bufferBinding)
state.bufferBinding->onDetached(context3d);
}
}
-
-void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> buffer)
-{
- if (buffer)
- buffer->onAttached();
- if (m_boundElementArrayBuffer)
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = buffer;
-
-}
-
-void WebGLVertexArrayObjectOES::setVertexAttribState(
- GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, PassRefPtr<WebGLBuffer> buffer)
-{
- GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
-
- VertexAttribState& state = m_vertexAttribState[index];
-
- if (buffer)
- buffer->onAttached();
- if (state.bufferBinding)
- state.bufferBinding->onDetached(context()->graphicsContext3D());
-
- state.bufferBinding = buffer;
- state.bytesPerElement = bytesPerElement;
- state.size = size;
- state.type = type;
- state.normalized = normalized;
- state.stride = validatedStride;
- state.originalStride = stride;
- state.offset = offset;
-}
-
-void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
-{
- if (m_boundElementArrayBuffer == buffer) {
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = 0;
- }
-
- for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
- VertexAttribState& state = m_vertexAttribState[i];
- if (state.bufferBinding == buffer) {
- buffer->onDetached(context()->graphicsContext3D());
-
- if (!i && !context()->isGLES2Compliant()) {
- state.bufferBinding = context()->m_vertexAttrib0Buffer;
- state.bufferBinding->onAttached();
- state.bytesPerElement = 0;
- state.size = 4;
- state.type = GraphicsContext3D::FLOAT;
- state.normalized = false;
- state.stride = 16;
- state.originalStride = 0;
- state.offset = 0;
- } else
- state.bufferBinding = 0;
- }
- }
-}
-
-void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- VertexAttribState& state = m_vertexAttribState[index];
- state.divisor = divisor;
-}
-
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
index 8853ff926..f9a2a58ec 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,84 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLVertexArrayObjectOES_h
-#define WebGLVertexArrayObjectOES_h
+#pragma once
-#include "WebGLBuffer.h"
-#include "WebGLContextObject.h"
-
-#include <wtf/PassRefPtr.h>
+#include "WebGLVertexArrayObjectBase.h"
namespace WebCore {
-class WebGLVertexArrayObjectOES : public WebGLContextObject {
+class WebGLVertexArrayObjectOES final : public WebGLVertexArrayObjectBase {
public:
- enum VaoType {
- VaoTypeDefault,
- VaoTypeUser,
- };
-
+ static Ref<WebGLVertexArrayObjectOES> create(WebGLRenderingContextBase&, Type);
virtual ~WebGLVertexArrayObjectOES();
-
- static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
-
- // Cached values for vertex attrib range checks
- struct VertexAttribState {
- VertexAttribState()
- : enabled(false)
- , bytesPerElement(0)
- , size(4)
- , type(GraphicsContext3D::FLOAT)
- , normalized(false)
- , stride(16)
- , originalStride(0)
- , offset(0)
- , divisor(0)
- {
- }
-
- bool isBound() const { return bufferBinding && bufferBinding->object(); }
- bool validateBinding() const { return !enabled || isBound(); }
-
- bool enabled;
- RefPtr<WebGLBuffer> bufferBinding;
- GC3Dsizei bytesPerElement;
- GC3Dint size;
- GC3Denum type;
- bool normalized;
- GC3Dsizei stride;
- GC3Dsizei originalStride;
- GC3Dintptr offset;
- GC3Duint divisor;
- };
-
- bool isDefaultObject() const { return m_type == VaoTypeDefault; }
-
- bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
- void setHasEverBeenBound() { m_hasEverBeenBound = true; }
-
- PassRefPtr<WebGLBuffer> getElementArrayBuffer() const { return m_boundElementArrayBuffer; }
- void setElementArrayBuffer(PassRefPtr<WebGLBuffer>);
-
- VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
- void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, PassRefPtr<WebGLBuffer>);
- void unbindBuffer(PassRefPtr<WebGLBuffer>);
-
- void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
-
private:
- WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
- virtual bool isVertexArray() const { return true; }
-
- VaoType m_type;
- bool m_hasEverBeenBound;
- RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
- Vector<VertexAttribState> m_vertexAttribState;
+ WebGLVertexArrayObjectOES(WebGLRenderingContextBase&, Type);
+ void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) final;
};
} // namespace WebCore
-
-#endif // WebGLVertexArrayObjectOES_h
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
index ce9f18d5f..f190a7e64 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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