summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/canvas
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebCore/html/canvas
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebCore/html/canvas')
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.idl37
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.idl36
-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.cpp74
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.h72
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.idl40
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.cpp66
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.h62
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.idl36
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.cpp54
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.h78
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.idl42
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp111
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h86
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.idl40
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp2252
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h323
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.idl229
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp304
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.h106
-rw-r--r--Source/WebCore/html/canvas/CheckedInt.h588
-rwxr-xr-xSource/WebCore/html/canvas/DataView.cpp245
-rw-r--r--Source/WebCore/html/canvas/DataView.h97
-rwxr-xr-xSource/WebCore/html/canvas/DataView.idl80
-rw-r--r--Source/WebCore/html/canvas/Float32Array.idl47
-rw-r--r--Source/WebCore/html/canvas/Float64Array.idl47
-rw-r--r--Source/WebCore/html/canvas/Int16Array.idl46
-rw-r--r--Source/WebCore/html/canvas/Int32Array.idl47
-rw-r--r--Source/WebCore/html/canvas/Int8Array.idl47
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.cpp55
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.h47
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.idl35
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.cpp55
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.h47
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.idl33
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.cpp115
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.h60
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.idl40
-rw-r--r--Source/WebCore/html/canvas/Uint16Array.idl46
-rw-r--r--Source/WebCore/html/canvas/Uint32Array.idl46
-rw-r--r--Source/WebCore/html/canvas/Uint8Array.idl46
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.h63
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.idl36
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp210
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.h105
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextures.cpp299
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextures.h75
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextures.idl46
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.cpp127
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.h87
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.idl39
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.cpp62
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.h69
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.idl35
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp57
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl36
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.cpp71
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.h53
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.idl34
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.cpp45
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.h60
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp497
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h107
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp245
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.h138
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.cpp67
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.idl35
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp81
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h92
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp160
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h89
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.cpp60
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.h85
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp5087
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h651
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl672
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.cpp56
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.h60
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.cpp356
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.h130
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.idl31
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.cpp67
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.h59
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.idl32
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp74
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h98
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl31
95 files changed, 16934 insertions, 0 deletions
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.idl b/Source/WebCore/html/canvas/ArrayBuffer.idl
new file mode 100644
index 000000000..9ba85ca2e
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBuffer.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ GenerateIsReachable=Impl,
+ CustomConstructor,
+ NoStaticTables
+ ] ArrayBuffer {
+ readonly attribute int byteLength;
+ ArrayBuffer slice(in long begin, in [Optional] long end);
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.idl b/Source/WebCore/html/canvas/ArrayBufferView.idl
new file mode 100644
index 000000000..0e3d76540
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBufferView.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomToJS,
+ NoStaticTables,
+ OmitConstructor
+ ] ArrayBufferView {
+ readonly attribute ArrayBuffer buffer;
+ readonly attribute unsigned long byteOffset;
+ readonly attribute unsigned long byteLength;
+ };
+}
diff --git a/Source/WebCore/html/canvas/CanvasContextAttributes.cpp b/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
new file mode 100644
index 000000000..d3d0398af
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644
index 000000000..97483b366
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasContextAttributes.h
@@ -0,0 +1,48 @@
+/*
+ * 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
new file mode 100644
index 000000000..8a7ace0cf
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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)
+{
+ if (!(value >= 0 && value <= 1.0f)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ RGBA32 rgba = 0;
+ if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (!m_dashbardCompatibilityMode)
+ ec = SYNTAX_ERR;
+#else
+ ec = SYNTAX_ERR;
+#endif
+ return;
+ }
+
+ m_gradient->addColorStop(value, Color(rgba));
+}
+
+} // namespace
diff --git a/Source/WebCore/html/canvas/CanvasGradient.h b/Source/WebCore/html/canvas/CanvasGradient.h
new file mode 100644
index 000000000..1ff9c6559
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasGradient_h
+#define CanvasGradient_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 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(); }
+
+ void addColorStop(float value, const String& color, ExceptionCode&);
+
+ void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient->getColor(value, r, g, b, a); }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ void setDashboardCompatibilityMode() { m_dashbardCompatibilityMode = 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;
+#if ENABLE(DASHBOARD_SUPPORT)
+ bool m_dashbardCompatibilityMode;
+#endif
+ };
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasGradient.idl b/Source/WebCore/html/canvas/CanvasGradient.idl
new file mode 100644
index 000000000..48f75bbda
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=bb1108ea-6b8c-4a08-894a-218628630cdb,
+ ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1
+ ] CanvasGradient {
+
+ void addColorStop(in [Optional=CallWithDefaultValue] float offset,
+ in [Optional=CallWithDefaultValue] DOMString color)
+ raises (DOMException);
+
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasPattern.cpp b/Source/WebCore/html/canvas/CanvasPattern.cpp
new file mode 100644
index 000000000..818d7d3b7
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasPattern.h"
+
+#include "ExceptionCode.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& repeatY, ExceptionCode& ec)
+{
+ ec = 0;
+ if (type.isEmpty() || type == "repeat") {
+ repeatX = true;
+ repeatY = true;
+ return;
+ }
+ if (type == "no-repeat") {
+ repeatX = false;
+ repeatY = false;
+ return;
+ }
+ if (type == "repeat-x") {
+ repeatX = true;
+ repeatY = false;
+ return;
+ }
+ if (type == "repeat-y") {
+ repeatX = false;
+ repeatY = true;
+ return;
+ }
+ ec = SYNTAX_ERR;
+}
+
+CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+ : m_pattern(Pattern::create(image, repeatX, repeatY))
+ , m_originClean(originClean)
+{
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasPattern.h b/Source/WebCore/html/canvas/CanvasPattern.h
new file mode 100644
index 000000000..58848a992
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasPattern_h
+#define CanvasPattern_h
+
+#include "Pattern.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class Image;
+
+ typedef int ExceptionCode;
+
+ class CanvasPattern : public RefCounted<CanvasPattern> {
+ public:
+ static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
+
+ static PassRefPtr<CanvasPattern> create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+ {
+ return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
+ }
+
+ Pattern* pattern() const { return m_pattern.get(); }
+
+ bool originClean() const { return m_originClean; }
+
+ private:
+ CanvasPattern(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
+
+ RefPtr<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
new file mode 100644
index 000000000..1cac8f880
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=c2131348-6d8c-47b5-86cc-d41aff34ce15,
+ ImplementationUUID=82f5d713-3d17-44dd-aa4a-7766fe345940
+ ] CanvasPattern {
+
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.cpp b/Source/WebCore/html/canvas/CanvasPixelArray.cpp
new file mode 100644
index 000000000..65ac7ecf0
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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"
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(unsigned length)
+{
+ return adoptRef(new CanvasPixelArray(length));
+}
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(PassRefPtr<ByteArray> byteArray)
+{
+ return adoptRef(new CanvasPixelArray(byteArray));
+}
+
+CanvasPixelArray::CanvasPixelArray(unsigned length)
+ : m_data(ByteArray::create(length))
+{
+}
+
+CanvasPixelArray::CanvasPixelArray(PassRefPtr<ByteArray> byteArray)
+ : m_data(byteArray)
+{
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.h b/Source/WebCore/html/canvas/CanvasPixelArray.h
new file mode 100644
index 000000000..7a94b1fe7
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#ifndef CanvasPixelArray_h
+#define CanvasPixelArray_h
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CanvasPixelArray : public RefCounted<CanvasPixelArray> {
+public:
+ static PassRefPtr<CanvasPixelArray> create(unsigned length);
+ static PassRefPtr<CanvasPixelArray> create(PassRefPtr<ByteArray>);
+
+ ByteArray* data() { return m_data.get(); }
+ const ByteArray* data() const { return m_data.get(); }
+ unsigned length() const { return m_data->length(); }
+
+ void set(unsigned index, double value)
+ {
+ m_data->set(index, value);
+ }
+
+ void set(unsigned index, unsigned char value)
+ {
+ m_data->set(index, value);
+ }
+
+ bool get(unsigned index, unsigned char& result) const
+ {
+ return m_data->get(index, result);
+ }
+
+ unsigned char get(unsigned index) const
+ {
+ return m_data->get(index);
+ }
+
+private:
+ CanvasPixelArray(unsigned length);
+ CanvasPixelArray(PassRefPtr<ByteArray>);
+
+ RefPtr<ByteArray> m_data;
+};
+
+} // namespace WebCore
+
+#endif // CanvasPixelArray_h
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.idl b/Source/WebCore/html/canvas/CanvasPixelArray.idl
new file mode 100644
index 000000000..8b7edbd5d
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+module html {
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT || defined(V8_BINDING) && V8_BINDING
+ interface [
+ OmitConstructor,
+ CustomHeader,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter
+ ] CanvasPixelArray {
+#if !defined(V8_BINDING) || !V8_BINDING
+ readonly attribute long length;
+#endif
+ };
+#endif
+}
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
new file mode 100644
index 000000000..b3f387eb7
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasRenderingContext.h"
+
+#include "CachedImage.h"
+#include "CanvasPattern.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "KURL.h"
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
+ : m_canvas(canvas)
+{
+}
+
+bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
+{
+ if (canvas()->originClean() && pattern && !pattern->originClean())
+ return true;
+ return false;
+}
+
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
+{
+ if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
+ return true;
+ return false;
+}
+
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
+{
+ if (!image || !canvas()->originClean())
+ return false;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return true;
+
+ return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
+}
+
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
+{
+#if ENABLE(VIDEO)
+ // FIXME: This check is likely wrong when a redirect is involved. We need
+ // 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())
+ return false;
+
+ if (wouldTaintOrigin(video->currentSrc()))
+ return true;
+
+ if (!video->hasSingleSecurityOrigin())
+ return true;
+#endif
+
+ return false;
+}
+
+bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
+{
+ if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
+ return false;
+
+ if (canvas()->securityOrigin()->taintsCanvas(url))
+ return true;
+
+ if (url.protocolIsData())
+ return false;
+
+ m_cleanURLs.add(url.string());
+ return false;
+}
+
+void CanvasRenderingContext::checkOrigin(const KURL& url)
+{
+ if (wouldTaintOrigin(url))
+ canvas()->setOriginTainted();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
new file mode 100644
index 000000000..53278788d
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasRenderingContext_h
+#define CanvasRenderingContext_h
+
+#include "GraphicsLayer.h"
+#include "HTMLCanvasElement.h"
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class CanvasPattern;
+class HTMLCanvasElement;
+class HTMLImageElement;
+class HTMLVideoElement;
+class KURL;
+class WebGLObject;
+
+class CanvasRenderingContext {
+ WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
+public:
+ virtual ~CanvasRenderingContext() { }
+
+ 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 isAccelerated() const { return false; }
+
+ virtual void paintRenderingResultsToCanvas() {}
+ virtual bool paintsIntoCanvasBuffer() const { return true; }
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return 0; }
+#endif
+
+protected:
+ CanvasRenderingContext(HTMLCanvasElement*);
+ bool wouldTaintOrigin(const CanvasPattern*);
+ bool wouldTaintOrigin(const HTMLCanvasElement*);
+ bool wouldTaintOrigin(const HTMLImageElement*);
+ bool wouldTaintOrigin(const HTMLVideoElement*);
+ bool wouldTaintOrigin(const KURL&);
+
+ template<class T> void checkOrigin(const T* arg)
+ {
+ if (wouldTaintOrigin(arg))
+ canvas()->setOriginTainted();
+ }
+ void checkOrigin(const KURL&);
+
+private:
+ HTMLCanvasElement* m_canvas;
+ HashSet<String> m_cleanURLs;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.idl b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
new file mode 100644
index 000000000..b53bdce5a
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ CustomMarkFunction,
+ GenerateIsReachable,
+ CustomToJS,
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
+ ] CanvasRenderingContext {
+
+ readonly attribute HTMLCanvasElement canvas;
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
new file mode 100644
index 000000000..948c21942
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -0,0 +1,2252 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasRenderingContext2D.h"
+
+#include "AffineTransform.h"
+#include "CSSFontSelector.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSParser.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
+#include "CachedImage.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasStyle.h"
+#include "Console.h"
+#include "ExceptionCode.h"
+#include "FloatConversion.h"
+#include "FloatQuad.h"
+#include "FontCache.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
+#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "KURL.h"
+#include "Page.h"
+#include "RenderHTMLCanvas.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "StrokeStyleApplier.h"
+#include "TextMetrics.h"
+#include "TextRun.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayer.h"
+#endif
+
+#include <wtf/ByteArray.h>
+#include <wtf/CheckedArithmetic.h>
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/UnusedParam.h>
+
+#if USE(CG)
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const char* const defaultFont = "10px sans-serif";
+
+static bool isOriginClean(CachedImage* cachedImage, SecurityOrigin* securityOrigin)
+{
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return false;
+ if (cachedImage->passesAccessControlCheck(securityOrigin))
+ return true;
+ return !securityOrigin->taintsCanvas(cachedImage->response().url());
+}
+
+class CanvasStrokeStyleApplier : public StrokeStyleApplier {
+public:
+ CanvasStrokeStyleApplier(CanvasRenderingContext2D* canvasContext)
+ : m_canvasContext(canvasContext)
+ {
+ }
+
+ virtual void strokeStyle(GraphicsContext* c)
+ {
+ c->setStrokeThickness(m_canvasContext->lineWidth());
+ c->setLineCap(m_canvasContext->getLineCap());
+ c->setLineJoin(m_canvasContext->getLineJoin());
+ c->setMiterLimit(m_canvasContext->miterLimit());
+ }
+
+private:
+ CanvasRenderingContext2D* m_canvasContext;
+};
+
+CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
+ : CanvasRenderingContext(canvas)
+ , m_stateStack(1)
+ , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
+#if ENABLE(DASHBOARD_SUPPORT)
+ , m_usesDashboardCompatibilityMode(usesDashboardCompatibilityMode)
+#endif
+{
+#if !ENABLE(DASHBOARD_SUPPORT)
+ ASSERT_UNUSED(usesDashboardCompatibilityMode, !usesDashboardCompatibilityMode);
+#endif
+}
+
+void CanvasRenderingContext2D::unwindStateStack()
+{
+ // Ensure that the state stack in the ImageBuffer's context
+ // is cleared before destruction, to avoid assertions in the
+ // GraphicsContext dtor.
+ if (size_t stackSize = m_stateStack.size()) {
+ if (GraphicsContext* context = canvas()->existingDrawingContext()) {
+ while (--stackSize)
+ context->restore();
+ }
+ }
+}
+
+CanvasRenderingContext2D::~CanvasRenderingContext2D()
+{
+#if !ASSERT_DISABLED
+ unwindStateStack();
+#endif
+}
+
+bool CanvasRenderingContext2D::isAccelerated() const
+{
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
+ return canvas()->hasCreatedImageBuffer() && drawingContext() && drawingContext()->isAcceleratedContext();
+#else
+ return false;
+#endif
+}
+
+bool CanvasRenderingContext2D::paintsIntoCanvasBuffer() const
+{
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ if (!isAccelerated())
+ return true;
+
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ return false;
+#endif
+ return true;
+}
+
+
+void CanvasRenderingContext2D::reset()
+{
+ unwindStateStack();
+ m_stateStack.resize(1);
+ m_stateStack.first() = State();
+ m_path.clear();
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+#endif
+}
+
+CanvasRenderingContext2D::State::State()
+ : m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
+ , m_fillStyle(CanvasStyle::createFromRGBA(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_invertibleCTM(true)
+ , m_lineDashOffset(0)
+ , m_textAlign(StartTextAlign)
+ , m_textBaseline(AlphabeticTextBaseline)
+ , m_unparsedFont(defaultFont)
+ , m_realizedFont(false)
+{
+}
+
+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_transform(other.m_transform)
+ , m_invertibleCTM(other.m_invertibleCTM)
+ , 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);
+}
+
+CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
+{
+ 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_transform = other.m_transform;
+ m_invertibleCTM = other.m_invertibleCTM;
+ 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);
+
+ return *this;
+}
+
+CanvasRenderingContext2D::State::~State()
+{
+ if (m_realizedFont)
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+}
+
+void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+{
+ ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
+ ASSERT(m_realizedFont);
+
+ m_font.update(fontSelector);
+}
+
+void CanvasRenderingContext2D::save()
+{
+ ASSERT(m_stateStack.size() >= 1);
+ m_stateStack.append(state());
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->save();
+}
+
+void CanvasRenderingContext2D::restore()
+{
+ ASSERT(m_stateStack.size() >= 1);
+ if (m_stateStack.size() <= 1)
+ return;
+ m_path.transform(state().m_transform);
+ m_stateStack.removeLast();
+ m_path.transform(state().m_transform.inverse());
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->restore();
+}
+
+void CanvasRenderingContext2D::setAllAttributesToDefault()
+{
+ state().m_globalAlpha = 1;
+ state().m_shadowOffset = FloatSize();
+ state().m_shadowBlur = 0;
+ state().m_shadowColor = Color::transparent;
+ state().m_globalComposite = CompositeSourceOver;
+
+ GraphicsContext* context = drawingContext();
+ if (!context)
+ return;
+
+ context->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+ context->setAlpha(1);
+ context->setCompositeOperation(CompositeSourceOver);
+}
+
+CanvasStyle* CanvasRenderingContext2D::strokeStyle() const
+{
+ return state().m_strokeStyle.get();
+}
+
+void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle)
+{
+ RefPtr<CanvasStyle> style = prpStyle;
+
+ if (!style)
+ return;
+
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style))
+ return;
+
+ if (style->isCurrentColor()) {
+ if (style->hasOverrideAlpha())
+ style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+ else
+ style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+ } else
+ checkOrigin(style->canvasPattern());
+
+ state().m_strokeStyle = style.release();
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ state().m_strokeStyle->applyStrokeColor(c);
+ state().m_unparsedStrokeColor = String();
+}
+
+CanvasStyle* CanvasRenderingContext2D::fillStyle() const
+{
+ return state().m_fillStyle.get();
+}
+
+void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> prpStyle)
+{
+ RefPtr<CanvasStyle> style = prpStyle;
+
+ if (!style)
+ return;
+
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style))
+ return;
+
+ if (style->isCurrentColor()) {
+ if (style->hasOverrideAlpha())
+ style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+ else
+ style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+ } else
+ checkOrigin(style->canvasPattern());
+
+ state().m_fillStyle = style.release();
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ state().m_fillStyle->applyFillColor(c);
+ state().m_unparsedFillColor = String();
+}
+
+float CanvasRenderingContext2D::lineWidth() const
+{
+ return state().m_lineWidth;
+}
+
+void CanvasRenderingContext2D::setLineWidth(float width)
+{
+ if (!(isfinite(width) && width > 0))
+ return;
+ state().m_lineWidth = width;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setStrokeThickness(width);
+}
+
+String CanvasRenderingContext2D::lineCap() const
+{
+ return lineCapName(state().m_lineCap);
+}
+
+void CanvasRenderingContext2D::setLineCap(const String& s)
+{
+ LineCap cap;
+ if (!parseLineCap(s, cap))
+ return;
+ state().m_lineCap = cap;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineCap(cap);
+}
+
+String CanvasRenderingContext2D::lineJoin() const
+{
+ return lineJoinName(state().m_lineJoin);
+}
+
+void CanvasRenderingContext2D::setLineJoin(const String& s)
+{
+ LineJoin join;
+ if (!parseLineJoin(s, join))
+ return;
+ state().m_lineJoin = join;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineJoin(join);
+}
+
+float CanvasRenderingContext2D::miterLimit() const
+{
+ return state().m_miterLimit;
+}
+
+void CanvasRenderingContext2D::setMiterLimit(float limit)
+{
+ if (!(isfinite(limit) && limit > 0))
+ return;
+ state().m_miterLimit = limit;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setMiterLimit(limit);
+}
+
+float CanvasRenderingContext2D::shadowOffsetX() const
+{
+ return state().m_shadowOffset.width();
+}
+
+void CanvasRenderingContext2D::setShadowOffsetX(float x)
+{
+ if (!isfinite(x))
+ return;
+ state().m_shadowOffset.setWidth(x);
+ applyShadow();
+}
+
+float CanvasRenderingContext2D::shadowOffsetY() const
+{
+ return state().m_shadowOffset.height();
+}
+
+void CanvasRenderingContext2D::setShadowOffsetY(float y)
+{
+ if (!isfinite(y))
+ return;
+ state().m_shadowOffset.setHeight(y);
+ applyShadow();
+}
+
+float CanvasRenderingContext2D::shadowBlur() const
+{
+ return state().m_shadowBlur;
+}
+
+void CanvasRenderingContext2D::setShadowBlur(float blur)
+{
+ if (!(isfinite(blur) && blur >= 0))
+ return;
+ state().m_shadowBlur = blur;
+ applyShadow();
+}
+
+String CanvasRenderingContext2D::shadowColor() const
+{
+ return Color(state().m_shadowColor).serialized();
+}
+
+void CanvasRenderingContext2D::setShadowColor(const String& color)
+{
+ if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
+ return;
+
+ applyShadow();
+}
+
+const DashArray* CanvasRenderingContext2D::webkitLineDash() const
+{
+ return &state().m_lineDash;
+}
+
+void CanvasRenderingContext2D::setWebkitLineDash(const DashArray& dash)
+{
+ state().m_lineDash = dash;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineDash(state().m_lineDash, state().m_lineDashOffset);
+}
+
+float CanvasRenderingContext2D::webkitLineDashOffset() const
+{
+ return state().m_lineDashOffset;
+}
+
+void CanvasRenderingContext2D::setWebkitLineDashOffset(float offset)
+{
+ if (!isfinite(offset))
+ return;
+
+ state().m_lineDashOffset = offset;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineDash(state().m_lineDash, state().m_lineDashOffset);
+}
+
+float CanvasRenderingContext2D::globalAlpha() const
+{
+ return state().m_globalAlpha;
+}
+
+void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
+{
+ if (!(alpha >= 0 && alpha <= 1))
+ return;
+ state().m_globalAlpha = alpha;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setAlpha(alpha);
+}
+
+String CanvasRenderingContext2D::globalCompositeOperation() const
+{
+ return compositeOperatorName(state().m_globalComposite);
+}
+
+void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operation)
+{
+ CompositeOperator op;
+ if (!parseCompositeOperator(operation, op))
+ return;
+ state().m_globalComposite = op;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setCompositeOperation(op);
+}
+
+void CanvasRenderingContext2D::scale(float sx, float sy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(sx) | !isfinite(sy))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.scaleNonUniform(sx, sy);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->scale(FloatSize(sx, sy));
+ m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
+}
+
+void CanvasRenderingContext2D::rotate(float angleInRadians)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(angleInRadians))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.rotate(angleInRadians / piDouble * 180.0);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->rotate(angleInRadians);
+ m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+}
+
+void CanvasRenderingContext2D::translate(float tx, float ty)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(tx) | !isfinite(ty))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.translate(tx, ty);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->translate(tx, ty);
+ m_path.transform(AffineTransform().translate(-tx, -ty));
+}
+
+void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) | !isfinite(m12) | !isfinite(m22) | !isfinite(dy))
+ return;
+
+ AffineTransform transform(m11, m12, m21, m22, dx, dy);
+ AffineTransform newTransform = state().m_transform * transform;
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->concatCTM(transform);
+ m_path.transform(transform.inverse());
+}
+
+void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) | !isfinite(m12) | !isfinite(m22) | !isfinite(dy))
+ return;
+
+ AffineTransform ctm = state().m_transform;
+ if (!ctm.isInvertible())
+ return;
+ c->concatCTM(c->getCTM().inverse());
+ c->concatCTM(canvas()->baseTransform());
+ state().m_transform = ctm.inverse() * state().m_transform;
+ m_path.transform(ctm);
+
+ state().m_invertibleCTM = true;
+ transform(m11, m12, m21, m22, dx, dy);
+}
+
+void CanvasRenderingContext2D::setStrokeColor(const String& color)
+{
+ if (color == state().m_unparsedStrokeColor)
+ return;
+ setStrokeStyle(CanvasStyle::createFromString(color, canvas()->document()));
+ state().m_unparsedStrokeColor = color;
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float grayLevel)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ return;
+ setStrokeStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, 1.0f));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(const String& color, float alpha)
+{
+ setStrokeStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float grayLevel, float alpha)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ return;
+ setStrokeStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, alpha));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float r, float g, float b, float a)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(r, g, b, a))
+ return;
+ setStrokeStyle(CanvasStyle::createFromRGBAChannels(r, g, b, a));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float c, float m, float y, float k, float a)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentCMYKA(c, m, y, k, a))
+ return;
+ setStrokeStyle(CanvasStyle::createFromCMYKAChannels(c, m, y, k, a));
+}
+
+void CanvasRenderingContext2D::setFillColor(const String& color)
+{
+ if (color == state().m_unparsedFillColor)
+ return;
+ setFillStyle(CanvasStyle::createFromString(color, canvas()->document()));
+ state().m_unparsedFillColor = color;
+}
+
+void CanvasRenderingContext2D::setFillColor(float grayLevel)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ return;
+ setFillStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, 1.0f));
+}
+
+void CanvasRenderingContext2D::setFillColor(const String& color, float alpha)
+{
+ setFillStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+}
+
+void CanvasRenderingContext2D::setFillColor(float grayLevel, float alpha)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ return;
+ setFillStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, alpha));
+}
+
+void CanvasRenderingContext2D::setFillColor(float r, float g, float b, float a)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(r, g, b, a))
+ return;
+ setFillStyle(CanvasStyle::createFromRGBAChannels(r, g, b, a));
+}
+
+void CanvasRenderingContext2D::setFillColor(float c, float m, float y, float k, float a)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentCMYKA(c, m, y, k, a))
+ return;
+ setFillStyle(CanvasStyle::createFromCMYKAChannels(c, m, y, k, a));
+}
+
+void CanvasRenderingContext2D::beginPath()
+{
+ m_path.clear();
+}
+
+void CanvasRenderingContext2D::closePath()
+{
+ if (m_path.isEmpty())
+ return;
+
+ FloatRect boundRect = m_path.fastBoundingRect();
+ if (boundRect.width() || boundRect.height())
+ m_path.closeSubpath();
+}
+
+void CanvasRenderingContext2D::moveTo(float x, float y)
+{
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ m_path.moveTo(FloatPoint(x, y));
+}
+
+void CanvasRenderingContext2D::lineTo(float x, float y)
+{
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(p1);
+ else if (p1 != m_path.currentPoint())
+ m_path.addLineTo(FloatPoint(x, y));
+}
+
+void CanvasRenderingContext2D::quadraticCurveTo(float cpx, float cpy, float x, float y)
+{
+ if (!isfinite(cpx) | !isfinite(cpy) | !isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(FloatPoint(cpx, cpy));
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (p1 != m_path.currentPoint())
+ m_path.addQuadCurveTo(FloatPoint(cpx, cpy), p1);
+}
+
+void CanvasRenderingContext2D::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
+{
+ if (!isfinite(cp1x) | !isfinite(cp1y) | !isfinite(cp2x) | !isfinite(cp2y) | !isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(FloatPoint(cp1x, cp1y));
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (p1 != m_path.currentPoint())
+ m_path.addBezierCurveTo(FloatPoint(cp1x, cp1y), FloatPoint(cp2x, cp2y), p1);
+}
+
+void CanvasRenderingContext2D::arcTo(float x1, float y1, float x2, float y2, float r, ExceptionCode& ec)
+{
+ ec = 0;
+ if (!isfinite(x1) | !isfinite(y1) | !isfinite(x2) | !isfinite(y2) | !isfinite(r))
+ return;
+
+ if (r < 0) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatPoint p1 = FloatPoint(x1, y1);
+ FloatPoint p2 = FloatPoint(x2, y2);
+
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(p1);
+ else if (p1 == m_path.currentPoint() || p1 == p2 || !r)
+ lineTo(x1, y1);
+ else
+ m_path.addArcTo(p1, p2, r);
+}
+
+void CanvasRenderingContext2D::arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode& ec)
+{
+ ec = 0;
+ if (!isfinite(x) | !isfinite(y) | !isfinite(r) | !isfinite(sa) | !isfinite(ea))
+ return;
+
+ if (r < 0) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (!r || sa == ea) {
+ // The arc is empty but we still need to draw the connecting line
+ lineTo(x + r * cosf(sa), y + r * sinf(sa));
+ return;
+ }
+
+ if (!state().m_invertibleCTM)
+ 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;
+ }
+ if (!anticlockwise && ea - sa >= 2 * piFloat) {
+ m_path.addArc(FloatPoint(x, y), r, sa, sa + 2 * piFloat, anticlockwise);
+ return;
+ }
+
+ m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
+}
+
+static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
+{
+ if (!isfinite(x) | !isfinite(y) | !isfinite(width) | !isfinite(height))
+ return false;
+
+ if (!width && !height)
+ return false;
+
+ if (width < 0) {
+ width = -width;
+ x -= width;
+ }
+
+ if (height < 0) {
+ height = -height;
+ y -= height;
+ }
+
+ return true;
+}
+
+void CanvasRenderingContext2D::rect(float x, float y, float width, float height)
+{
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(x) || !isfinite(y) || !isfinite(width) || !isfinite(height))
+ return;
+
+ if (!width && !height) {
+ m_path.moveTo(FloatPoint(x, y));
+ return;
+ }
+
+ m_path.addRect(FloatRect(x, y, width, height));
+}
+
+#if ENABLE(DASHBOARD_SUPPORT)
+void CanvasRenderingContext2D::clearPathForDashboardBackwardCompatibilityMode()
+{
+ if (m_usesDashboardCompatibilityMode)
+ m_path.clear();
+}
+#endif
+
+static bool isFullCanvasCompositeMode(CompositeOperator op)
+{
+ // See 4.8.11.1.3 Compositing
+ // CompositeSourceAtop and CompositeDestinationOut are not listed here as the platforms already
+ // implement the specification's behavior.
+ return op == CompositeSourceIn || op == CompositeSourceOut || op == CompositeDestinationIn || op == CompositeDestinationAtop;
+}
+
+void CanvasRenderingContext2D::fill()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!m_path.isEmpty()) {
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedFill(m_path);
+ didDrawEntireCanvas();
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->fillPath(m_path);
+ didDrawEntireCanvas();
+ } else {
+ c->fillPath(m_path);
+ didDraw(m_path.fastBoundingRect());
+ }
+ }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+void CanvasRenderingContext2D::stroke()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!m_path.isEmpty()) {
+ FloatRect dirtyRect = m_path.fastBoundingRect();
+ // Fast approximation of the stroke's bounding rect.
+ // This yields a slightly oversized rect but is very fast
+ // compared to Path::strokeBoundingRect().
+ dirtyRect.inflate(state().m_miterLimit + state().m_lineWidth);
+
+ c->strokePath(m_path);
+ didDraw(dirtyRect);
+ }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+void CanvasRenderingContext2D::clip()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ c->canvasClip(m_path);
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return false;
+ if (!state().m_invertibleCTM)
+ return false;
+
+ FloatPoint point(x, y);
+ AffineTransform ctm = state().m_transform;
+ FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
+ if (!isfinite(transformedPoint.x()) || !isfinite(transformedPoint.y()))
+ return false;
+ return m_path.contains(transformedPoint);
+}
+
+void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+ GraphicsContext* context = drawingContext();
+ if (!context)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ FloatRect rect(x, y, width, height);
+
+ save();
+ setAllAttributesToDefault();
+ context->clearRect(rect);
+ didDraw(rect);
+ restore();
+}
+
+void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ 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();
+ if (gradient && gradient->isZeroSize())
+ return;
+
+ FloatRect rect(x, y, width, height);
+
+ if (rectContainsCanvas(rect)) {
+ c->fillRect(rect);
+ didDrawEntireCanvas();
+ } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedFill(rect);
+ didDrawEntireCanvas();
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->fillRect(rect);
+ didDrawEntireCanvas();
+ } else {
+ c->fillRect(rect);
+ didDraw(rect);
+ }
+}
+
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+ strokeRect(x, y, width, height, state().m_lineWidth);
+}
+
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+
+ if (!(lineWidth >= 0))
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatRect rect(x, y, width, height);
+
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(lineWidth / 2);
+
+ c->strokeRect(rect, lineWidth);
+ didDraw(boundingRect);
+}
+
+#if USE(CG)
+static inline CGSize adjustedShadowSize(CGFloat width, CGFloat height)
+{
+ // Work around <rdar://problem/5539388> by ensuring that shadow offsets will get truncated
+ // to the desired integer.
+ static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
+ if (width > 0)
+ width += extraShadowOffset;
+ else if (width < 0)
+ width -= extraShadowOffset;
+
+ if (height > 0)
+ height += extraShadowOffset;
+ else if (height < 0)
+ height -= extraShadowOffset;
+
+ return CGSizeMake(width, height);
+}
+#endif
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = Color::transparent;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color)
+{
+ if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
+ return;
+
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, 1.0f);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color, float alpha)
+{
+ RGBA32 rgba;
+
+ if (!parseColorOrCurrentColor(rgba, color, canvas()))
+ return;
+
+ state().m_shadowColor = colorWithOverrideAlpha(rgba, alpha);
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(r, g, b, a);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBAFromCMYKA(c, m, y, k, a);
+
+ GraphicsContext* dc = drawingContext();
+ if (!dc)
+ return;
+#if USE(CG)
+ const CGFloat components[5] = { c, m, y, k, a };
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceCMYK();
+ CGColorRef shadowColor = CGColorCreate(colorSpace, components);
+ CGColorSpaceRelease(colorSpace);
+ CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
+ CGColorRelease(shadowColor);
+#else
+ dc->setLegacyShadow(FloatSize(width, -height), blur, state().m_shadowColor, ColorSpaceDeviceRGB);
+#endif
+}
+
+void CanvasRenderingContext2D::clearShadow()
+{
+ state().m_shadowOffset = FloatSize();
+ state().m_shadowBlur = 0;
+ state().m_shadowColor = Color::transparent;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::applyShadow()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ float width = state().m_shadowOffset.width();
+ float height = state().m_shadowOffset.height();
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+static LayoutSize size(HTMLImageElement* image)
+{
+ if (CachedImage* cachedImage = image->cachedImage())
+ return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
+ return IntSize();
+}
+
+#if ENABLE(VIDEO)
+static IntSize size(HTMLVideoElement* video)
+{
+ if (MediaPlayer* player = video->player())
+ return player->naturalSize();
+ return IntSize();
+}
+#endif
+
+static inline FloatRect normalizeRect(const FloatRect& rect)
+{
+ return FloatRect(min(rect.x(), rect.maxX()),
+ min(rect.y(), rect.maxY()),
+ max(rect.width(), -rect.width()),
+ max(rect.height(), -rect.height()));
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ LayoutSize s = size(image);
+ drawImage(image, x, y, s.width(), s.height(), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
+ float x, float y, float width, float height, ExceptionCode& ec)
+{
+ 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);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode& ec)
+{
+ drawImage(image, srcRect, dstRect, state().m_globalComposite, ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ if (!isfinite(dstRect.x()) || !isfinite(dstRect.y()) || !isfinite(dstRect.width()) || !isfinite(dstRect.height())
+ || !isfinite(srcRect.x()) || !isfinite(srcRect.y()) || !isfinite(srcRect.width()) || !isfinite(srcRect.height()))
+ return;
+
+ if (!dstRect.width() || !dstRect.height())
+ return;
+
+ if (!image->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;
+ }
+ if (!imageRect.contains(normalizedSrcRect))
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage)
+ return;
+
+ checkOrigin(image);
+
+ if (rectContainsCanvas(normalizedDstRect)) {
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
+ didDrawEntireCanvas();
+ } else if (isFullCanvasCompositeMode(op)) {
+ fullCanvasCompositedDrawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
+ didDrawEntireCanvas();
+ } else if (op == CompositeCopy) {
+ clearCanvas();
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
+ didDrawEntireCanvas();
+ } else {
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
+ didDraw(normalizedDstRect);
+ }
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, float x, float y, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ // In order to emulate drawing the result of toDataURL() into the canvas, we
+ // need to deflate the size of the source rectangle by the source canvas's
+ // backing store scale factor.
+ // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=15041 for motivation.
+
+ FloatSize logicalSize = canvas->convertDeviceToLogical(canvas->size());
+
+ drawImage(canvas, 0, 0, logicalSize.width(), logicalSize.height(), x, y, canvas->width(), canvas->height(), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas,
+ float x, float y, float width, float height, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ drawImage(canvas, FloatRect(0, 0, canvas->width(), canvas->height()), FloatRect(x, y, width, height), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, ExceptionCode& ec)
+{
+ drawImage(canvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
+ const FloatRect& dstRect, ExceptionCode& ec)
+{
+ if (!sourceCanvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ 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;
+ }
+
+ ec = 0;
+
+ if (!srcCanvasRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ ImageBuffer* buffer = sourceCanvas->buffer();
+ if (!buffer)
+ return;
+
+ checkOrigin(sourceCanvas);
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ // 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();
+ // 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();
+#else
+ sourceCanvas->makeRenderingResultsAvailable();
+#endif
+
+ // drawImageBuffer's srcRect is in buffer pixels (backing store pixels, in our case), dstRect is in canvas pixels.
+ FloatRect bufferSrcRect(sourceCanvas->convertLogicalToDevice(srcRect));
+
+ if (rectContainsCanvas(dstRect)) {
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, bufferSrcRect, state().m_globalComposite);
+ didDrawEntireCanvas();
+ } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedDrawImage(buffer, ColorSpaceDeviceRGB, bufferSrcRect, srcRect, state().m_globalComposite);
+ didDrawEntireCanvas();
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, bufferSrcRect, state().m_globalComposite);
+ didDrawEntireCanvas();
+ } else {
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, bufferSrcRect, state().m_globalComposite);
+ 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);
+}
+
+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);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect,
+ ExceptionCode& ec)
+{
+ if (!video) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ 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 (!videoRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ checkOrigin(video);
+
+ GraphicsContextStateSaver stateSaver(*c);
+ c->clip(dstRect);
+ 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)));
+ stateSaver.restore();
+ didDraw(dstRect);
+}
+#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)
+{
+ CompositeOperator op;
+ if (!parseCompositeOperator(compositeOperation, op))
+ op = CompositeSourceOver;
+
+ ExceptionCode ec;
+ drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, ec);
+}
+
+void CanvasRenderingContext2D::setAlpha(float alpha)
+{
+ setGlobalAlpha(alpha);
+}
+
+void CanvasRenderingContext2D::setCompositeOperation(const String& operation)
+{
+ setGlobalCompositeOperation(operation);
+}
+
+void CanvasRenderingContext2D::clearCanvas()
+{
+ FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->save();
+ c->setCTM(canvas()->baseTransform());
+ c->clearRect(canvasRect);
+ c->restore();
+}
+
+Path CanvasRenderingContext2D::transformAreaToDevice(const Path& path) const
+{
+ Path transformed(path);
+ transformed.transform(state().m_transform);
+ transformed.transform(canvas()->baseTransform());
+ return transformed;
+}
+
+Path CanvasRenderingContext2D::transformAreaToDevice(const FloatRect& rect) const
+{
+ Path path;
+ path.addRect(rect);
+ return transformAreaToDevice(path);
+}
+
+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);
+}
+
+template<class T> IntRect CanvasRenderingContext2D::calculateCompositingBufferRect(const T& area, IntSize* croppedOffset)
+{
+ 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();
+ bufferRect.intersect(canvasRect);
+ if (croppedOffset)
+ *croppedOffset = originalLocation - bufferRect.location();
+ return bufferRect;
+}
+
+PassOwnPtr<ImageBuffer> CanvasRenderingContext2D::createCompositingBuffer(const IntRect& bufferRect)
+{
+ RenderingMode renderMode = isAccelerated() ? Accelerated : Unaccelerated;
+ return ImageBuffer::create(bufferRect.size(), ColorSpaceDeviceRGB, renderMode);
+}
+
+void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRect& bufferRect, CompositeOperator op)
+{
+ IntRect canvasRect(0, 0, canvas()->width(), canvas()->height());
+ canvasRect = canvas()->baseTransform().mapRect(canvasRect);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->save();
+ c->setCTM(AffineTransform());
+ c->setCompositeOperation(op);
+
+ c->save();
+ c->clipOut(bufferRect);
+ c->clearRect(canvasRect);
+ c->restore();
+
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, bufferRect.location(), state().m_globalComposite);
+ c->restore();
+}
+
+static void drawImageToContext(Image* image, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+{
+ context->drawImage(image, styleColorSpace, dest, src, op);
+}
+
+static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+{
+ context->drawImageBuffer(imageBuffer, styleColorSpace, dest, src, op);
+}
+
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
+{
+ ASSERT(isFullCanvasCompositeMode(op));
+
+ IntSize croppedOffset;
+ IntRect bufferRect = calculateCompositingBufferRect(dest, &croppedOffset);
+ if (bufferRect.isEmpty()) {
+ clearCanvas();
+ return;
+ }
+
+ OwnPtr<ImageBuffer> buffer = createCompositingBuffer(bufferRect);
+ if (!buffer)
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ FloatRect adjustedDest = dest;
+ 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);
+
+ compositeBuffer(buffer.get(), bufferRect, op);
+}
+
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const T& area)
+{
+ ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
+
+ IntRect bufferRect = calculateCompositingBufferRect(area, 0);
+ if (bufferRect.isEmpty()) {
+ clearCanvas();
+ return;
+ }
+
+ OwnPtr<ImageBuffer> buffer = createCompositingBuffer(bufferRect);
+ if (!buffer)
+ return;
+
+ Path path = transformAreaToDevice(area);
+ path.translate(FloatSize(-bufferRect.x(), -bufferRect.y()));
+
+ buffer->context()->setCompositeOperation(CompositeSourceOver);
+ state().m_fillStyle->applyFillColor(buffer->context());
+ buffer->context()->fillPath(path);
+
+ compositeBuffer(buffer.get(), bufferRect, state().m_globalComposite);
+}
+
+void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient* gradient) const
+{
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (m_usesDashboardCompatibilityMode)
+ gradient->setDashboardCompatibilityMode();
+#else
+ UNUSED_PARAM(gradient);
+#endif
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
+{
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(x1) || !isfinite(y1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ prepareGradientForDashboard(gradient.get());
+ return gradient.release();
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
+{
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(r0) || !isfinite(x1) || !isfinite(y1) || !isfinite(r1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ if (r0 < 0 || r1 < 0) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ prepareGradientForDashboard(gradient.get());
+ return gradient.release();
+}
+
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+ const String& repetitionType, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+ bool repeatX, repeatY;
+ ec = 0;
+ CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
+ if (ec)
+ return 0;
+
+ if (!image->complete())
+ return 0;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage || !image->cachedImage()->imageForRenderer(image->renderer()))
+ return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+
+ bool originClean = isOriginClean(cachedImage, canvas()->securityOrigin());
+ return CanvasPattern::create(cachedImage->imageForRenderer(image->renderer()), repeatX, repeatY, originClean);
+}
+
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
+ const String& repetitionType, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+ if (!canvas->width() || !canvas->height()) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+
+ bool repeatX, repeatY;
+ ec = 0;
+ CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
+ if (ec)
+ return 0;
+ return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+}
+
+void CanvasRenderingContext2D::didDrawEntireCanvas()
+{
+ didDraw(FloatRect(FloatPoint::zero(), canvas()->size()), CanvasDidDrawApplyClip);
+}
+
+void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ // If we are drawing to hardware and we have a composited layer, just call contentChanged().
+ if (isAccelerated()) {
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing()) {
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+ canvas()->clearCopiedImage();
+ return;
+ }
+ }
+#endif
+
+ FloatRect dirtyRect = r;
+ if (options & CanvasDidDrawApplyTransform) {
+ AffineTransform ctm = state().m_transform;
+ dirtyRect = ctm.mapRect(r);
+ }
+
+ if (options & CanvasDidDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
+ // The shadow gets applied after transformation
+ FloatRect shadowRect(dirtyRect);
+ shadowRect.move(state().m_shadowOffset);
+ shadowRect.inflate(state().m_shadowBlur);
+ dirtyRect.unite(shadowRect);
+ }
+
+ if (options & CanvasDidDrawApplyClip) {
+ // FIXME: apply the current clip to the rectangle. Unfortunately we can't get the clip
+ // back out of the GraphicsContext, so to take clip into account for incremental painting,
+ // we'd have to keep the clip path around.
+ }
+
+ canvas()->didDraw(dirtyRect);
+}
+
+GraphicsContext* CanvasRenderingContext2D::drawingContext() const
+{
+ return canvas()->drawingContext();
+}
+
+static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+{
+ Checked<int, RecordOverflow> dataSize = 4;
+ dataSize *= size.width();
+ dataSize *= size.height();
+ if (dataSize.hasOverflowed())
+ return 0;
+
+ RefPtr<ImageData> data = ImageData::create(size);
+ memset(data->data()->data()->data(), 0, data->data()->data()->length());
+ return data.release();
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionCode& ec) const
+{
+ if (!imageData) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ return createEmptyImageData(imageData->size());
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const
+{
+ ec = 0;
+ if (!sw || !sh) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ if (!isfinite(sw) || !isfinite(sh)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ FloatSize logicalSize(fabs(sw), fabs(sh));
+ FloatSize deviceSize = canvas()->convertLogicalToDevice(logicalSize);
+ if (!deviceSize.isExpressibleAsIntSize())
+ return 0;
+
+ IntSize size(deviceSize.width(), deviceSize.height());
+ if (size.width() < 1)
+ size.setWidth(1);
+ if (size.height() < 1)
+ size.setHeight(1);
+
+ return createEmptyImageData(size);
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+{
+ if (!canvas()->originClean()) {
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Unable to get image data from canvas because the canvas has been tainted by cross-origin data."));
+ canvas()->document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
+ ec = SECURITY_ERR;
+ return 0;
+ }
+ if (!sw || !sh) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ if (!isfinite(sx) || !isfinite(sy) || !isfinite(sw) || !isfinite(sh)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ if (sw < 0) {
+ sx += sw;
+ sw = -sw;
+ }
+ if (sh < 0) {
+ sy += sh;
+ sh = -sh;
+ }
+
+ FloatRect logicalRect(sx, sy, sw, sh);
+ FloatRect deviceRect = canvas()->convertLogicalToDevice(logicalRect);
+ if (deviceRect.width() < 1)
+ deviceRect.setWidth(1);
+ if (deviceRect.height() < 1)
+ deviceRect.setHeight(1);
+ if (!deviceRect.isExpressibleAsIntRect())
+ return 0;
+
+ IntRect imageDataRect(deviceRect);
+ ImageBuffer* buffer = canvas()->buffer();
+ if (!buffer)
+ return createEmptyImageData(imageDataRect.size());
+
+ RefPtr<ByteArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect);
+ if (!byteArray)
+ return 0;
+
+ return ImageData::create(imageDataRect.size(), byteArray.release());
+}
+
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ putImageData(data, dx, dy, 0, 0, data->width(), data->height(), ec);
+}
+
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
+ float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) || !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+
+ ImageBuffer* buffer = canvas()->buffer();
+ if (!buffer)
+ return;
+
+ if (dirtyWidth < 0) {
+ dirtyX += dirtyWidth;
+ dirtyWidth = -dirtyWidth;
+ }
+
+ if (dirtyHeight < 0) {
+ dirtyY += dirtyHeight;
+ dirtyHeight = -dirtyHeight;
+ }
+
+ FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+ 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);
+ destRect.intersect(IntRect(IntPoint(), buffer->size()));
+ if (destRect.isEmpty())
+ return;
+ IntRect sourceRect(destRect);
+ sourceRect.move(-destOffset);
+
+ buffer->putUnmultipliedImageData(data->data()->data(), IntSize(data->width(), data->height()), sourceRect, IntPoint(destOffset));
+ didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
+}
+
+String CanvasRenderingContext2D::font() const
+{
+ return state().m_unparsedFont;
+}
+
+void CanvasRenderingContext2D::setFont(const String& newFont)
+{
+ RefPtr<CSSMutableStyleDeclaration> tempDecl = CSSMutableStyleDeclaration::create();
+ CSSParser parser(!m_usesCSSCompatibilityParseMode);
+
+ String declarationText("font: ");
+ declarationText += newFont;
+ parser.parseDeclaration(tempDecl.get(), declarationText);
+ if (!tempDecl->length())
+ return;
+
+ // The parse succeeded.
+ state().m_unparsedFont = newFont;
+
+ // 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())
+ newStyle->setFontDescription(computedStyle->fontDescription());
+ newStyle->font().update(newStyle->font().fontSelector());
+
+ // Now map the font property longhands into the style.
+ CSSStyleSelector* styleSelector = canvas()->styleSelector();
+ styleSelector->applyPropertyToStyle(CSSPropertyFontFamily, tempDecl->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());
+ styleSelector->applyPropertyToCurrentStyle(CSSPropertyFontStyle, tempDecl->getPropertyCSSValue(CSSPropertyFontStyle).get());
+ styleSelector->applyPropertyToCurrentStyle(CSSPropertyFontVariant, tempDecl->getPropertyCSSValue(CSSPropertyFontVariant).get());
+ styleSelector->applyPropertyToCurrentStyle(CSSPropertyFontWeight, tempDecl->getPropertyCSSValue(CSSPropertyFontWeight).get());
+
+ // As described in BUG66291, setting font-size on a font may entail a CSSPrimitiveValue::computeLengthDouble call,
+ // which assumes the fontMetrics are available for the affected font, otherwise a crash occurs (see http://trac.webkit.org/changeset/96122).
+ // The updateFont() call below updates the fontMetrics and ensures the proper setting of font-size.
+ styleSelector->updateFont();
+ styleSelector->applyPropertyToCurrentStyle(CSSPropertyFontSize, tempDecl->getPropertyCSSValue(CSSPropertyFontSize).get());
+ styleSelector->applyPropertyToCurrentStyle(CSSPropertyLineHeight, tempDecl->getPropertyCSSValue(CSSPropertyLineHeight).get());
+
+ state().m_font = newStyle->font();
+ state().m_font.update(styleSelector->fontSelector());
+ state().m_realizedFont = true;
+ styleSelector->fontSelector()->registerForInvalidationCallbacks(&state());
+}
+
+String CanvasRenderingContext2D::textAlign() const
+{
+ return textAlignName(state().m_textAlign);
+}
+
+void CanvasRenderingContext2D::setTextAlign(const String& s)
+{
+ TextAlign align;
+ if (!parseTextAlign(s, align))
+ return;
+ state().m_textAlign = align;
+}
+
+String CanvasRenderingContext2D::textBaseline() const
+{
+ return textBaselineName(state().m_textBaseline);
+}
+
+void CanvasRenderingContext2D::setTextBaseline(const String& s)
+{
+ TextBaseline baseline;
+ if (!parseTextBaseline(s, baseline))
+ return;
+ state().m_textBaseline = baseline;
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, true);
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, true, maxWidth, true);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, false);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, false, maxWidth, true);
+}
+
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
+ metrics->setWidth(accessFont().width(TextRun(text.characters(), text.length())));
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
+
+ return metrics.release();
+}
+
+void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ if (useMaxWidth && !isfinite(maxWidth))
+ return;
+
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ const Font& font = accessFont();
+ const FontMetrics& fontMetrics = font.fontMetrics();
+
+ // FIXME: Need to turn off font smoothing.
+
+ RenderStyle* computedStyle = canvas()->computedStyle();
+ TextDirection direction = computedStyle ? computedStyle->direction() : LTR;
+ bool isRTL = direction == RTL;
+ bool override = computedStyle ? computedStyle->unicodeBidi() == Override : false;
+
+ unsigned length = text.length();
+ const UChar* string = text.characters();
+ TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, direction, override, TextRun::NoRounding);
+
+ // Draw the item text at the correct point.
+ FloatPoint location(x, y);
+ switch (state().m_textBaseline) {
+ case TopTextBaseline:
+ case HangingTextBaseline:
+ location.setY(y + fontMetrics.ascent());
+ break;
+ case BottomTextBaseline:
+ case IdeographicTextBaseline:
+ location.setY(y - fontMetrics.descent());
+ break;
+ case MiddleTextBaseline:
+ location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2);
+ break;
+ case AlphabeticTextBaseline:
+ default:
+ // Do nothing.
+ break;
+ }
+
+ float fontWidth = font.width(TextRun(text, false, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
+
+ useMaxWidth = (useMaxWidth && maxWidth < fontWidth);
+ float width = useMaxWidth ? maxWidth : fontWidth;
+
+ TextAlign align = state().m_textAlign;
+ if (align == StartTextAlign)
+ align = isRTL ? RightTextAlign : LeftTextAlign;
+ else if (align == EndTextAlign)
+ align = isRTL ? LeftTextAlign : RightTextAlign;
+
+ switch (align) {
+ case CenterTextAlign:
+ location.setX(location.x() - width / 2);
+ break;
+ case RightTextAlign:
+ location.setX(location.x() - width);
+ break;
+ default:
+ break;
+ }
+
+ // 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());
+ if (!fill)
+ textRect.inflate(c->strokeThickness() / 2);
+
+#if USE(CG)
+ CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
+ if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
+ // FIXME: The rect is not big enough for miters on stroked text.
+ IntRect maskRect = enclosingIntRect(textRect);
+
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), ColorSpaceDeviceRGB, Accelerated);
+#else
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size());
+#endif
+
+ GraphicsContext* maskImageContext = maskImage->context();
+
+ if (fill)
+ maskImageContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ else {
+ maskImageContext->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
+ maskImageContext->setStrokeThickness(c->strokeThickness());
+ }
+
+ maskImageContext->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+
+ if (useMaxWidth) {
+ 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));
+ } else {
+ maskImageContext->translate(-maskRect.x(), -maskRect.y());
+ maskImageContext->drawBidiText(font, textRun, location);
+ }
+
+ GraphicsContextStateSaver stateSaver(*c);
+ c->clipToImageBuffer(maskImage.get(), maskRect);
+ drawStyle->applyFillColor(c);
+ c->fillRect(maskRect);
+ return;
+ }
+#endif
+
+ c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
+ 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));
+ } else
+ c->drawBidiText(font, textRun, location);
+
+ if (fill)
+ didDraw(textRect);
+ else {
+ // When stroking text, pointy miters can extend outside of textRect, so we
+ // punt and dirty the whole canvas.
+ didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ }
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
+}
+
+const Font& CanvasRenderingContext2D::accessFont()
+{
+ canvas()->document()->updateStyleIfNeeded();
+
+ if (!state().m_realizedFont)
+ setFont(state().m_unparsedFont);
+ return state().m_font;
+}
+
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+PlatformLayer* CanvasRenderingContext2D::platformLayer() const
+{
+ return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
new file mode 100644
index 000000000..4b3df1592
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasRenderingContext2D_h
+#define CanvasRenderingContext2D_h
+
+#include "AffineTransform.h"
+#include "CanvasRenderingContext.h"
+#include "Color.h"
+#include "ColorSpace.h"
+#include "DashArray.h"
+#include "FloatSize.h"
+#include "Font.h"
+#include "GraphicsTypes.h"
+#include "Path.h"
+#include "PlatformString.h"
+#include <wtf/Vector.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayer.h"
+#endif
+
+namespace WebCore {
+
+class CanvasGradient;
+class CanvasPattern;
+class CanvasStyle;
+class FloatRect;
+class GraphicsContext;
+class HTMLCanvasElement;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageData;
+class TextMetrics;
+
+typedef int ExceptionCode;
+
+class CanvasRenderingContext2D : public CanvasRenderingContext {
+public:
+ static PassOwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
+ {
+ return adoptPtr(new CanvasRenderingContext2D(canvas, usesCSSCompatibilityParseMode, usesDashboardCompatibilityMode));
+ }
+ virtual ~CanvasRenderingContext2D();
+
+ virtual bool is2d() const { return true; }
+ virtual bool isAccelerated() const;
+ virtual bool paintsIntoCanvasBuffer() const;
+
+ CanvasStyle* strokeStyle() const;
+ void setStrokeStyle(PassRefPtr<CanvasStyle>);
+
+ CanvasStyle* fillStyle() const;
+ void setFillStyle(PassRefPtr<CanvasStyle>);
+
+ float lineWidth() const;
+ void setLineWidth(float);
+
+ String lineCap() const;
+ void setLineCap(const String&);
+
+ String lineJoin() const;
+ void setLineJoin(const String&);
+
+ float miterLimit() const;
+ void setMiterLimit(float);
+
+ const DashArray* webkitLineDash() const;
+ void setWebkitLineDash(const DashArray&);
+
+ float webkitLineDashOffset() const;
+ void setWebkitLineDashOffset(float);
+
+ float shadowOffsetX() const;
+ void setShadowOffsetX(float);
+
+ float shadowOffsetY() const;
+ void setShadowOffsetY(float);
+
+ float shadowBlur() const;
+ void setShadowBlur(float);
+
+ String shadowColor() const;
+ void setShadowColor(const String&);
+
+ float globalAlpha() const;
+ void setGlobalAlpha(float);
+
+ String globalCompositeOperation() const;
+ void setGlobalCompositeOperation(const String&);
+
+ void save();
+ void restore();
+ void setAllAttributesToDefault();
+
+ 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 setStrokeColor(const String& color);
+ void setStrokeColor(float grayLevel);
+ void setStrokeColor(const String& color, float alpha);
+ void setStrokeColor(float grayLevel, float alpha);
+ 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(float r, float g, float b, float a);
+ void setFillColor(float c, float m, float y, float k, float a);
+
+ void beginPath();
+ 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 clockwise, ExceptionCode&);
+ void rect(float x, float y, float width, float height);
+
+ void fill();
+ void stroke();
+ void clip();
+
+ bool isPointInPath(const float x, const 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 strokeRect(float x, float y, float width, float height, float lineWidth);
+
+ 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, 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&, 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
+
+ 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&);
+
+ 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;
+ 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 reset();
+
+ String font() const;
+ void setFont(const String&);
+
+ String textAlign() const;
+ void setTextAlign(const String&);
+
+ 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);
+
+ LineCap getLineCap() const { return state().m_lineCap; }
+ LineJoin getLineJoin() const { return state().m_lineJoin; }
+
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const;
+#endif
+
+private:
+ struct State : FontSelectorClient {
+ State();
+ virtual ~State();
+
+ State(const State&);
+ State& operator=(const State&);
+
+ virtual void fontsNeedUpdate(FontSelector*);
+
+ String m_unparsedStrokeColor;
+ String m_unparsedFillColor;
+ RefPtr<CanvasStyle> m_strokeStyle;
+ RefPtr<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;
+ AffineTransform m_transform;
+ bool m_invertibleCTM;
+ DashArray m_lineDash;
+ float m_lineDashOffset;
+
+ // Text state.
+ TextAlign m_textAlign;
+ TextBaseline m_textBaseline;
+
+ String m_unparsedFont;
+ Font m_font;
+ bool m_realizedFont;
+ };
+
+ enum CanvasDidDrawOption {
+ CanvasDidDrawApplyNone = 0,
+ CanvasDidDrawApplyTransform = 1,
+ CanvasDidDrawApplyShadow = 1 << 1,
+ CanvasDidDrawApplyClip = 1 << 2,
+ CanvasDidDrawApplyAll = 0xffffffff
+ };
+
+ CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
+
+ Path m_path;
+
+ State& state() { return m_stateStack.last(); }
+ const State& state() const { return m_stateStack.last(); }
+
+ void applyShadow();
+
+ void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
+ void didDrawEntireCanvas();
+
+ GraphicsContext* drawingContext() const;
+
+ void unwindStateStack();
+
+ void applyStrokePattern();
+ void applyFillPattern();
+
+ void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
+
+ const Font& accessFont();
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ void clearPathForDashboardBackwardCompatibilityMode();
+#endif
+
+ void clearCanvas();
+ Path transformAreaToDevice(const Path&) const;
+ Path transformAreaToDevice(const FloatRect&) const;
+ bool rectContainsCanvas(const FloatRect&) const;
+
+ template<class T> IntRect calculateCompositingBufferRect(const T&, IntSize*);
+ PassOwnPtr<ImageBuffer> createCompositingBuffer(const IntRect&);
+ void compositeBuffer(ImageBuffer*, const IntRect&, CompositeOperator);
+
+ template<class T> void fullCanvasCompositedFill(const T&);
+ template<class T> void fullCanvasCompositedDrawImage(T*, ColorSpace, const FloatRect&, const FloatRect&, CompositeOperator);
+
+ void prepareGradientForDashboard(CanvasGradient* gradient) const;
+
+ Vector<State, 1> m_stateStack;
+ bool m_usesCSSCompatibilityParseMode;
+#if ENABLE(DASHBOARD_SUPPORT)
+ bool m_usesDashboardCompatibilityMode;
+#endif
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
new file mode 100644
index 000000000..0168e4c66
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
+ ] CanvasRenderingContext2D : CanvasRenderingContext {
+
+ void save();
+ void restore();
+
+ void scale(in [Optional=CallWithDefaultValue] float sx,
+ in [Optional=CallWithDefaultValue] float sy);
+ void rotate(in [Optional=CallWithDefaultValue] float angle);
+ void translate(in [Optional=CallWithDefaultValue] float tx,
+ in [Optional=CallWithDefaultValue] float ty);
+ void transform(in [Optional=CallWithDefaultValue] float m11,
+ in [Optional=CallWithDefaultValue] float m12,
+ in [Optional=CallWithDefaultValue] float m21,
+ in [Optional=CallWithDefaultValue] float m22,
+ in [Optional=CallWithDefaultValue] float dx,
+ in [Optional=CallWithDefaultValue] float dy);
+ void setTransform(in [Optional=CallWithDefaultValue] float m11,
+ in [Optional=CallWithDefaultValue] float m12,
+ in [Optional=CallWithDefaultValue] float m21,
+ in [Optional=CallWithDefaultValue] float m22,
+ in [Optional=CallWithDefaultValue] float dx,
+ in [Optional=CallWithDefaultValue] float dy);
+
+ attribute float globalAlpha;
+ attribute [ConvertNullToNullString] DOMString globalCompositeOperation;
+
+ CanvasGradient createLinearGradient(in [Optional=CallWithDefaultValue] float x0,
+ in [Optional=CallWithDefaultValue] float y0,
+ in [Optional=CallWithDefaultValue] float x1,
+ in [Optional=CallWithDefaultValue] float y1)
+ raises (DOMException);
+ CanvasGradient createRadialGradient(in [Optional=CallWithDefaultValue] float x0,
+ in [Optional=CallWithDefaultValue] float y0,
+ in [Optional=CallWithDefaultValue] float r0,
+ in [Optional=CallWithDefaultValue] float x1,
+ in [Optional=CallWithDefaultValue] float y1,
+ in [Optional=CallWithDefaultValue] float r1)
+ raises (DOMException);
+
+ attribute float lineWidth;
+ attribute [ConvertNullToNullString] DOMString lineCap;
+ attribute [ConvertNullToNullString] DOMString lineJoin;
+ attribute float miterLimit;
+
+ attribute float shadowOffsetX;
+ attribute float shadowOffsetY;
+ attribute float shadowBlur;
+ attribute [ConvertNullToNullString] DOMString shadowColor;
+
+ // FIXME: These attributes should also be implemented for V8.
+#if !(defined(V8_BINDING) && V8_BINDING)
+ attribute [Custom] Array webkitLineDash;
+ attribute float webkitLineDashOffset;
+#endif
+
+ void clearRect(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y,
+ in [Optional=CallWithDefaultValue] float width,
+ in [Optional=CallWithDefaultValue] float height);
+ void fillRect(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y,
+ in [Optional=CallWithDefaultValue] float width,
+ in [Optional=CallWithDefaultValue] float height);
+
+ void beginPath();
+ void closePath();
+ void moveTo(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y);
+ void lineTo(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y);
+ void quadraticCurveTo(in [Optional=CallWithDefaultValue] float cpx,
+ in [Optional=CallWithDefaultValue] float cpy,
+ in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y);
+ void bezierCurveTo(in [Optional=CallWithDefaultValue] float cp1x,
+ in [Optional=CallWithDefaultValue] float cp1y,
+ in [Optional=CallWithDefaultValue] float cp2x,
+ in [Optional=CallWithDefaultValue] float cp2y,
+ in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y);
+ void arcTo(in [Optional=CallWithDefaultValue] float x1,
+ in [Optional=CallWithDefaultValue] float y1,
+ in [Optional=CallWithDefaultValue] float x2,
+ in [Optional=CallWithDefaultValue] float y2,
+ in [Optional=CallWithDefaultValue] float radius)
+ raises (DOMException);
+ void rect(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y,
+ in [Optional=CallWithDefaultValue] float width,
+ in [Optional=CallWithDefaultValue] float height);
+ void arc(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y,
+ in [Optional=CallWithDefaultValue] float radius,
+ in [Optional=CallWithDefaultValue] float startAngle,
+ in [Optional=CallWithDefaultValue] float endAngle,
+ in [Optional=CallWithDefaultValue] boolean anticlockwise)
+ raises (DOMException);
+ void fill();
+ void stroke();
+ void clip();
+ boolean isPointInPath(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y);
+
+ // text
+ attribute DOMString font;
+ attribute DOMString textAlign;
+ attribute DOMString textBaseline;
+
+ TextMetrics measureText(in [Optional=CallWithDefaultValue] DOMString text);
+
+ // other
+
+ void setAlpha(in [Optional=CallWithDefaultValue] float alpha);
+ void setCompositeOperation(in [Optional=CallWithDefaultValue] DOMString compositeOperation);
+
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ void setLineWidth(in [Optional=CallWithDefaultValue] float width);
+ void setLineCap(in [Optional=CallWithDefaultValue] DOMString cap);
+ void setLineJoin(in [Optional=CallWithDefaultValue] DOMString join);
+ void setMiterLimit(in [Optional=CallWithDefaultValue] float limit);
+#endif
+
+ void clearShadow();
+
+ void fillText(in DOMString text, in float x, in float y, in [Optional] float maxWidth);
+ void strokeText(in DOMString text, in float x, in float y, in [Optional] float maxWidth);
+
+ void setStrokeColor(in DOMString color, in [Optional] float alpha);
+ void setStrokeColor(in float grayLevel, in [Optional] float alpha);
+ void setStrokeColor(in float r, in float g, in float b, in float a);
+ void setStrokeColor(in float c, in float m, in float y, in float k, in float a);
+
+ void setFillColor(in DOMString color, in [Optional] float alpha);
+ void setFillColor(in float grayLevel, in [Optional] float alpha);
+ void setFillColor(in float r, in float g, in float b, in float a);
+ void setFillColor(in float c, in float m, in float y, in float k, in float a);
+
+ void strokeRect(in [Optional=CallWithDefaultValue] float x,
+ in [Optional=CallWithDefaultValue] float y,
+ in [Optional=CallWithDefaultValue] float width,
+ in [Optional=CallWithDefaultValue] float height,
+ in [Optional] float lineWidth);
+
+ void drawImage(in HTMLImageElement image, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLImageElement image, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ void drawImage(in HTMLVideoElement video, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLVideoElement video, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLVideoElement video, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+#endif
+
+ void drawImageFromRect(in HTMLImageElement image,
+ in [Optional] float sx, in [Optional] float sy, in [Optional] float sw, in [Optional] float sh,
+ in [Optional] float dx, in [Optional] float dy, in [Optional] float dw, in [Optional] float dh,
+ in [Optional] DOMString compositeOperation);
+
+ void setShadow(in float width, in float height, in float blur, in [Optional] DOMString color, in [Optional] float alpha);
+ void setShadow(in float width, in float height, in float blur, in float grayLevel, in [Optional] float alpha);
+ void setShadow(in float width, in float height, in float blur, in float r, in float g, in float b, in float a);
+ void setShadow(in float width, in float height, in float blur, in float c, in float m, in float y, in float k, in float a);
+
+ void putImageData(in ImageData imagedata, in float dx, in float dy)
+ raises(DOMException);
+ void putImageData(in ImageData imagedata, in float dx, in float dy, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight)
+ raises(DOMException);
+
+ CanvasPattern createPattern(in HTMLCanvasElement canvas, in [ConvertNullToNullString] DOMString repetitionType)
+ raises (DOMException);
+ CanvasPattern createPattern(in HTMLImageElement image, in [ConvertNullToNullString] DOMString repetitionType)
+ raises (DOMException);
+ ImageData createImageData(in ImageData imagedata)
+ raises (DOMException);
+ ImageData createImageData(in float sw, in float sh)
+ raises (DOMException);
+
+ attribute [Custom] custom strokeStyle;
+ attribute [Custom] custom fillStyle;
+
+ // pixel manipulation
+ ImageData getImageData(in [Optional=CallWithDefaultValue] float sx, in [Optional=CallWithDefaultValue] float sy,
+ in [Optional=CallWithDefaultValue] float sw, in [Optional=CallWithDefaultValue] float sh)
+ raises(DOMException);
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
new file mode 100644
index 000000000..3aee6e8f1
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2006, 2008 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>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasStyle.h"
+
+#include "CSSParser.h"
+#include "CSSPropertyNames.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h>
+
+#if USE(CG)
+#include <CoreGraphics/CGContext.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QPainter>
+#include <QBrush>
+#include <QPen>
+#include <QColor>
+#endif
+
+namespace WebCore {
+
+enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
+
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0)
+{
+ if (equalIgnoringCase(colorString, "currentcolor"))
+ return ParsedCurrentColor;
+ if (CSSParser::parseColor(parsedColor, colorString))
+ return ParsedRGBA;
+ if (CSSParser::parseSystemColor(parsedColor, colorString, document))
+ return ParsedSystemColor;
+ return ParseFailed;
+}
+
+RGBA32 currentColor(HTMLCanvasElement* canvas)
+{
+ if (!canvas || !canvas->inDocument())
+ return Color::black;
+ RGBA32 rgba = Color::black;
+ CSSParser::parseColor(rgba, canvas->style()->getPropertyValue(CSSPropertyColor));
+ return rgba;
+}
+
+bool parseColorOrCurrentColor(RGBA32& parsedColor, 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;
+ }
+}
+
+CanvasStyle::CanvasStyle(Type type, float overrideAlpha)
+ : m_type(type)
+ , m_overrideAlpha(overrideAlpha)
+{
+}
+
+CanvasStyle::CanvasStyle(RGBA32 rgba)
+ : m_type(RGBA)
+ , m_rgba(rgba)
+{
+}
+
+CanvasStyle::CanvasStyle(float grayLevel, float alpha)
+ : m_type(RGBA)
+ , m_rgba(makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha))
+{
+}
+
+CanvasStyle::CanvasStyle(float r, float g, float b, float a)
+ : m_type(RGBA)
+ , m_rgba(makeRGBA32FromFloats(r, g, b, a))
+{
+}
+
+CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
+ : m_type(CMYKA)
+ , m_rgba(makeRGBAFromCMYKA(c, m, y, k, a))
+ , m_cmyka(c, m, y, k, a)
+{
+}
+
+CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
+ : m_type(Gradient)
+ , m_gradient(gradient)
+{
+}
+
+CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
+ : m_type(ImagePattern)
+ , m_pattern(pattern)
+{
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Document* document)
+{
+ RGBA32 rgba;
+ ColorParseResult parseResult = parseColor(rgba, color, document);
+ switch (parseResult) {
+ case ParsedRGBA:
+ case ParsedSystemColor:
+ return adoptRef(new CanvasStyle(rgba));
+ case ParsedCurrentColor:
+ return adoptRef(new CanvasStyle(CurrentColor));
+ case ParseFailed:
+ return 0;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha)
+{
+ RGBA32 rgba;
+ ColorParseResult parseResult = parseColor(rgba, color);
+ switch (parseResult) {
+ case ParsedRGBA:
+ return adoptRef(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha)));
+ case ParsedCurrentColor:
+ return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
+ case ParseFailed:
+ return 0;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
+{
+ if (!gradient)
+ return 0;
+ return adoptRef(new CanvasStyle(gradient));
+}
+PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
+{
+ if (!pattern)
+ return 0;
+ return adoptRef(new CanvasStyle(pattern));
+}
+
+bool CanvasStyle::isEquivalentColor(const CanvasStyle& other) const
+{
+ if (m_type != other.m_type)
+ return false;
+
+ 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;
+ }
+
+ 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);
+}
+
+bool CanvasStyle::isEquivalentCMYKA(float c, float m, float y, float k, float a) const
+{
+ if (m_type != CMYKA)
+ return false;
+
+ return c == m_cmyka.c
+ && m == m_cmyka.m
+ && y == m_cmyka.y
+ && k == m_cmyka.k
+ && a == m_cmyka.a;
+}
+
+void CanvasStyle::applyStrokeColor(GraphicsContext* context)
+{
+ 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
+#if USE(CG)
+ CGContextSetCMYKStrokeColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+#elif PLATFORM(QT)
+ QPen currentPen = context->platformContext()->pen();
+ QColor clr;
+ clr.setCmykF(m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+ currentPen.setColor(clr);
+ context->platformContext()->setPen(currentPen);
+#else
+ context->setStrokeColor(m_rgba, ColorSpaceDeviceRGB);
+#endif
+ break;
+ }
+ case Gradient:
+ context->setStrokeGradient(canvasGradient()->gradient());
+ break;
+ case ImagePattern:
+ context->setStrokePattern(canvasPattern()->pattern());
+ break;
+ case CurrentColor:
+ case CurrentColorWithOverrideAlpha:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void CanvasStyle::applyFillColor(GraphicsContext* context)
+{
+ 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
+#if USE(CG)
+ CGContextSetCMYKFillColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+#elif PLATFORM(QT)
+ QBrush currentBrush = context->platformContext()->brush();
+ QColor clr;
+ clr.setCmykF(m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+ currentBrush.setColor(clr);
+ context->platformContext()->setBrush(currentBrush);
+#else
+ context->setFillColor(m_rgba, ColorSpaceDeviceRGB);
+#endif
+ break;
+ }
+ case Gradient:
+ context->setFillGradient(canvasGradient()->gradient());
+ break;
+ case ImagePattern:
+ context->setFillPattern(canvasPattern()->pattern());
+ break;
+ case CurrentColor:
+ case CurrentColorWithOverrideAlpha:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h
new file mode 100644
index 000000000..8f4bfd402
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasStyle.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006, 2008 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
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasStyle_h
+#define CanvasStyle_h
+
+#include "Color.h"
+#include "PlatformString.h"
+#include <wtf/Assertions.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class CanvasGradient;
+ class CanvasPattern;
+ class Document;
+ class GraphicsContext;
+ class HTMLCanvasElement;
+
+ class CanvasStyle : public RefCounted<CanvasStyle> {
+ public:
+ static PassRefPtr<CanvasStyle> createFromRGBA(RGBA32 rgba) { return adoptRef(new CanvasStyle(rgba)); }
+ static PassRefPtr<CanvasStyle> createFromString(const String& color, Document* = 0);
+ static PassRefPtr<CanvasStyle> createFromStringWithOverrideAlpha(const String& color, float alpha);
+ static PassRefPtr<CanvasStyle> createFromGrayLevelWithAlpha(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); }
+ static PassRefPtr<CanvasStyle> createFromRGBAChannels(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); }
+ static PassRefPtr<CanvasStyle> createFromCMYKAChannels(float c, float m, float y, float k, float a) { return adoptRef(new CanvasStyle(c, m, y, k, a)); }
+ static PassRefPtr<CanvasStyle> createFromGradient(PassRefPtr<CanvasGradient>);
+ static PassRefPtr<CanvasStyle> createFromPattern(PassRefPtr<CanvasPattern>);
+
+ 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 { ASSERT(m_type == RGBA || m_type == CMYKA); return Color(m_rgba).serialized(); }
+ CanvasGradient* canvasGradient() const { return m_gradient.get(); }
+ CanvasPattern* canvasPattern() const { return m_pattern.get(); }
+
+ void applyFillColor(GraphicsContext*);
+ void applyStrokeColor(GraphicsContext*);
+
+ 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;
+
+ private:
+ enum Type { RGBA, CMYKA, Gradient, ImagePattern, CurrentColor, CurrentColorWithOverrideAlpha };
+
+ CanvasStyle(Type, float overrideAlpha = 0);
+ CanvasStyle(RGBA32 rgba);
+ CanvasStyle(float grayLevel, float alpha);
+ CanvasStyle(float r, float g, float b, float a);
+ CanvasStyle(float c, float m, float y, float k, float a);
+ CanvasStyle(PassRefPtr<CanvasGradient>);
+ CanvasStyle(PassRefPtr<CanvasPattern>);
+
+ Type m_type;
+
+ union {
+ RGBA32 m_rgba;
+ float m_overrideAlpha;
+ };
+
+ RefPtr<CanvasGradient> m_gradient;
+ RefPtr<CanvasPattern> m_pattern;
+
+ struct CMYKAValues {
+ CMYKAValues() {}
+ CMYKAValues(float cyan, float magenta, float yellow, float black, float alpha) : c(cyan), m(magenta), y(yellow), k(black), a(alpha) {}
+ float c;
+ float m;
+ float y;
+ float k;
+ float a;
+ } m_cmyka;
+ };
+
+ RGBA32 currentColor(HTMLCanvasElement*);
+ bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement*);
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CheckedInt.h b/Source/WebCore/html/canvas/CheckedInt.h
new file mode 100644
index 000000000..b83ac19ea
--- /dev/null
+++ b/Source/WebCore/html/canvas/CheckedInt.h
@@ -0,0 +1,588 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Benoit Jacob <bjacob@mozilla.com>
+ * Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Necessary modifications are made to the original CheckedInt.h file to remove
+// dependencies on prtypes.
+// Also, change define Mozilla_CheckedInt_h to CheckedInt_h, change namespace
+// from mozilla to WebCore for easier usage.
+
+#ifndef CheckedInt_h
+#define CheckedInt_h
+
+#include <climits>
+
+namespace WebCore {
+
+namespace CheckedInt_internal {
+
+/* we don't want to use std::numeric_limits here because int... types may not support it,
+ * depending on the platform, e.g. on certain platform they use nonstandard built-in types
+ */
+
+/*** Step 1: manually record information for all the types that we want to support
+ ***/
+
+struct unsupported_type {};
+
+template<typename T> struct integer_type_manually_recorded_info;
+
+
+#define CHECKEDINT_REGISTER_SUPPORTED_TYPE(T,_twice_bigger_type,_unsigned_type) \
+template<> struct integer_type_manually_recorded_info<T> \
+{ \
+ enum { is_supported = 1 }; \
+ typedef _twice_bigger_type twice_bigger_type; \
+ typedef _unsigned_type unsigned_type; \
+};
+
+// Type Twice Bigger Type Unsigned Type
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int8_t, int16_t, uint8_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint8_t, uint16_t, uint8_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int16_t, int32_t, uint16_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint16_t, uint32_t, uint16_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int32_t, int64_t, uint32_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint32_t, uint64_t, uint32_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int64_t, unsupported_type, uint64_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint64_t, unsupported_type, uint64_t)
+
+// now implement the fallback for standard types like int, long, ...
+// the difficulty is that they may or may not be equal to one of the above types, and/or
+// to each other. This is why any attempt to handle at once PRInt8... types and standard types
+// is bound to fail.
+template<typename T>
+struct is_standard_integer_type { enum { value = 0 }; };
+
+template<>
+struct is_standard_integer_type<char> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<unsigned char> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<short> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<unsigned short> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<int> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<unsigned int> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<long> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<unsigned long> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<long long> { enum { value = 1 }; };
+template<>
+struct is_standard_integer_type<unsigned long long> { enum { value = 1 }; };
+
+template<int size, bool is_signed>
+struct explicitly_sized_integer_type {};
+
+template<>
+struct explicitly_sized_integer_type<1, true> { typedef int8_t type; };
+template<>
+struct explicitly_sized_integer_type<1, false> { typedef uint8_t type; };
+template<>
+struct explicitly_sized_integer_type<2, true> { typedef int16_t type; };
+template<>
+struct explicitly_sized_integer_type<2, false> { typedef uint16_t type; };
+template<>
+struct explicitly_sized_integer_type<4, true> { typedef int32_t type; };
+template<>
+struct explicitly_sized_integer_type<4, false> { typedef uint32_t type; };
+template<>
+struct explicitly_sized_integer_type<8, true> { typedef int64_t type; };
+template<>
+struct explicitly_sized_integer_type<8, false> { typedef uint64_t type; };
+
+template<typename T> struct integer_type_manually_recorded_info
+{
+ enum {
+ is_supported = is_standard_integer_type<T>::value,
+ size = sizeof(T),
+ is_signed = (T(-1) > T(0)) ? 0 : 1
+ };
+ typedef typename explicitly_sized_integer_type<size, is_signed>::type explicit_sized_type;
+ typedef integer_type_manually_recorded_info<explicit_sized_type> base;
+ typedef typename base::twice_bigger_type twice_bigger_type;
+ typedef typename base::unsigned_type unsigned_type;
+};
+
+template<typename T, bool is_supported = integer_type_manually_recorded_info<T>::is_supported>
+struct TYPE_NOT_SUPPORTED_BY_CheckedInt {};
+
+template<typename T>
+struct TYPE_NOT_SUPPORTED_BY_CheckedInt<T, true> { static void run() {} };
+
+
+/*** Step 2: record some info about a given integer type,
+ *** including whether it is supported, whether a twice bigger integer type
+ *** is supported, what that twice bigger type is, and some stuff as found
+ *** in std::numeric_limits (which we don't use because int.. types may
+ *** not support it, if they are defined directly from compiler built-in types).
+ ***/
+
+template<typename T> struct is_unsupported_type { enum { answer = 0 }; };
+template<> struct is_unsupported_type<unsupported_type> { enum { answer = 1 }; };
+
+template<typename T> struct integer_traits
+{
+ typedef typename integer_type_manually_recorded_info<T>::twice_bigger_type twice_bigger_type;
+
+ enum {
+ is_supported = integer_type_manually_recorded_info<T>::is_supported,
+ twice_bigger_type_is_supported
+ = is_unsupported_type<
+ typename integer_type_manually_recorded_info<T>::twice_bigger_type
+ >::answer ? 0 : 1,
+ size = sizeof(T),
+ position_of_sign_bit = CHAR_BIT * size - 1,
+ is_signed = (T(-1) > T(0)) ? 0 : 1
+ };
+
+ static T min()
+ {
+ // bitwise ops may return a larger type, that's why we cast explicitly to T
+ return is_signed ? T(T(1) << position_of_sign_bit) : T(0);
+ }
+
+ static T max()
+ {
+ return ~min();
+ }
+};
+
+/*** Step 3: Implement the actual validity checks --- ideas taken from IntegerLib, code different.
+ ***/
+
+// bitwise ops may return a larger type, so it's good to use these inline helpers guaranteeing that
+// the result is really of type T
+
+template<typename T> inline T has_sign_bit(T x)
+{
+ return x >> integer_traits<T>::position_of_sign_bit;
+}
+
+template<typename T> inline T binary_complement(T x)
+{
+ return ~x;
+}
+
+template<typename T, typename U,
+ bool is_T_signed = integer_traits<T>::is_signed,
+ bool is_U_signed = integer_traits<U>::is_signed>
+struct is_in_range_impl {};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, true>
+{
+ static T run(U x)
+ {
+ return (x <= integer_traits<T>::max()) &
+ (x >= integer_traits<T>::min());
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, false>
+{
+ static T run(U x)
+ {
+ return x <= integer_traits<T>::max();
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, false>
+{
+ static T run(U x)
+ {
+ if (sizeof(T) > sizeof(U))
+ return 1;
+ else
+ return x <= U(integer_traits<T>::max());
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, true>
+{
+ static T run(U x)
+ {
+ if (sizeof(T) >= sizeof(U))
+ return x >= 0;
+ else
+ return x >= 0 && x <= U(integer_traits<T>::max());
+ }
+};
+
+template<typename T, typename U> inline T is_in_range(U x)
+{
+ return is_in_range_impl<T, U>::run(x);
+}
+
+template<typename T> inline T is_add_valid(T x, T y, T result)
+{
+ return integer_traits<T>::is_signed ?
+ // addition is valid if the sign of x+y is equal to either that of x or that of y.
+ // Beware! These bitwise operations can return a larger integer type, if T was a
+ // small type like int8, so we explicitly cast to T.
+ has_sign_bit(binary_complement(T((result^x) & (result^y))))
+ :
+ binary_complement(x) >= y;
+}
+
+template<typename T> inline T is_sub_valid(T x, T y, T result)
+{
+ return integer_traits<T>::is_signed ?
+ // substraction is valid if either x and y have same sign, or x-y and x have same sign
+ has_sign_bit(binary_complement(T((result^x) & (x^y))))
+ :
+ x >= y;
+}
+
+template<typename T,
+ bool is_signed = integer_traits<T>::is_signed,
+ bool twice_bigger_type_is_supported = integer_traits<T>::twice_bigger_type_is_supported>
+struct is_mul_valid_impl {};
+
+template<typename T>
+struct is_mul_valid_impl<T, true, true>
+{
+ static T run(T x, T y)
+ {
+ typedef typename integer_traits<T>::twice_bigger_type twice_bigger_type;
+ twice_bigger_type product = twice_bigger_type(x) * twice_bigger_type(y);
+ return is_in_range<T>(product);
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, false, true>
+{
+ static T run(T x, T y)
+ {
+ typedef typename integer_traits<T>::twice_bigger_type twice_bigger_type;
+ twice_bigger_type product = twice_bigger_type(x) * twice_bigger_type(y);
+ return is_in_range<T>(product);
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, true, false>
+{
+ static T run(T x, T y)
+ {
+ const T max_value = integer_traits<T>::max();
+ const T min_value = integer_traits<T>::min();
+
+ if (x == 0 || y == 0) return true;
+
+ if (x > 0) {
+ if (y > 0)
+ return x <= max_value / y;
+ else
+ return y >= min_value / x;
+ } else {
+ if (y > 0)
+ return x >= min_value / y;
+ else
+ return y >= max_value / x;
+ }
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, false, false>
+{
+ static T run(T x, T y)
+ {
+ const T max_value = integer_traits<T>::max();
+ if (x == 0 || y == 0) return true;
+ return x <= max_value / y;
+ }
+};
+
+template<typename T> inline T is_mul_valid(T x, T y, T /*result not used*/)
+{
+ return is_mul_valid_impl<T>::run(x, y);
+}
+
+template<typename T> inline T is_div_valid(T x, T y)
+{
+ return integer_traits<T>::is_signed ?
+ // keep in mind that min/-1 is invalid because abs(min)>max
+ y != 0 && (x != integer_traits<T>::min() || y != T(-1))
+ :
+ y != 0;
+}
+
+} // end namespace CheckedInt_internal
+
+
+/*** Step 4: Now define the CheckedInt class.
+ ***/
+
+/** \class CheckedInt
+ * \brief Integer wrapper class checking for integer overflow and other errors
+ * \param T the integer type to wrap. Can be any of int8_t, uint8_t, int16_t, uint16_t,
+ * int32_t, uint32_t, int64_t, uint64_t.
+ *
+ * This class implements guarded integer arithmetic. Do a computation, then check that
+ * valid() returns true, you then have a guarantee that no problem, such as integer overflow,
+ * happened during this computation.
+ *
+ * The arithmetic operators in this class are guaranteed not to crash your app
+ * in case of a division by zero.
+ *
+ * For example, suppose that you want to implement a function that computes (x+y)/z,
+ * that doesn't crash if z==0, and that reports on error (divide by zero or integer overflow).
+ * You could code it as follows:
+ \code
+ bool compute_x_plus_y_over_z(int32_t x, int32_t y, int32_t z, int32_t *result)
+ {
+ CheckedInt<int32_t> checked_result = (CheckedInt<int32_t>(x) + y) / z;
+ *result = checked_result.value();
+ return checked_result.valid();
+ }
+ \endcode
+ *
+ * Implicit conversion from plain integers to checked integers is allowed. The plain integer
+ * is checked to be in range before being casted to the destination type. This means that the following
+ * lines all compile, and the resulting CheckedInts are correctly detected as valid or invalid:
+ * \code
+ CheckedInt<uint8_t> x(1); // 1 is of type int, is found to be in range for uint8_t, x is valid
+ CheckedInt<uint8_t> x(-1); // -1 is of type int, is found not to be in range for uint8_t, x is invalid
+ CheckedInt<int8_t> x(-1); // -1 is of type int, is found to be in range for int8_t, x is valid
+ CheckedInt<int8_t> x(int16_t(1000)); // 1000 is of type int16_t, is found not to be in range for int8_t, x is invalid
+ CheckedInt<int32_t> x(uint32_t(123456789)); // 3123456789 is of type uint32_t, is found not to be in range
+ // for int32_t, x is invalid
+ * \endcode
+ * Implicit conversion from
+ * checked integers to plain integers is not allowed. As shown in the
+ * above example, to get the value of a checked integer as a normal integer, call value().
+ *
+ * Arithmetic operations between checked and plain integers is allowed; the result type
+ * is the type of the checked integer.
+ *
+ * Safe integers of different types cannot be used in the same arithmetic expression.
+ */
+template<typename T>
+class CheckedInt
+{
+protected:
+ T mValue;
+ T mIsValid; // stored as a T to limit the number of integer conversions when
+ // evaluating nested arithmetic expressions.
+
+ template<typename U>
+ CheckedInt(const U& value, bool isValid) : mValue(value), mIsValid(isValid)
+ {
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
+ }
+
+public:
+ /** Constructs a checked integer with given \a value. The checked integer is initialized as valid or invalid
+ * depending on whether the \a value is in range.
+ *
+ * This constructor is not explicit. Instead, the type of its argument is a separate template parameter,
+ * ensuring that no conversion is performed before this constructor is actually called.
+ * As explained in the above documentation for class CheckedInt, this constructor checks that its argument is
+ * valid.
+ */
+ template<typename U>
+ CheckedInt(const U& value)
+ : mValue(value),
+ mIsValid(CheckedInt_internal::is_in_range<T>(value))
+ {
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
+ }
+
+ /** Constructs a valid checked integer with uninitialized value */
+ CheckedInt() : mIsValid(1)
+ {
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
+ }
+
+ /** \returns the actual value */
+ T value() const { return mValue; }
+
+ /** \returns true if the checked integer is valid, i.e. is not the result
+ * of an invalid operation or of an operation involving an invalid checked integer
+ */
+ bool valid() const { return mIsValid; }
+
+ /** \returns the sum. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator +(const CheckedInt<U>& lhs, const CheckedInt<U>& rhs);
+ /** Adds. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator +=(const U &rhs);
+ /** \returns the difference. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator -(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Substracts. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator -=(const U &rhs);
+ /** \returns the product. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator *(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Multiplies. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator *=(const U &rhs);
+ /** \returns the quotient. Checks for overflow and for divide-by-zero. */
+ template<typename U> friend CheckedInt<U> operator /(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Divides. Checks for overflow and for divide-by-zero. \returns self reference */
+ template<typename U> CheckedInt& operator /=(const U &rhs);
+
+ /** \returns the opposite value. Checks for overflow. */
+ CheckedInt operator -() const
+ {
+ T result = -value();
+ /* give the compiler a good chance to perform RVO */
+ return CheckedInt(result,
+ mIsValid & CheckedInt_internal::is_sub_valid(T(0), value(), result));
+ }
+
+ /** \returns true if the left and right hand sides are valid and have the same value. */
+ bool operator ==(const CheckedInt& other) const
+ {
+ return bool(mIsValid & other.mIsValid & T(value() == other.value()));
+ }
+
+private:
+ /** operator!= is disabled. Indeed: (a!=b) should be the same as !(a==b) but that
+ * would mean that if a or b is invalid, (a!=b) is always true, which is very tricky.
+ */
+ template<typename U>
+ bool operator !=(const U& other) const { return !(*this == other); }
+};
+
+#define CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \
+template<typename T> \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs) \
+{ \
+ T x = lhs.value(); \
+ T y = rhs.value(); \
+ T result = x OP y; \
+ T is_op_valid \
+ = CheckedInt_internal::is_##NAME##_valid(x, y, result); \
+ /* give the compiler a good chance to perform RVO */ \
+ return CheckedInt<T>(result, \
+ lhs.mIsValid & \
+ rhs.mIsValid & \
+ is_op_valid); \
+}
+
+CHECKEDINT_BASIC_BINARY_OPERATOR(add, +)
+CHECKEDINT_BASIC_BINARY_OPERATOR(sub, -)
+CHECKEDINT_BASIC_BINARY_OPERATOR(mul, *)
+
+// division can't be implemented by CHECKEDINT_BASIC_BINARY_OPERATOR
+// because if rhs == 0, we are not allowed to even try to compute the quotient.
+template<typename T>
+inline CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs)
+{
+ T x = lhs.value();
+ T y = rhs.value();
+ T is_op_valid = CheckedInt_internal::is_div_valid(x, y);
+ T result = is_op_valid ? (x / y) : 0;
+ /* give the compiler a good chance to perform RVO */
+ return CheckedInt<T>(result,
+ lhs.mIsValid &
+ rhs.mIsValid &
+ is_op_valid);
+}
+
+// implement cast_to_CheckedInt<T>(x), making sure that
+// - it allows x to be either a CheckedInt<T> or any integer type that can be casted to T
+// - if x is already a CheckedInt<T>, we just return a reference to it, instead of copying it (optimization)
+
+template<typename T, typename U>
+struct cast_to_CheckedInt_impl
+{
+ typedef CheckedInt<T> return_type;
+ static CheckedInt<T> run(const U& u) { return u; }
+};
+
+template<typename T>
+struct cast_to_CheckedInt_impl<T, CheckedInt<T> >
+{
+ typedef const CheckedInt<T>& return_type;
+ static const CheckedInt<T>& run(const CheckedInt<T>& u) { return u; }
+};
+
+template<typename T, typename U>
+inline typename cast_to_CheckedInt_impl<T, U>::return_type
+cast_to_CheckedInt(const U& u)
+{
+ return cast_to_CheckedInt_impl<T, U>::run(u);
+}
+
+#define CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
+template<typename T> \
+template<typename U> \
+CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(const U &rhs) \
+{ \
+ *this = *this OP cast_to_CheckedInt<T>(rhs); \
+ return *this; \
+} \
+template<typename T, typename U> \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, const U &rhs) \
+{ \
+ return lhs OP cast_to_CheckedInt<T>(rhs); \
+} \
+template<typename T, typename U> \
+inline CheckedInt<T> operator OP(const U & lhs, const CheckedInt<T> &rhs) \
+{ \
+ return cast_to_CheckedInt<T>(lhs) OP rhs; \
+}
+
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
+
+template<typename T, typename U>
+inline bool operator ==(const CheckedInt<T> &lhs, const U &rhs)
+{
+ return lhs == cast_to_CheckedInt<T>(rhs);
+}
+
+template<typename T, typename U>
+inline bool operator ==(const U & lhs, const CheckedInt<T> &rhs)
+{
+ return cast_to_CheckedInt<T>(lhs) == rhs;
+}
+
+} // end namespace WebCore
+
+#endif /* CheckedInt_h */
diff --git a/Source/WebCore/html/canvas/DataView.cpp b/Source/WebCore/html/canvas/DataView.cpp
new file mode 100755
index 000000000..3e55d3776
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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:
+ *
+ * 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"
+#include "DataView.h"
+
+#include "CheckedInt.h"
+#include "ExceptionCode.h"
+
+namespace {
+
+template<typename T>
+union Value {
+ T data;
+ char bytes[sizeof(T)];
+};
+
+}
+
+namespace WebCore {
+
+PassRefPtr<DataView> DataView::create(unsigned length)
+{
+ RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(uint8_t));
+ if (!buffer.get())
+ return 0;
+ return create(buffer, 0, length);
+}
+
+PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+{
+ if (byteOffset > buffer->byteLength())
+ return 0;
+ CheckedInt<uint32_t> checkedOffset(byteOffset);
+ CheckedInt<uint32_t> checkedLength(byteLength);
+ CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
+ if (!checkedMax.valid() || checkedMax.value() > buffer->byteLength())
+ return 0;
+ return adoptRef(new DataView(buffer, byteOffset, byteLength));
+}
+
+DataView::DataView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+ : ArrayBufferView(buffer, byteOffset)
+ , m_byteLength(byteLength)
+{
+}
+
+static bool needToFlipBytes(bool littleEndian)
+{
+#if CPU(BIG_ENDIAN)
+ return littleEndian;
+#else
+ return !littleEndian;
+#endif
+}
+
+inline void swapBytes(char* p, char* q)
+{
+ char temp = *p;
+ *p = *q;
+ *q = temp;
+}
+
+static void flipBytesFor16Bits(char* p)
+{
+ swapBytes(p, p + 1);
+}
+
+static void flipBytesFor32Bits(char* p)
+{
+ swapBytes(p, p + 3);
+ swapBytes(p + 1, p + 2);
+}
+
+static void flipBytesFor64Bits(char* p)
+{
+ swapBytes(p, p + 7);
+ swapBytes(p + 1, p + 6);
+ swapBytes(p + 2, p + 5);
+ swapBytes(p + 3, p + 4);
+}
+
+static void flipBytesIfNeeded(char* value, size_t size, bool littleEndian)
+{
+ if (!needToFlipBytes(littleEndian))
+ return;
+
+ switch (size) {
+ case 1:
+ // Nothing to do.
+ break;
+ case 2:
+ flipBytesFor16Bits(value);
+ break;
+ case 4:
+ flipBytesFor32Bits(value);
+ break;
+ case 8:
+ flipBytesFor64Bits(value);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+template<typename T>
+T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) const
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ // We do not want to load the data directly since it would cause a bus error on architectures that don't support unaligned loads.
+ Value<T> value;
+ memcpy(value.bytes, static_cast<const char*>(m_baseAddress) + byteOffset, sizeof(T));
+ flipBytesIfNeeded(value.bytes, sizeof(T), littleEndian);
+ return value.data;
+}
+
+template<typename T>
+void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode& ec)
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // We do not want to store the data directly since it would cause a bus error on architectures that don't support unaligned stores.
+ Value<T> tempValue;
+ tempValue.data = value;
+ flipBytesIfNeeded(tempValue.bytes, sizeof(T), littleEndian);
+ memcpy(static_cast<char*>(m_baseAddress) + byteOffset, tempValue.bytes, sizeof(T));
+}
+
+int8_t DataView::getInt8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<int8_t>(byteOffset, false, ec);
+}
+
+uint8_t DataView::getUint8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<uint8_t>(byteOffset, false, ec);
+}
+
+int16_t DataView::getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<int16_t>(byteOffset, littleEndian, ec);
+}
+
+uint16_t DataView::getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<uint16_t>(byteOffset, littleEndian, ec);
+}
+
+int32_t DataView::getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<int32_t>(byteOffset, littleEndian, ec);
+}
+
+uint32_t DataView::getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<uint32_t>(byteOffset, littleEndian, ec);
+}
+
+float DataView::getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<float>(byteOffset, littleEndian, ec);
+}
+
+double DataView::getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<double>(byteOffset, littleEndian, ec);
+}
+
+void DataView::setInt8(unsigned byteOffset, int8_t value, ExceptionCode& ec)
+{
+ setData<int8_t>(byteOffset, value, false, ec);
+}
+
+void DataView::setUint8(unsigned byteOffset, uint8_t value, ExceptionCode& ec)
+{
+ setData<uint8_t>(byteOffset, value, false, ec);
+}
+
+void DataView::setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<int16_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint16(unsigned byteOffset, uint16_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<uint16_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setInt32(unsigned byteOffset, int32_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<int32_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint32(unsigned byteOffset, uint32_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<uint32_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<float>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<double>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::neuter()
+{
+ ArrayBufferView::neuter();
+ m_byteLength = 0;
+}
+
+}
diff --git a/Source/WebCore/html/canvas/DataView.h b/Source/WebCore/html/canvas/DataView.h
new file mode 100644
index 000000000..63b156d3d
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.h
@@ -0,0 +1,97 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+#ifndef DataView_h
+#define DataView_h
+
+#include <wtf/ArrayBufferView.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class DataView : public ArrayBufferView {
+public:
+ static PassRefPtr<DataView> create(unsigned length);
+ static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ virtual bool isDataView() const { return true; }
+ virtual unsigned length() const { return m_byteLength; }
+ virtual unsigned byteLength() const { return m_byteLength; }
+ virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; }
+
+ int8_t getInt8(unsigned byteOffset, ExceptionCode&);
+ uint8_t getUint8(unsigned byteOffset, ExceptionCode&);
+ int16_t getInt16(unsigned byteOffset, ExceptionCode& ec) { return getInt16(byteOffset, false, ec); }
+ int16_t getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ uint16_t getUint16(unsigned byteOffset, ExceptionCode& ec) { return getUint16(byteOffset, false, ec); }
+ uint16_t getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ int32_t getInt32(unsigned byteOffset, ExceptionCode& ec) { return getInt32(byteOffset, false, ec); }
+ int32_t getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ uint32_t getUint32(unsigned byteOffset, ExceptionCode& ec) { return getUint32(byteOffset, false, ec); }
+ uint32_t getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ float getFloat32(unsigned byteOffset, ExceptionCode& ec) { return getFloat32(byteOffset, false, ec); }
+ float getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ double getFloat64(unsigned byteOffset, ExceptionCode& ec) { return getFloat64(byteOffset, false, ec); }
+ double getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+
+ void setInt8(unsigned byteOffset, int8_t value, ExceptionCode&);
+ void setUint8(unsigned byteOffset, uint8_t value, ExceptionCode&);
+ void setInt16(unsigned byteOffset, int16_t value, ExceptionCode& ec) { setInt16(byteOffset, value, false, ec); }
+ void setInt16(unsigned byteOffset, int16_t value, bool littleEndian, ExceptionCode&);
+ void setUint16(unsigned byteOffset, uint16_t value, ExceptionCode& ec) { setUint16(byteOffset, value, false, ec); }
+ void setUint16(unsigned byteOffset, uint16_t value, bool littleEndian, ExceptionCode&);
+ void setInt32(unsigned byteOffset, int32_t value, ExceptionCode& ec) { setInt32(byteOffset, value, false, ec); }
+ void setInt32(unsigned byteOffset, int32_t value, bool littleEndian, ExceptionCode&);
+ void setUint32(unsigned byteOffset, uint32_t value, ExceptionCode& ec) { setUint32(byteOffset, value, false, ec); }
+ void setUint32(unsigned byteOffset, uint32_t value, bool littleEndian, ExceptionCode&);
+ void setFloat32(unsigned byteOffset, float value, ExceptionCode& ec) { setFloat32(byteOffset, value, false, ec); }
+ void setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode&);
+ void setFloat64(unsigned byteOffset, double value, ExceptionCode& ec) { setFloat64(byteOffset, value, false, ec); }
+ void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&);
+
+protected:
+ virtual void neuter();
+
+private:
+ DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ template<typename T>
+ inline bool beyondRange(unsigned byteOffset) const { return byteOffset >= m_byteLength || byteOffset + sizeof(T) > m_byteLength; }
+
+ template<typename T>
+ T getData(unsigned byteOffset, bool littleEndian, ExceptionCode&) const;
+
+ template<typename T>
+ void setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode&);
+
+ unsigned m_byteLength;
+};
+
+
+} // namespace WebCore
+
+#endif // DataView_h
diff --git a/Source/WebCore/html/canvas/DataView.idl b/Source/WebCore/html/canvas/DataView.idl
new file mode 100755
index 000000000..bba13c93a
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.idl
@@ -0,0 +1,80 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ CustomConstructor,
+ CustomToJS,
+ NoStaticTables
+ ] DataView : ArrayBufferView {
+ // All these methods raise an exception if they would read or write beyond the end of the view.
+
+ // We have to use custom code because our code generator does not support int8_t type.
+ // int8_t getInt8(in unsigned long byteOffset);
+ // uint8_t getUint8(in unsigned long byteOffset);
+ [Custom] DOMObject getInt8()
+ raises (DOMException);
+ [Custom] DOMObject getUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking] short getInt16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] unsigned short getUint16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] long getInt32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] unsigned long getUint32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // Use custom code to handle NaN case for JSC.
+ [JSCCustom, StrictTypeChecking] float getFloat32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [JSCCustom, StrictTypeChecking] double getFloat64(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // We have to use custom code because our code generator does not support uint8_t type.
+ // void setInt8(in unsigned long byteOffset, in int8_t value);
+ // void setUint8(in unsigned long byteOffset, in uint8_t value);
+ [Custom] void setInt8()
+ raises (DOMException);
+ [Custom] void setUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking] void setInt16(in unsigned long byteOffset, in short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] void setUint16(in unsigned long byteOffset, in unsigned short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] void setInt32(in unsigned long byteOffset, in long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] void setUint32(in unsigned long byteOffset, in unsigned long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] void setFloat32(in unsigned long byteOffset, in float value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking] void setFloat64(in unsigned long byteOffset, in double value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/Float32Array.idl b/Source/WebCore/html/canvas/Float32Array.idl
new file mode 100644
index 000000000..ef6c956b7
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float32Array.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Computer, 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Float32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Float32Array subarray(in [Optional=CallWithDefaultValue] long start,
+ in [Optional] long end);
+
+ // void set(in Float32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Float64Array.idl b/Source/WebCore/html/canvas/Float64Array.idl
new file mode 100644
index 000000000..01495350b
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float64Array.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Float64Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 8;
+
+ readonly attribute unsigned long length;
+ Float64Array subarray(in [Optional=CallWithDefaultValue] long start,
+ in [Optional] long end);
+
+ // void set(in Float64Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int16Array.idl b/Source/WebCore/html/canvas/Int16Array.idl
new file mode 100644
index 000000000..b1a547180
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int16Array.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int16Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 2;
+
+ readonly attribute unsigned long length;
+ Int16Array subarray(in [Optional=CallWithDefaultValue] long start,
+ in [Optional] long end);
+
+ // void set(in Int16Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int32Array.idl b/Source/WebCore/html/canvas/Int32Array.idl
new file mode 100644
index 000000000..bad745d6e
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int32Array.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Int32Array subarray(in [Optional=CallWithDefaultValue] long start,
+ in [Optional] long end);
+
+ // void set(in Int32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int8Array.idl b/Source/WebCore/html/canvas/Int8Array.idl
new file mode 100644
index 000000000..4ae2eace6
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int8Array.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int8Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Int8Array subarray(in [Optional=CallWithDefaultValue] long start,
+ in [Optional] long end);
+
+ // void set(in Int8Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
new file mode 100644
index 000000000..a91c193d5
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "OESStandardDerivatives.h"
+
+namespace WebCore {
+
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+OESStandardDerivatives::~OESStandardDerivatives()
+{
+}
+
+WebGLExtension::ExtensionName OESStandardDerivatives::getName() const
+{
+ return OESStandardDerivativesName;
+}
+
+PassOwnPtr<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
new file mode 100644
index 000000000..af2ea14b9
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef OESStandardDerivatives_h
+#define OESStandardDerivatives_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class OESStandardDerivatives : public WebGLExtension {
+public:
+ static PassOwnPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
+
+ virtual ~OESStandardDerivatives();
+ virtual ExtensionName getName() const;
+
+private:
+ OESStandardDerivatives(WebGLRenderingContext*);
+};
+
+} // namespace WebCore
+
+#endif // OESStandardDerivatives_h
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.idl b/Source/WebCore/html/canvas/OESStandardDerivatives.idl
new file mode 100644
index 000000000..f1d4740b2
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor,
+ DontCheckEnums
+ ] OESStandardDerivatives {
+ const unsigned int FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+ };
+}
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.cpp b/Source/WebCore/html/canvas/OESTextureFloat.cpp
new file mode 100644
index 000000000..3ba150b07
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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:
+ *
+ * 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 "OESTextureFloat.h"
+
+namespace WebCore {
+
+OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+OESTextureFloat::~OESTextureFloat()
+{
+}
+
+WebGLExtension::ExtensionName OESTextureFloat::getName() const
+{
+ return OESTextureFloatName;
+}
+
+PassOwnPtr<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
new file mode 100644
index 000000000..21da31c08
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.h
@@ -0,0 +1,47 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+#ifndef OESTextureFloat_h
+#define OESTextureFloat_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class OESTextureFloat : public WebGLExtension {
+public:
+ static PassOwnPtr<OESTextureFloat> create(WebGLRenderingContext*);
+
+ virtual ~OESTextureFloat();
+ virtual ExtensionName getName() const;
+
+private:
+ OESTextureFloat(WebGLRenderingContext*);
+};
+
+} // namespace WebCore
+
+#endif // OESTextureFloat_h
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.idl b/Source/WebCore/html/canvas/OESTextureFloat.idl
new file mode 100644
index 000000000..950c355c3
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.idl
@@ -0,0 +1,33 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor
+ ] OESTextureFloat {
+ };
+}
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
new file mode 100644
index 000000000..a26d7069f
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "OESVertexArrayObject.h"
+
+#include "Extensions3D.h"
+#include "WebGLRenderingContext.h"
+#include "WebGLVertexArrayObjectOES.h"
+
+namespace WebCore {
+
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+OESVertexArrayObject::~OESVertexArrayObject()
+{
+}
+
+WebGLExtension::ExtensionName OESVertexArrayObject::getName() const
+{
+ return OESVertexArrayObjectName;
+}
+
+PassOwnPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESVertexArrayObject(context));
+}
+
+PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
+{
+ if (m_context->isContextLost())
+ return 0;
+
+ RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
+ m_context->addObject(o.get());
+ return o.release();
+}
+
+void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
+{
+ if (!arrayObject || m_context->isContextLost())
+ return;
+
+ arrayObject->deleteObject();
+}
+
+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());
+}
+
+void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (m_context->isContextLost())
+ return;
+
+ if (arrayObject && arrayObject->context() != m_context) {
+ m_context->graphicsContext3D()->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ Extensions3D* extensions = m_context->graphicsContext3D()->getExtensions();
+ if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
+ extensions->bindVertexArrayOES(arrayObject->object());
+
+ arrayObject->setHasEverBeenBound();
+ m_context->setBoundVertexArrayObject(arrayObject);
+ } else {
+ extensions->bindVertexArrayOES(0);
+
+ m_context->setBoundVertexArrayObject(0);
+ }
+
+ m_context->cleanupAfterGraphicsCall(false);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.h b/Source/WebCore/html/canvas/OESVertexArrayObject.h
new file mode 100644
index 000000000..148df3721
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OESVertexArrayObject_h
+#define OESVertexArrayObject_h
+
+#include "GraphicsTypes3D.h"
+#include "WebGLExtension.h"
+#include "WebGLVertexArrayObjectOES.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+class WebGLRenderingContext;
+class WebGLVertexArrayObjectOES;
+
+typedef int ExceptionCode;
+
+class OESVertexArrayObject : public WebGLExtension {
+public:
+ static PassOwnPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
+
+ virtual ~OESVertexArrayObject();
+ virtual ExtensionName getName() const;
+
+ PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
+ void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
+ GC3Dboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
+ void bindVertexArrayOES(WebGLVertexArrayObjectOES*, ExceptionCode&);
+
+private:
+ OESVertexArrayObject(WebGLRenderingContext*);
+};
+
+} // namespace WebCore
+
+#endif // OESVertexArrayObject_h
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.idl b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
new file mode 100644
index 000000000..cfb6506bb
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor,
+ DontCheckEnums
+ ] OESVertexArrayObject {
+ const unsigned int VERTEX_ARRAY_BINDING_OES = 0x85B5;
+
+ [StrictTypeChecking] WebGLVertexArrayObjectOES createVertexArrayOES();
+ [StrictTypeChecking] void deleteVertexArrayOES(in [Optional=CallWithDefaultValue] WebGLVertexArrayObjectOES arrayObject);
+ [StrictTypeChecking] boolean isVertexArrayOES(in [Optional=CallWithDefaultValue] WebGLVertexArrayObjectOES arrayObject);
+ [StrictTypeChecking] void bindVertexArrayOES(in [Optional=CallWithDefaultValue] WebGLVertexArrayObjectOES arrayObject) raises(DOMException);
+ };
+}
diff --git a/Source/WebCore/html/canvas/Uint16Array.idl b/Source/WebCore/html/canvas/Uint16Array.idl
new file mode 100644
index 000000000..bb08a4f01
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint16Array.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint16Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 2;
+
+ readonly attribute unsigned long length;
+ Uint16Array subarray(in [Optional=CallWithDefaultValue] long start, in [Optional] long end);
+
+ // void set(in Uint16Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Uint32Array.idl b/Source/WebCore/html/canvas/Uint32Array.idl
new file mode 100644
index 000000000..2a87885a7
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint32Array.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Uint32Array subarray(in [Optional=CallWithDefaultValue] long start, in [Optional] long end);
+
+ // void set(in Uint32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Uint8Array.idl b/Source/WebCore/html/canvas/Uint8Array.idl
new file mode 100644
index 000000000..1a6f5889f
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8Array.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint8Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Uint8Array subarray(in [Optional=CallWithDefaultValue] long start, in [Optional] long end);
+
+ // void set(in Uint8Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.h b/Source/WebCore/html/canvas/WebGLActiveInfo.h
new file mode 100644
index 000000000..e75e1f545
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 WebGLActiveInfo_h
+#define WebGLActiveInfo_h
+
+#include "GraphicsContext3D.h"
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLActiveInfo : public RefCounted<WebGLActiveInfo> {
+public:
+ static PassRefPtr<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
+ {
+ return adoptRef(new WebGLActiveInfo(name, type, size));
+ }
+ String name() const { return m_name; }
+ GC3Denum type() const { return m_type; }
+ GC3Dint size() const { return m_size; }
+
+private:
+ WebGLActiveInfo(const String& name, GC3Denum type, GC3Dint size)
+ : m_name(name)
+ , m_type(type)
+ , m_size(size)
+ {
+ ASSERT(name.length());
+ ASSERT(type);
+ ASSERT(size);
+ }
+ String m_name;
+ GC3Denum m_type;
+ GC3Dint m_size;
+};
+
+}
+
+#endif // WebGLActiveInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.idl b/Source/WebCore/html/canvas/WebGLActiveInfo.idl
new file mode 100644
index 000000000..20ab8af90
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=WEBGL,
+ ] WebGLActiveInfo {
+ readonly attribute int size;
+ readonly attribute unsigned int type;
+ readonly attribute DOMString name;
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
new file mode 100644
index 000000000..997dba500
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLBuffer.h"
+
+#include "CheckedInt.h"
+#include "WebGLRenderingContext.h"
+#include <wtf/ArrayBufferView.h>
+
+namespace WebCore {
+
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLBuffer(ctx));
+}
+
+WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_target(0)
+ , m_byteLength(0)
+ , m_nextAvailableCacheEntry(0)
+{
+ setObject(context()->graphicsContext3D()->createBuffer());
+ clearCachedMaxIndices();
+}
+
+void WebGLBuffer::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteBuffer(object);
+}
+
+bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOffset, GC3Dsizeiptr byteLength)
+{
+ if (byteLength < 0 || byteOffset < 0)
+ return false;
+
+ if (array && byteLength) {
+ CheckedInt<GC3Dintptr> checkedOffset(byteOffset);
+ CheckedInt<GC3Dsizeiptr> checkedLength(byteLength);
+ CheckedInt<GC3Dintptr> checkedMax = checkedOffset + checkedLength;
+ if (!checkedMax.valid() || checkedMax.value() > static_cast<int32_t>(array->byteLength()))
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ m_byteLength = byteLength;
+ clearCachedMaxIndices();
+ if (byteLength) {
+ m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1);
+ if (!m_elementArrayBuffer) {
+ m_byteLength = 0;
+ return false;
+ }
+ if (array) {
+ // We must always clone the incoming data because client-side
+ // modifications without calling bufferData or bufferSubData
+ // must never be able to change the validation results.
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()),
+ static_cast<unsigned char*>(array->data()) + byteOffset,
+ byteLength);
+ }
+ } else
+ m_elementArrayBuffer = 0;
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ m_byteLength = byteLength;
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLBuffer::associateBufferData(GC3Dsizeiptr size)
+{
+ if (size < 0)
+ return false;
+ return associateBufferDataImpl(0, 0, size);
+}
+
+bool WebGLBuffer::associateBufferData(ArrayBuffer* array)
+{
+ if (!array)
+ return false;
+ return associateBufferDataImpl(array, 0, array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferData(ArrayBufferView* array)
+{
+ if (!array)
+ return false;
+ return associateBufferDataImpl(array->buffer().get(), array->byteOffset(), array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, ArrayBuffer* array, GC3Dintptr arrayByteOffset, GC3Dsizeiptr byteLength)
+{
+ if (!array || offset < 0 || arrayByteOffset < 0 || byteLength < 0)
+ return false;
+
+ if (byteLength) {
+ CheckedInt<GC3Dintptr> checkedBufferOffset(offset);
+ CheckedInt<GC3Dintptr> checkedArrayOffset(arrayByteOffset);
+ CheckedInt<GC3Dsizeiptr> checkedLength(byteLength);
+ CheckedInt<GC3Dintptr> checkedArrayMax = checkedArrayOffset + checkedLength;
+ CheckedInt<GC3Dintptr> checkedBufferMax = checkedBufferOffset + checkedLength;
+ if (!checkedArrayMax.valid() || checkedArrayMax.value() > static_cast<int32_t>(array->byteLength()) || !checkedBufferMax.valid() || checkedBufferMax.value() > m_byteLength)
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ clearCachedMaxIndices();
+ if (byteLength) {
+ if (!m_elementArrayBuffer)
+ return false;
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + offset,
+ static_cast<unsigned char*>(array->data()) + arrayByteOffset,
+ byteLength);
+ }
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLBuffer::associateBufferSubData(GC3Dintptr offset, ArrayBuffer* array)
+{
+ if (!array)
+ return false;
+ return associateBufferSubDataImpl(offset, array, 0, array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferSubData(GC3Dintptr offset, ArrayBufferView* array)
+{
+ if (!array)
+ return false;
+ return associateBufferSubDataImpl(offset, array->buffer().get(), array->byteOffset(), array->byteLength());
+}
+
+GC3Dsizeiptr WebGLBuffer::byteLength() const
+{
+ return m_byteLength;
+}
+
+int 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;
+}
+
+void WebGLBuffer::setCachedMaxIndex(GC3Denum type, int 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;
+ return;
+ }
+ m_maxIndexCache[m_nextAvailableCacheEntry].type = type;
+ m_maxIndexCache[m_nextAvailableCacheEntry].maxIndex = value;
+ m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % numEntries;
+}
+
+void WebGLBuffer::setTarget(GC3Denum target)
+{
+ // 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;
+}
+
+void WebGLBuffer::clearCachedMaxIndices()
+{
+ memset(m_maxIndexCache, 0, sizeof(m_maxIndexCache));
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h
new file mode 100644
index 000000000..0157ece65
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLBuffer_h
+#define WebGLBuffer_h
+
+#include "WebGLObject.h"
+
+#include <wtf/ArrayBuffer.h>
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLBuffer : public WebGLObject {
+public:
+ virtual ~WebGLBuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
+
+ bool associateBufferData(GC3Dsizeiptr size);
+ bool associateBufferData(ArrayBuffer*);
+ bool associateBufferData(ArrayBufferView*);
+ bool associateBufferSubData(GC3Dintptr offset, ArrayBuffer*);
+ bool associateBufferSubData(GC3Dintptr offset, ArrayBufferView*);
+
+ GC3Dsizeiptr byteLength() const;
+ const 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);
+ // Sets the cached max index for the given type.
+ void setCachedMaxIndex(GC3Denum type, int value);
+
+ GC3Denum getTarget() const { return m_target; }
+ void setTarget(GC3Denum);
+
+ bool hasEverBeenBound() const { return object() && m_target; }
+
+protected:
+ WebGLBuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject o);
+
+private:
+ virtual bool isBuffer() const { return true; }
+
+ GC3Denum m_target;
+
+ RefPtr<ArrayBuffer> m_elementArrayBuffer;
+ GC3Dsizeiptr m_byteLength;
+
+ // Optimization for index validation. For each type of index
+ // (i.e., UNSIGNED_SHORT), cache the maximum index in the
+ // entire buffer.
+ //
+ // This is sufficient to eliminate a lot of work upon each
+ // draw call as long as all bound array buffers are at least
+ // that size.
+ struct MaxIndexCacheEntry {
+ GC3Denum type;
+ int 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.
+ MaxIndexCacheEntry m_maxIndexCache[4];
+ unsigned int m_nextAvailableCacheEntry;
+
+ // Clears all of the cached max indices.
+ void clearCachedMaxIndices();
+
+ // Helper function called by the three associateBufferData().
+ bool associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOffset, GC3Dsizeiptr byteLength);
+ // Helper function called by the two associateBufferSubData().
+ bool associateBufferSubDataImpl(GC3Dintptr offset, ArrayBuffer* array, GC3Dintptr arrayByteOffset, GC3Dsizeiptr byteLength);
+};
+
+} // namespace WebCore
+
+#endif // WebGLBuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.idl b/Source/WebCore/html/canvas/WebGLBuffer.idl
new file mode 100644
index 000000000..312b00911
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ ] WebGLBuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp
new file mode 100644
index 000000000..1eab78723
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLCompressedTextures.h"
+
+#include "Extensions3D.h"
+#include "WebGLRenderingContext.h"
+
+#include <wtf/Int32Array.h>
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+WebGLCompressedTextures::WebGLCompressedTextures(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+ , m_supportsDxt1(false)
+ , m_supportsDxt5(false)
+ , m_supportsEtc1(false)
+ , m_supportsPvrtc(false)
+{
+ Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
+ if (extensions->supports("GL_EXT_texture_compression_dxt1")) {
+ extensions->ensureEnabled("GL_EXT_texture_compression_dxt1");
+ m_supportsDxt1 = true;
+ }
+ if (extensions->supports("GL_EXT_texture_compression_s3tc")) {
+ extensions->ensureEnabled("GL_EXT_texture_compression_s3tc");
+ m_supportsDxt1 = true;
+ m_supportsDxt5 = true;
+ }
+ if (extensions->supports("GL_CHROMIUM_texture_compression_dxt5")) {
+ extensions->ensureEnabled("GL_CHROMIUM_texture_compression_dxt5");
+ m_supportsDxt5 = true;
+ }
+ if (extensions->supports("GL_OES_compressed_ETC1_RGB8_texture")) {
+ extensions->ensureEnabled("GL_OES_compressed_ETC1_RGB8_texture");
+ m_supportsEtc1 = true;
+ }
+ if (extensions->supports("GL_IMG_texture_compression_pvrtc")) {
+ extensions->ensureEnabled("GL_IMG_texture_compression_pvrtc");
+ m_supportsPvrtc = true;
+ }
+
+ if (m_supportsDxt1) {
+ m_formats.append(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
+ m_formats.append(Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ }
+
+ if (m_supportsDxt5)
+ m_formats.append(Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT);
+
+ if (m_supportsEtc1)
+ m_formats.append(Extensions3D::ETC1_RGB8_OES);
+
+ if (m_supportsPvrtc) {
+ m_formats.append(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
+ m_formats.append(Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
+ }
+}
+
+WebGLCompressedTextures::~WebGLCompressedTextures()
+{
+}
+
+WebGLExtension::ExtensionName WebGLCompressedTextures::getName() const
+{
+ return WebKitWebGLCompressedTexturesName;
+}
+
+PassOwnPtr<WebGLCompressedTextures> WebGLCompressedTextures::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLCompressedTextures(context));
+}
+
+bool WebGLCompressedTextures::supported(WebGLRenderingContext* context)
+{
+ Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
+ return extensions->supports("GL_EXT_texture_compression_dxt1")
+ || extensions->supports("GL_EXT_texture_compression_s3tc")
+ || extensions->supports("GL_CHROMIUM_texture_compression_dxt5")
+ || extensions->supports("GL_OES_compressed_ETC1_RGB8_texture")
+ || extensions->supports("GL_IMG_texture_compression_pvrtc");
+}
+
+bool WebGLCompressedTextures::validateCompressedTexFormat(GC3Denum format)
+{
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return m_supportsDxt1;
+ case Extensions3D::ETC1_RGB8_OES:
+ return m_supportsEtc1;
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return m_supportsDxt5;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ return m_supportsPvrtc;
+ }
+ return false;
+}
+
+bool WebGLCompressedTextures::validateCompressedTexFuncData(GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* pixels)
+{
+ GraphicsContext3D* context = m_context->graphicsContext3D();
+ if (!pixels) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (width < 0 || height < 0) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ unsigned int bytesRequired = 0;
+
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::ETC1_RGB8_OES:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 8;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 16;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ bytesRequired = (std::max(width, 8) * std::max(height, 8) + 7) / 8;
+ }
+ break;
+ default:
+ context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ if (pixels->byteLength() != bytesRequired) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLCompressedTextures::validateCompressedTexSubDimensions(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
+{
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case Extensions3D::ETC1_RGB8_OES:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight))
+ return false;
+ if (!xoffset) {
+ if (width != tex->getWidth(target, level))
+ return false;
+ } else {
+ if (width % kBlockWidth)
+ return false;
+ }
+ if (!yoffset) {
+ if (height != tex->getHeight(target, level))
+ return false;
+ } else {
+ if (height % kBlockHeight)
+ return false;
+ }
+ return true;
+ }
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ if (xoffset || yoffset
+ || width != tex->getWidth(target, level) || height != tex->getHeight(target, level)) {
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+void WebGLCompressedTextures::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
+{
+ GraphicsContext3D* context = m_context->graphicsContext3D();
+ if (m_context->isContextLost())
+ return;
+ if (!validateCompressedTexFormat(internalformat)) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (border) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!validateCompressedTexFuncData(width, height, internalformat, data))
+ return;
+ WebGLTexture* tex = m_context->validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!m_context->isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+ context->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data->byteLength(), data->baseAddress());
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ m_context->cleanupAfterGraphicsCall(false);
+}
+
+void WebGLCompressedTextures::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
+{
+ GraphicsContext3D* context = m_context->graphicsContext3D();
+ if (m_context->isContextLost())
+ return;
+ if (!validateCompressedTexFormat(format)) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (!validateCompressedTexFuncData(width, height, format, data))
+ return;
+
+ WebGLTexture* tex = m_context->validateTextureBinding(target, true);
+ if (!tex)
+ return;
+
+ if (format != tex->getInternalFormat(target, level)) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (!validateCompressedTexSubDimensions(target, level, xoffset, yoffset, width, height, format, tex)) {
+ context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ context->compressedTexSubImage2D(target, level, xoffset, yoffset,
+ width, height, format, data->byteLength(), data->baseAddress());
+ m_context->cleanupAfterGraphicsCall(false);
+}
+
+WebGLGetInfo WebGLCompressedTextures::getCompressedTextureFormats()
+{
+ return WebGLGetInfo(Int32Array::create(&m_formats[0], m_formats.size()));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextures.h b/Source/WebCore/html/canvas/WebGLCompressedTextures.h
new file mode 100644
index 000000000..699370668
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextures.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef WebGLCompressedTextures_h
+#define WebGLCompressedTextures_h
+
+#include "ExceptionCode.h"
+#include "WebGLExtension.h"
+#include <wtf/ArrayBufferView.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class WebGLTexture;
+
+class WebGLCompressedTextures : public WebGLExtension {
+public:
+ static PassOwnPtr<WebGLCompressedTextures> create(WebGLRenderingContext*);
+
+ static bool supported(WebGLRenderingContext*);
+
+ virtual ~WebGLCompressedTextures();
+ virtual ExtensionName getName() const;
+
+ 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);
+
+ WebGLGetInfo getCompressedTextureFormats();
+
+private:
+ WebGLCompressedTextures(WebGLRenderingContext*);
+
+ bool validateCompressedTexFuncData(GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* pixels);
+
+ bool validateCompressedTexFormat(GC3Denum format);
+
+ bool validateCompressedTexSubDimensions(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
+
+ bool m_supportsDxt1;
+ bool m_supportsDxt5;
+ bool m_supportsEtc1;
+ bool m_supportsPvrtc;
+
+ Vector<int> m_formats;
+};
+
+} // namespace WebCore
+
+#endif // WebGLCompressedTextures_h
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextures.idl b/Source/WebCore/html/canvas/WebGLCompressedTextures.idl
new file mode 100644
index 000000000..bbd9a256c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextures.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor,
+ DontCheckEnums
+ ] WebGLCompressedTextures {
+ /* 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_DXT5_EXT = 0x83F3;
+ const unsigned int ETC1_RGB8_OES = 0x8D64;
+ const unsigned int COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+ const unsigned int COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+
+ [StrictTypeChecking] void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in long width, in long height, in long border, in ArrayBufferView data);
+ [StrictTypeChecking] void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in long width, in long height, in unsigned long format, in ArrayBufferView data);
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
new file mode 100644
index 000000000..e36e04ef0
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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
new file mode 100644
index 000000000..5391a2b7d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.h
@@ -0,0 +1,87 @@
+/*
+ * 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 WebGLContextAttributes_h
+#define WebGLContextAttributes_h
+
+#include "CanvasContextAttributes.h"
+#include "GraphicsContext3D.h"
+#include <wtf/PassRefPtr.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;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextAttributes_h
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.idl b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
new file mode 100644
index 000000000..56da1c61e
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ OmitConstructor
+ ] WebGLContextAttributes {
+ attribute boolean alpha;
+ attribute boolean depth;
+ attribute boolean stencil;
+ attribute boolean antialias;
+ attribute boolean premultipliedAlpha;
+ attribute boolean preserveDrawingBuffer;
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.cpp b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
new file mode 100644
index 000000000..3351a4b08
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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:
+ *
+ * 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"
+#include "WebGLContextEvent.h"
+
+#include "EventNames.h"
+
+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)
+ , m_statusMessage(initializer.statusMessage)
+{
+}
+
+WebGLContextEvent::~WebGLContextEvent()
+{
+}
+
+const AtomicString& WebGLContextEvent::interfaceName() const
+{
+ return eventNames().interfaceForWebGLContextEvent;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.h b/Source/WebCore/html/canvas/WebGLContextEvent.h
new file mode 100644
index 000000000..036bd9617
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.h
@@ -0,0 +1,69 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+#ifndef WebGLContextEvent_h
+#define WebGLContextEvent_h
+
+#include "Event.h"
+
+namespace WebCore {
+
+struct WebGLContextEventInit : public EventInit {
+ WebGLContextEventInit();
+
+ String statusMessage;
+};
+
+class WebGLContextEvent : 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)
+ {
+ return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ }
+ static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
+ {
+ return adoptRef(new WebGLContextEvent(type, initializer));
+ }
+ virtual ~WebGLContextEvent();
+
+ const String& statusMessage() const { return m_statusMessage; }
+
+ virtual const AtomicString& interfaceName() const;
+
+private:
+ WebGLContextEvent();
+ WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
+ WebGLContextEvent(const AtomicString&, const WebGLContextEventInit&);
+
+ String m_statusMessage;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextEvent_h
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.idl b/Source/WebCore/html/canvas/WebGLContextEvent.idl
new file mode 100644
index 000000000..8b4bbddbc
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.idl
@@ -0,0 +1,35 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=WEBGL,
+ ConstructorTemplate=Event
+ ] WebGLContextEvent : Event {
+ readonly attribute [InitializedByConstructor] DOMString statusMessage;
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
new file mode 100644
index 000000000..f5715b681
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLDebugRendererInfo.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+WebGLDebugRendererInfo::~WebGLDebugRendererInfo()
+{
+}
+
+WebGLExtension::ExtensionName WebGLDebugRendererInfo::getName() const
+{
+ return WebGLDebugRendererInfoName;
+}
+
+PassOwnPtr<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
new file mode 100644
index 000000000..b96c02b74
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef WebGLDebugRendererInfo_h
+#define WebGLDebugRendererInfo_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class WebGLDebugRendererInfo : public WebGLExtension {
+public:
+ enum EnumType {
+ UNMASKED_VENDOR_WEBGL = 0x9245,
+ UNMASKED_RENDERER_WEBGL = 0x9246
+ };
+
+ static PassOwnPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
+
+ virtual ~WebGLDebugRendererInfo();
+ virtual ExtensionName getName() const;
+
+private:
+ WebGLDebugRendererInfo(WebGLRenderingContext*);
+};
+
+} // namespace WebCore
+
+#endif // WebGLDebugRendererInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl
new file mode 100644
index 000000000..da2082a2c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor,
+ DontCheckEnums
+ ] WebGLDebugRendererInfo {
+ const unsigned int UNMASKED_VENDOR_WEBGL = 0x9245;
+ const unsigned int UNMASKED_RENDERER_WEBGL = 0x9246;
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
new file mode 100644
index 000000000..5d2c3176d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLDebugShaders.h"
+
+#include "Extensions3D.h"
+#include "WebGLRenderingContext.h"
+#include "WebGLShader.h"
+
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+WebGLDebugShaders::~WebGLDebugShaders()
+{
+}
+
+WebGLExtension::ExtensionName WebGLDebugShaders::getName() const
+{
+ return WebGLDebugShadersName;
+}
+
+PassOwnPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLDebugShaders(context));
+}
+
+String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (m_context->isContextLost())
+ return String();
+ if (!m_context->validateWebGLObject(shader))
+ return "";
+ return m_context->graphicsContext3D()->getExtensions()->getTranslatedShaderSourceANGLE(shader->object());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.h b/Source/WebCore/html/canvas/WebGLDebugShaders.h
new file mode 100644
index 000000000..2068c6dfd
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef WebGLDebugShaders_h
+#define WebGLDebugShaders_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class WebGLShader;
+
+typedef int ExceptionCode;
+
+class WebGLDebugShaders : public WebGLExtension {
+public:
+ static PassOwnPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
+
+ virtual ~WebGLDebugShaders();
+ virtual ExtensionName getName() const;
+
+ String getTranslatedShaderSource(WebGLShader*, ExceptionCode&);
+
+private:
+ WebGLDebugShaders(WebGLRenderingContext*);
+};
+
+} // namespace WebCore
+
+#endif // WebGLDebugShaders_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.idl b/Source/WebCore/html/canvas/WebGLDebugShaders.idl
new file mode 100644
index 000000000..ce120327d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor
+ ] WebGLDebugShaders {
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getTranslatedShaderSource(in WebGLShader shader) raises(DOMException);
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLExtension.cpp b/Source/WebCore/html/canvas/WebGLExtension.cpp
new file mode 100644
index 000000000..bf62eecec
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLExtension.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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:
+ *
+ * 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 "WebGLExtension.h"
+
+namespace WebCore {
+
+WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
+ : m_context(context)
+{
+}
+
+WebGLExtension::~WebGLExtension()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h
new file mode 100644
index 000000000..4ff969086
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLExtension.h
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+#ifndef WebGLExtension_h
+#define WebGLExtension_h
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+class WebGLExtension {
+public:
+ // Extension names are needed to properly wrap instances in JavaScript objects.
+ enum ExtensionName {
+ WebKitWebGLLoseContextName, // WEBKIT_ prefix until extension is official
+ OESTextureFloatName,
+ OESStandardDerivativesName,
+ OESVertexArrayObjectName,
+ WebGLDebugRendererInfoName,
+ WebGLDebugShadersName,
+ WebKitWebGLCompressedTexturesName, // WEBKIT_ prefix until extension is official
+ };
+
+ void ref() { m_context->ref(); }
+ void deref() { m_context->deref(); }
+ WebGLRenderingContext* context() { return m_context; }
+
+ virtual ~WebGLExtension();
+ virtual ExtensionName getName() const = 0;
+
+protected:
+ WebGLExtension(WebGLRenderingContext*);
+ WebGLRenderingContext* m_context;
+};
+
+} // namespace WebCore
+
+#endif // WebGLExtension_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
new file mode 100644
index 000000000..d1af518c0
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLFramebuffer.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+namespace {
+
+ bool isAttachmentComplete(WebGLObject* attachedObject, GC3Denum attachment)
+ {
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
+ return false;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
+ return false;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
+ return false;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ if (!buffer->getWidth() || !buffer->getHeight())
+ return false;
+ return true;
+ }
+
+ GC3Dsizei getImageWidth(WebGLObject* attachedObject)
+ {
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ return buffer->getWidth();
+ }
+
+ GC3Dsizei getImageHeight(WebGLObject* attachedObject)
+ {
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ return buffer->getHeight();
+ }
+
+ bool isUninitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
+ && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
+ return true;
+ return false;
+ }
+
+ void setInitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
+ (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
+ }
+
+ bool isValid(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) {
+ if (!(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isValid())
+ return false;
+ }
+ return true;
+ }
+
+} // anonymous namespace
+
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLFramebuffer(ctx));
+}
+
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_hasEverBeenBound(false)
+ , m_texTarget(0)
+ , m_texLevel(-1)
+{
+ setObject(context()->graphicsContext3D()->createFramebuffer());
+}
+
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
+{
+ ASSERT(isBound());
+ if (!object())
+ return;
+ removeAttachmentFromBoundFramebuffer(attachment);
+ if (texture && !texture->object())
+ texture = 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ m_colorAttachment = texture;
+ if (texture) {
+ m_texTarget = texTarget;
+ m_texLevel = level;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_depthAttachment = texture;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_stencilAttachment = texture;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_depthStencilAttachment = texture;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ if (texture)
+ texture->onAttached();
+}
+
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
+{
+ ASSERT(isBound());
+ if (!object())
+ return;
+ removeAttachmentFromBoundFramebuffer(attachment);
+ if (renderbuffer && !renderbuffer->object())
+ renderbuffer = 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ m_colorAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_depthAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_stencilAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_depthStencilAttachment = renderbuffer;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ if (renderbuffer)
+ renderbuffer->onAttached();
+}
+
+WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
+{
+ if (!object())
+ return 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ return m_colorAttachment.get();
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ return m_depthAttachment.get();
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ return m_stencilAttachment.get();
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ return m_depthStencilAttachment.get();
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
+{
+ ASSERT(isBound());
+ if (!object())
+ return;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ if (m_colorAttachment) {
+ m_colorAttachment->onDetached();
+ m_colorAttachment = 0;
+ m_texTarget = 0;
+ m_texLevel = -1;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ if (m_depthAttachment) {
+ m_depthAttachment->onDetached();
+ m_depthAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ if (m_stencilAttachment) {
+ m_stencilAttachment->onDetached();
+ m_stencilAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ if (m_depthStencilAttachment) {
+ m_depthStencilAttachment->onDetached();
+ m_depthStencilAttachment = 0;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLObject* attachment)
+{
+ ASSERT(isBound());
+ if (!object())
+ return;
+ if (!attachment)
+ return;
+ GraphicsContext3D* gc3d = context()->graphicsContext3D();
+ if (attachment == m_colorAttachment.get()) {
+ if (attachment->isRenderbuffer())
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, 0);
+ else
+ gc3d->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, m_texTarget, 0, m_texLevel);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::COLOR_ATTACHMENT0);
+ }
+ if (attachment == m_depthAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_ATTACHMENT);
+ }
+ if (attachment == m_stencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::STENCIL_ATTACHMENT);
+ }
+ if (attachment == m_depthStencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT);
+ }
+}
+
+GC3Dsizei WebGLFramebuffer::getColorBufferWidth() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer())
+ return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getWidth();
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getWidth(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+GC3Dsizei WebGLFramebuffer::getColorBufferHeight() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer())
+ return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getHeight();
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getHeight(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+GC3Denum WebGLFramebuffer::getColorBufferFormat() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer()) {
+ unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
+ switch (format) {
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ return GraphicsContext3D::RGBA;
+ case GraphicsContext3D::RGB565:
+ return GraphicsContext3D::RGB;
+ }
+ return 0;
+ }
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+GC3Denum WebGLFramebuffer::checkStatus() const
+{
+ unsigned int count = 0;
+ GC3Dsizei width = 0, height = 0;
+ if (isDepthAttached()) {
+ if (!isAttachmentComplete(m_depthAttachment.get(), GraphicsContext3D::DEPTH_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ width = getImageWidth(m_depthAttachment.get());
+ height = getImageHeight(m_depthAttachment.get());
+ count++;
+ }
+ if (isStencilAttached()) {
+ if (!isAttachmentComplete(m_stencilAttachment.get(), GraphicsContext3D::STENCIL_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if (!count) {
+ width = getImageWidth(m_stencilAttachment.get());
+ height = getImageHeight(m_stencilAttachment.get());
+ } else {
+ if (width != getImageWidth(m_stencilAttachment.get()) || height != getImageHeight(m_stencilAttachment.get()))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ count++;
+ }
+ if (isDepthStencilAttached()) {
+ if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if (!isValid(m_depthStencilAttachment.get()))
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (!count) {
+ width = getImageWidth(m_depthStencilAttachment.get());
+ height = getImageHeight(m_depthStencilAttachment.get());
+ } else {
+ if (width != getImageWidth(m_depthStencilAttachment.get()) || height != getImageHeight(m_depthStencilAttachment.get()))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ count++;
+ }
+ // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments.
+ if (count > 1)
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (isColorAttached()) {
+ // FIXME: if color buffer is texture, is ALPHA, LUMINANCE or LUMINANCE_ALPHA valid?
+ if (!getColorBufferFormat())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if (!count) {
+ if (!getColorBufferWidth() || !getColorBufferHeight())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ } else {
+ if (width != getColorBufferWidth() || height != getColorBufferHeight())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ } else {
+ if (!count)
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ }
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+}
+
+bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
+{
+ if (checkStatus() != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+ return false;
+ if (needToInitializeRenderbuffers)
+ return initializeRenderbuffers();
+ return true;
+}
+
+void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
+{
+ if (m_colorAttachment)
+ m_colorAttachment->onDetached();
+ if (m_depthAttachment)
+ m_depthAttachment->onDetached();
+ if (m_stencilAttachment)
+ m_stencilAttachment->onDetached();
+ if (m_depthStencilAttachment)
+ m_depthStencilAttachment->onDetached();
+ context()->graphicsContext3D()->deleteFramebuffer(object);
+}
+
+bool WebGLFramebuffer::initializeRenderbuffers()
+{
+ ASSERT(object());
+ bool initColor = false, initDepth = false, initStencil = false;
+ GC3Dbitfield mask = 0;
+ if (isUninitialized(m_colorAttachment.get())) {
+ initColor = true;
+ mask |= GraphicsContext3D::COLOR_BUFFER_BIT;
+ }
+ if (isUninitialized(m_depthAttachment.get())) {
+ initDepth = true;
+ mask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ }
+ if (isUninitialized(m_stencilAttachment.get())) {
+ initStencil = true;
+ mask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ }
+ if (isUninitialized(m_depthStencilAttachment.get())) {
+ initDepth = true;
+ initStencil = true;
+ mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
+ }
+ if (!initColor && !initDepth && !initStencil)
+ return true;
+
+ // We only clear un-initialized renderbuffers when they are ready to be
+ // read, i.e., when the framebuffer is complete.
+ GraphicsContext3D* g3d = context()->graphicsContext3D();
+ if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+ return false;
+
+ GC3Dfloat colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0;
+ GC3Dint stencilClearValue = 0;
+ GC3Dboolean colorMask[] = {0, 0, 0, 0}, depthMask = 0;
+ GC3Duint stencilMask = 0xffffffff;
+ GC3Dboolean isScissorEnabled = 0;
+ GC3Dboolean isDitherEnabled = 0;
+ if (initColor) {
+ g3d->getFloatv(GraphicsContext3D::COLOR_CLEAR_VALUE, colorClearValue);
+ g3d->getBooleanv(GraphicsContext3D::COLOR_WRITEMASK, colorMask);
+ g3d->clearColor(0, 0, 0, 0);
+ g3d->colorMask(true, true, true, true);
+ }
+ if (initDepth) {
+ g3d->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &depthClearValue);
+ g3d->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
+ g3d->clearDepth(0);
+ g3d->depthMask(true);
+ }
+ if (initStencil) {
+ g3d->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &stencilClearValue);
+ g3d->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<GC3Dint*>(&stencilMask));
+ g3d->clearStencil(0);
+ g3d->stencilMask(0xffffffff);
+ }
+ isScissorEnabled = g3d->isEnabled(GraphicsContext3D::SCISSOR_TEST);
+ g3d->disable(GraphicsContext3D::SCISSOR_TEST);
+ isDitherEnabled = g3d->isEnabled(GraphicsContext3D::DITHER);
+ g3d->disable(GraphicsContext3D::DITHER);
+
+ g3d->clear(mask);
+
+ if (initColor) {
+ g3d->clearColor(colorClearValue[0], colorClearValue[1], colorClearValue[2], colorClearValue[3]);
+ g3d->colorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
+ }
+ if (initDepth) {
+ g3d->clearDepth(depthClearValue);
+ g3d->depthMask(depthMask);
+ }
+ if (initStencil) {
+ g3d->clearStencil(stencilClearValue);
+ g3d->stencilMask(stencilMask);
+ }
+ if (isScissorEnabled)
+ g3d->enable(GraphicsContext3D::SCISSOR_TEST);
+ else
+ g3d->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (isDitherEnabled)
+ g3d->enable(GraphicsContext3D::DITHER);
+ else
+ g3d->disable(GraphicsContext3D::DITHER);
+
+ if (initColor)
+ setInitialized(m_colorAttachment.get());
+ if (initDepth && initStencil && m_depthStencilAttachment)
+ setInitialized(m_depthStencilAttachment.get());
+ else {
+ if (initDepth)
+ setInitialized(m_depthAttachment.get());
+ if (initStencil)
+ setInitialized(m_stencilAttachment.get());
+ }
+ return true;
+}
+
+bool WebGLFramebuffer::isBound() const
+{
+ return (context()->m_framebufferBinding.get() == this);
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
new file mode 100644
index 000000000..110f51395
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLFramebuffer_h
+#define WebGLFramebuffer_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderbuffer;
+class WebGLTexture;
+
+class WebGLFramebuffer : public WebGLObject {
+public:
+ virtual ~WebGLFramebuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
+ // If an object is attached to the currently bound framebuffer, remove it.
+ void removeAttachmentFromBoundFramebuffer(WebGLObject*);
+ // If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
+ void removeAttachmentFromBoundFramebuffer(GC3Denum);
+ WebGLObject* getAttachment(GC3Denum) const;
+
+ GC3Denum getColorBufferFormat() const;
+ GC3Dsizei getColorBufferWidth() const;
+ GC3Dsizei getColorBufferHeight() const;
+
+ // This should always be called before drawArray, drawElements, clear,
+ // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
+ // currently bound.
+ // Return false if the framebuffer is incomplete; otherwise initialize
+ // the buffers if they haven't been initialized and
+ // needToInitializeRenderbuffers is true.
+ bool onAccess(bool needToInitializeRenderbuffers);
+
+ // Software version of glCheckFramebufferStatus(), except that when
+ // FRAMEBUFFER_COMPLETE is returned, it is still possible for
+ // glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
+ // depending on hardware implementation.
+ GC3Denum checkStatus() const;
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+protected:
+ WebGLFramebuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isFramebuffer() const { return true; }
+
+ // Return false if framebuffer is incomplete.
+ bool initializeRenderbuffers();
+
+ // Check if the framebuffer is currently bound.
+ bool isBound() const;
+
+ bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
+ bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
+ bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
+ bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
+
+ RefPtr<WebGLObject> m_colorAttachment;
+ RefPtr<WebGLObject> m_depthAttachment;
+ RefPtr<WebGLObject> m_stencilAttachment;
+ RefPtr<WebGLObject> m_depthStencilAttachment;
+
+ bool m_hasEverBeenBound;
+
+ GC3Denum m_texTarget;
+ GC3Dint m_texLevel;
+};
+
+} // namespace WebCore
+
+#endif // WebGLFramebuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.idl b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
new file mode 100644
index 000000000..d0caa917f
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLFramebuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
new file mode 100644
index 000000000..bce383676
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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 <wtf/Float32Array.h>
+#include <wtf/Int32Array.h>
+#include <wtf/Uint8Array.h>
+
+namespace WebCore {
+
+WebGLGetInfo::WebGLGetInfo(bool value)
+ : m_type(kTypeBool)
+ , m_bool(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
+ : m_type(kTypeBoolArray)
+{
+ 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_float(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(int value)
+ : m_type(kTypeInt)
+ , m_int(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo()
+ : m_type(kTypeNull)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(const String& value)
+ : m_type(kTypeString)
+ , m_string(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(unsigned int value)
+ : m_type(kTypeUnsignedInt)
+ , m_unsignedInt(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLBuffer> value)
+ : m_type(kTypeWebGLBuffer)
+ , m_webglBuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Float32Array> value)
+ : m_type(kTypeWebGLFloatArray)
+ , m_webglFloatArray(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value)
+ : m_type(kTypeWebGLFramebuffer)
+ , m_webglFramebuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Int32Array> value)
+ : m_type(kTypeWebGLIntArray)
+ , m_webglIntArray(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLProgram> value)
+ : m_type(kTypeWebGLProgram)
+ , m_webglProgram(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value)
+ : m_type(kTypeWebGLRenderbuffer)
+ , m_webglRenderbuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLTexture> value)
+ : m_type(kTypeWebGLTexture)
+ , m_webglTexture(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
+ : m_type(kTypeWebGLUnsignedByteArray)
+ , m_webglUnsignedByteArray(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value)
+ : m_type(kTypeWebGLVertexArrayObjectOES)
+ , 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<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
new file mode 100644
index 000000000..f747a0902
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.h
@@ -0,0 +1,138 @@
+/*
+ * 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 "PlatformString.h"
+#include "WebGLBuffer.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
+#include "WebGLVertexArrayObjectOES.h"
+
+#include <wtf/Float32Array.h>
+#include <wtf/Int32Array.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Uint8Array.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,
+ 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<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<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<WebGLVertexArrayObjectOES> m_webglVertexArrayObject;
+};
+
+} // namespace WebCore
+
+#endif // WebGLGetInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.cpp b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
new file mode 100644
index 000000000..244f3dc18
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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:
+ *
+ * 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 "WebGLLoseContext.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
+ : WebGLExtension(context)
+{
+}
+
+WebGLLoseContext::~WebGLLoseContext()
+{
+}
+
+WebGLExtension::ExtensionName WebGLLoseContext::getName() const
+{
+ return WebKitWebGLLoseContextName;
+}
+
+PassOwnPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLLoseContext(context));
+}
+
+void WebGLLoseContext::loseContext()
+{
+ m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+}
+
+void WebGLLoseContext::restoreContext()
+{
+ m_context->forceRestoreContext();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.h b/Source/WebCore/html/canvas/WebGLLoseContext.h
new file mode 100644
index 000000000..a326e0852
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.h
@@ -0,0 +1,52 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+#ifndef WebGLLoseContext_h
+#define WebGLLoseContext_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class WebGLRenderingContext;
+
+class WebGLLoseContext : public WebGLExtension {
+public:
+ static PassOwnPtr<WebGLLoseContext> create(WebGLRenderingContext*);
+
+ virtual ~WebGLLoseContext();
+ virtual ExtensionName getName() const;
+
+ 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
new file mode 100644
index 000000000..50955cbb6
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.idl
@@ -0,0 +1,35 @@
+/*
+ * 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:
+ *
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplContext,
+ OmitConstructor
+ ] WebGLLoseContext {
+ [StrictTypeChecking] void loseContext();
+ [StrictTypeChecking] void restoreContext();
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
new file mode 100644
index 000000000..7b629a69c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLObject.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLObject::WebGLObject(WebGLRenderingContext* context)
+ : m_object(0)
+ , m_context(context)
+ , m_attachmentCount(0)
+ , m_deleted(false)
+{
+}
+
+WebGLObject::~WebGLObject()
+{
+ if (m_context)
+ m_context->removeObject(this);
+}
+
+void WebGLObject::setObject(Platform3DObject object)
+{
+ // object==0 && m_deleted==false indicating an uninitialized state;
+ ASSERT(!m_object && !m_deleted);
+ m_object = object;
+}
+
+void WebGLObject::deleteObject()
+{
+ m_deleted = true;
+ if (!m_context || !m_object)
+ return;
+ if (!m_attachmentCount) {
+ m_context->graphicsContext3D()->makeContextCurrent();
+ deleteObjectImpl(m_object);
+ m_object = 0;
+ }
+}
+
+void WebGLObject::detachContext()
+{
+ m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
+ if (m_context) {
+ deleteObject();
+ m_context->removeObject(this);
+ m_context = 0;
+ }
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
new file mode 100644
index 000000000..44cc36f6b
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLObject_h
+#define WebGLObject_h
+
+#include "GraphicsContext3D.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderingContext;
+
+class WebGLObject : public RefCounted<WebGLObject> {
+public:
+ virtual ~WebGLObject();
+
+ Platform3DObject object() const { return m_object; }
+
+ // deleteObject may not always delete the OpenGL resource. For programs and
+ // shaders, deletion is delayed until they are no longer attached.
+ // FIXME: revisit this when resource sharing between contexts are implemented.
+ void deleteObject();
+
+ void detachContext();
+
+ WebGLRenderingContext* context() const { return m_context; }
+
+ 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; }
+
+ void onAttached() { ++m_attachmentCount; }
+ void onDetached()
+ {
+ if (m_attachmentCount)
+ --m_attachmentCount;
+ if (m_deleted)
+ deleteObject();
+ }
+
+ // This indicates whether the client side issue a delete call already, not
+ // whether the OpenGL resource is deleted.
+ // object()==0 indicates the OpenGL resource is deleted.
+ bool isDeleted() { return m_deleted; }
+
+protected:
+ WebGLObject(WebGLRenderingContext*);
+
+ // setObject should be only called once right after creating a WebGLObject.
+ void setObject(Platform3DObject);
+
+ // deleteObjectImpl should be only called once to delete the OpenGL resource.
+ virtual void deleteObjectImpl(Platform3DObject) = 0;
+
+private:
+ Platform3DObject m_object;
+ WebGLRenderingContext* m_context;
+ unsigned m_attachmentCount;
+ bool m_deleted;
+};
+
+} // namespace WebCore
+
+#endif // WebGLObject_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
new file mode 100644
index 000000000..d3efda47d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLProgram.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLProgram(ctx));
+}
+
+WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_linkStatus(false)
+ , m_linkCount(0)
+{
+ setObject(context()->graphicsContext3D()->createProgram());
+}
+
+void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
+{
+ context()->graphicsContext3D()->deleteProgram(obj);
+ if (m_vertexShader) {
+ m_vertexShader->onDetached();
+ m_vertexShader = 0;
+ }
+ if (m_fragmentShader) {
+ m_fragmentShader->onDetached();
+ m_fragmentShader = 0;
+ }
+}
+
+bool WebGLProgram::cacheActiveAttribLocations()
+{
+ m_activeAttribLocations.clear();
+ if (!object())
+ return false;
+ GraphicsContext3D* context3d = context()->graphicsContext3D();
+
+ // Assume link status has already been cached.
+ if (!m_linkStatus)
+ return false;
+
+ GC3Dint numAttribs = 0;
+ context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_ATTRIBUTES, &numAttribs);
+ m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
+ for (int i = 0; i < numAttribs; ++i) {
+ ActiveInfo info;
+ context3d->getActiveAttrib(object(), i, info);
+ m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.charactersWithNullTermination());
+ }
+
+ return true;
+}
+
+unsigned WebGLProgram::numActiveAttribLocations() const
+{
+ return m_activeAttribLocations.size();
+}
+
+GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index) const
+{
+ if (index >= numActiveAttribLocations())
+ return -1;
+ return m_activeAttribLocations[index];
+}
+
+bool WebGLProgram::isUsingVertexAttrib0() const
+{
+ for (unsigned ii = 0; ii < numActiveAttribLocations(); ++ii) {
+ if (!getActiveAttribLocation(ii))
+ return true;
+ }
+ return false;
+}
+
+WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type)
+{
+ switch (type) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ return m_vertexShader.get();
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ return m_fragmentShader.get();
+ default:
+ return 0;
+ }
+}
+
+bool WebGLProgram::attachShader(WebGLShader* shader)
+{
+ if (!shader || !shader->object())
+ return false;
+ switch (shader->getType()) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ if (m_vertexShader)
+ return false;
+ m_vertexShader = shader;
+ return true;
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ if (m_fragmentShader)
+ return false;
+ m_fragmentShader = shader;
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLProgram::detachShader(WebGLShader* shader)
+{
+ if (!shader || !shader->object())
+ return false;
+ switch (shader->getType()) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ if (m_vertexShader != shader)
+ return false;
+ m_vertexShader = 0;
+ return true;
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ if (m_fragmentShader != shader)
+ return false;
+ m_fragmentShader = 0;
+ return true;
+ default:
+ return false;
+ }
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
new file mode 100644
index 000000000..0dd3ba0fa
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLProgram_h
+#define WebGLProgram_h
+
+#include "WebGLObject.h"
+
+#include "WebGLShader.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WebGLProgram : public WebGLObject {
+public:
+ virtual ~WebGLProgram() { deleteObject(); }
+
+ static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
+
+ // cacheActiveAttribLocation() is only called once after linkProgram()
+ // succeeds.
+ bool cacheActiveAttribLocations();
+ unsigned numActiveAttribLocations() const;
+ GC3Dint getActiveAttribLocation(GC3Duint index) const;
+
+ bool isUsingVertexAttrib0() const;
+
+ bool getLinkStatus() const { return m_linkStatus; }
+ void setLinkStatus(bool status) { m_linkStatus = status; }
+
+ unsigned getLinkCount() const { return m_linkCount; }
+
+ // This is to be called everytime after the program is successfully linked.
+ // We don't deal with integer overflow here, assuming in reality a program
+ // will never be linked so many times.
+ void increaseLinkCount() { ++m_linkCount; }
+
+ WebGLShader* getAttachedShader(GC3Denum);
+ bool attachShader(WebGLShader*);
+ bool detachShader(WebGLShader*);
+
+protected:
+ WebGLProgram(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isProgram() const { return true; }
+
+ Vector<GC3Dint> m_activeAttribLocations;
+
+ GC3Dint m_linkStatus;
+
+ // This is used to track whether a WebGLUniformLocation belongs to this
+ // program or not.
+ unsigned m_linkCount;
+
+ RefPtr<WebGLShader> m_vertexShader;
+ RefPtr<WebGLShader> m_fragmentShader;
+};
+
+} // namespace WebCore
+
+#endif // WebGLProgram_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.idl b/Source/WebCore/html/canvas/WebGLProgram.idl
new file mode 100644
index 000000000..326f1c376
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLProgram {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
new file mode 100644
index 000000000..93b9165c9
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLRenderbuffer.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLRenderbuffer(ctx));
+}
+
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_internalFormat(GraphicsContext3D::RGBA4)
+ , m_initialized(false)
+ , m_width(0)
+ , m_height(0)
+ , m_isValid(true)
+ , m_hasEverBeenBound(false)
+{
+ setObject(context()->graphicsContext3D()->createRenderbuffer());
+}
+
+void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteRenderbuffer(object);
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.h b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
new file mode 100644
index 000000000..4b47bf5d3
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLRenderbuffer_h
+#define WebGLRenderbuffer_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderbuffer : public WebGLObject {
+public:
+ virtual ~WebGLRenderbuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+
+ void setInternalFormat(GC3Denum internalformat)
+ {
+ m_internalFormat = internalformat;
+ m_initialized = false;
+ }
+ GC3Denum getInternalFormat() const { return m_internalFormat; }
+
+ void setSize(GC3Dsizei width, GC3Dsizei height)
+ {
+ m_width = width;
+ m_height = height;
+ }
+ GC3Dsizei getWidth() const { return m_width; }
+ GC3Dsizei getHeight() const { return m_height; }
+
+ void setIsValid(bool isValid) { m_isValid = isValid; }
+ bool isValid() const { return m_isValid; }
+
+ bool isInitialized() const { return m_initialized; }
+ void setInitialized() { m_initialized = true; }
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+protected:
+ WebGLRenderbuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isRenderbuffer() const { return true; }
+
+ GC3Denum m_internalFormat;
+ bool m_initialized;
+ GC3Dsizei m_width, m_height;
+ bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported.
+
+ bool m_hasEverBeenBound;
+};
+
+} // namespace WebCore
+
+#endif // WebGLRenderbuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
new file mode 100644
index 000000000..a6518ea2e
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLRenderbuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
new file mode 100644
index 000000000..a7b9cf648
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -0,0 +1,5087 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLRenderingContext.h"
+
+#include "CachedImage.h"
+#include "CanvasPixelArray.h"
+#include "CheckedInt.h"
+#include "Console.h"
+#include "DOMWindow.h"
+#include "ExceptionCode.h"
+#include "Extensions3D.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntSize.h"
+#include "NotImplemented.h"
+#include "OESStandardDerivatives.h"
+#include "OESTextureFloat.h"
+#include "OESVertexArrayObject.h"
+#include "Page.h"
+#include "RenderBox.h"
+#include "RenderLayer.h"
+#include "Settings.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLBuffer.h"
+#include "WebGLCompressedTextures.h"
+#include "WebGLContextAttributes.h"
+#include "WebGLContextEvent.h"
+#include "WebGLDebugRendererInfo.h"
+#include "WebGLDebugShaders.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLLoseContext.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLShader.h"
+#include "WebGLTexture.h"
+#include "WebGLUniformLocation.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
+#include <wtf/Uint16Array.h>
+#include <wtf/text/StringBuilder.h>
+
+#if PLATFORM(QT)
+#undef emit
+#endif
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+
+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;
+ }
+
+ // 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()
+ {
+ 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)
+ {
+ if (m_position + 1 >= m_length)
+ return false;
+ character = m_sourceString[m_position + 1];
+ return true;
+ }
+
+ UChar current()
+ {
+ ASSERT(m_position < m_length);
+ return m_sourceString[m_position];
+ }
+
+ void advance()
+ {
+ ++m_position;
+ }
+
+ bool isNewline(UChar character)
+ {
+ // 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 {
+public:
+ explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
+ virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
+ virtual ~WebGLRenderingContextLostCallback() {}
+private:
+ WebGLRenderingContext* m_context;
+};
+
+PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
+{
+ HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow();
+ GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
+
+ if (attributes.antialias) {
+ Page* p = canvas->document()->page();
+ if (p && !p->settings()->openGLMultisamplingEnabled())
+ attributes.antialias = false;
+ }
+
+ attributes.noExtensions = true;
+#if PLATFORM(CHROMIUM)
+ attributes.shareResources = true;
+#else
+ attributes.shareResources = false;
+#endif
+
+
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
+
+ if (!context) {
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
+ return nullptr;
+ }
+
+ return adoptPtr(new WebGLRenderingContext(canvas, context, attributes));
+}
+
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
+ GraphicsContext3D::Attributes attributes)
+ : CanvasRenderingContext(passedCanvas)
+ , m_context(context)
+ , m_drawingBuffer(0)
+ , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
+ , m_restoreAllowed(false)
+ , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
+ , m_videoCache(4)
+ , m_contextLost(false)
+ , m_contextLostMode(SyntheticLostContext)
+ , m_attributes(attributes)
+{
+ ASSERT(m_context);
+
+#if PLATFORM(CHROMIUM)
+ // Create the DrawingBuffer and initialize the platform layer.
+ m_drawingBuffer = DrawingBuffer::create(m_context.get(), IntSize(canvas()->width(), canvas()->height()), !m_attributes.preserveDrawingBuffer);
+#endif
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->bind();
+
+ setupFlags();
+ initializeNewContext();
+}
+
+void WebGLRenderingContext::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 = 0;
+ m_currentProgram = 0;
+ m_framebufferBinding = 0;
+ m_renderbufferBinding = 0;
+ m_depthMask = true;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_layerCleared = false;
+
+ 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);
+ m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+ m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
+ addObject(m_defaultVertexArrayObject.get());
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+ m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+ if (!isGLES2NPOTStrict())
+ createFallbackBlackTextures1x1();
+ if (!isGLES2Compliant())
+ initVertexAttrib0();
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
+
+ m_context->reshape(canvas()->width(), canvas()->height());
+ m_context->viewport(0, 0, canvas()->width(), canvas()->height());
+
+ m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
+}
+
+void WebGLRenderingContext::setupFlags()
+{
+ ASSERT(m_context);
+
+ 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");
+ }
+}
+
+bool WebGLRenderingContext::allowPrivilegedExtensions() const
+{
+ Page* p = canvas()->document()->page();
+ if (p && p->settings())
+ return p->settings()->privilegedWebGLExtensionsEnabled();
+ return false;
+}
+
+WebGLRenderingContext::~WebGLRenderingContext()
+{
+ detachAndRemoveAllObjects();
+ m_context->setContextLostCallback(nullptr);
+}
+
+void WebGLRenderingContext::markContextChanged()
+{
+ if (m_framebufferBinding)
+ return;
+
+ m_context->markContextChanged();
+
+ m_layerCleared = false;
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing()) {
+ m_markedCanvasDirty = true;
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+ } else {
+#endif
+ if (!m_markedCanvasDirty) {
+ m_markedCanvasDirty = true;
+ canvas()->didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ }
+#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;
+
+ if (m_framebufferBinding) {
+ if (m_drawingBuffer)
+ m_drawingBuffer->bind();
+ else
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ }
+ 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);
+ }
+ m_context->clear(clearMask);
+
+ // 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);
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ m_layerCleared = true;
+
+ return combinedClear;
+}
+
+void WebGLRenderingContext::markLayerComposited()
+{
+ m_context->markLayerComposited();
+}
+
+void WebGLRenderingContext::paintRenderingResultsToCanvas()
+{
+ // 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(this);
+
+#if USE(ACCELERATED_COMPOSITING) && PLATFORM(CHROMIUM)
+ if (m_drawingBuffer)
+ m_drawingBuffer->paintCompositedResultsToCanvas(this);
+#endif
+
+ 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(this, 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;
+}
+
+bool WebGLRenderingContext::paintsIntoCanvasBuffer() const
+{
+ return m_context->paintsIntoCanvasBuffer();
+}
+
+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->hasLayer())
+ renderBox->layer()->contentChanged(RenderLayer::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));
+ else
+ m_context->reshape(width, height);
+}
+
+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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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(program) || !validateWebGLObject(shader))
+ return;
+ if (!program->attachShader(shader)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(program))
+ return;
+ if (!validateLocationLength(name))
+ return;
+ if (!validateString(name))
+ return;
+ m_context->bindAttribLocation(objectOrZero(program), index, name);
+ cleanupAfterGraphicsCall(false);
+}
+
+bool WebGLRenderingContext::checkObjectToBeBound(WebGLObject* object, bool& deleted)
+{
+ deleted = false;
+ if (isContextLost())
+ return false;
+ if (object) {
+ if (object->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ deleted = !object->object();
+ }
+ return true;
+}
+
+void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound(buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (target == GraphicsContext3D::ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+ else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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(buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_framebufferBinding = buffer;
+ 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();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound(renderBuffer, deleted))
+ return;
+ if (deleted)
+ renderBuffer = 0;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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(texture, deleted))
+ return;
+ if (deleted)
+ texture = 0;
+ if (texture && texture->getTarget() && texture->getTarget() != target) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ GC3Dint maxLevel = 0;
+ if (target == GraphicsContext3D::TEXTURE_2D) {
+ m_textureUnits[m_activeTextureUnit].m_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].m_textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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(mode))
+ return;
+ m_context->blendEquation(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
+{
+ if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
+ return;
+ m_context->blendEquationSeparate(modeRGB, modeAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+ if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor))
+ return;
+ m_context->blendFunc(sfactor, dfactor);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
+{
+ if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB))
+ return;
+ m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (size < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(size)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferData(target, size, usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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(target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBuffer* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, offset, data->byteLength(), data->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBufferView* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, offset, data->byteLength(), data->baseAddress());
+ cleanupAfterGraphicsCall(false);
+}
+
+GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
+{
+ if (isContextLost())
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+ GC3Denum result = m_framebufferBinding->checkStatus();
+ if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+ 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)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ 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 (isnan(r))
+ r = 0;
+ if (isnan(g))
+ g = 0;
+ if (isnan(b))
+ b = 0;
+ if (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(shader))
+ return;
+ m_context->compileShader(objectOrZero(shader));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ 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(target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!validateSize(xoffset, yoffset) || !validateSize(width, height))
+ return;
+ if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), getBoundFramebufferColorFormat())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ 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);
+ OwnArrayPtr<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) {
+ m_context->synthesizeGLError(error);
+ return;
+ }
+ zero = adoptArrayPtr(new unsigned char[size]);
+ if (!zero) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+ addObject(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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+
+ RefPtr<WebGLShader> o = WebGLShader::create(this, type);
+ addObject(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->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ if (object->object())
+ object->deleteObject();
+ return true;
+}
+
+void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (!deleteObject(buffer))
+ return;
+ if (m_boundArrayBuffer == buffer)
+ m_boundArrayBuffer = 0;
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+ if (elementArrayBuffer == buffer)
+ m_boundVertexArrayObject->setElementArrayBuffer(0);
+ if (!isGLES2Compliant()) {
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (buffer == state.bufferBinding) {
+ state.bufferBinding = m_vertexAttrib0Buffer;
+ state.bytesPerElement = 0;
+ state.size = 4;
+ state.type = GraphicsContext3D::FLOAT;
+ state.normalized = false;
+ state.stride = 16;
+ state.originalStride = 0;
+ state.offset = 0;
+ }
+ }
+}
+
+void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!deleteObject(framebuffer))
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = 0;
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ if (m_drawingBuffer)
+ 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].m_texture2DBinding)
+ m_textureUnits[i].m_texture2DBinding = 0;
+ if (texture == m_textureUnits[i].m_textureCubeMapBinding)
+ m_textureUnits[i].m_textureCubeMapBinding = 0;
+ }
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->depthRange(zNear, zFar);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
+ return;
+ if (!program->detachShader(shader)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::disable(GC3Denum cap)
+{
+ if (isContextLost() || !validateCapability(cap))
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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_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, int& 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 = 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 = 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, int& numElementsRequired)
+{
+ ASSERT(count >= 0 && offset >= 0);
+ int lastIndex = -1;
+
+ 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_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::validateRenderingState(int numElementsRequired)
+{
+ 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) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled
+ && (!state.bufferBinding || !state.bufferBinding->object()))
+ return false;
+ }
+
+ if (numElementsRequired <= 0)
+ return true;
+
+ // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size
+ int smallestNumElements = INT_MAX;
+ 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) {
+ // 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);
+ int numElements = 0;
+ ASSERT(state.stride > 0);
+ if (bytesRemaining >= state.bytesPerElement)
+ numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
+ if (numElements < smallestNumElements)
+ smallestNumElements = numElements;
+ }
+ }
+ }
+
+ if (smallestNumElements == INT_MAX)
+ smallestNumElements = 0;
+
+ return numElementsRequired <= smallestNumElements;
+}
+
+bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (object->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (isContextLost() || !validateDrawMode(mode))
+ return;
+
+ if (!validateStencilSettings())
+ return;
+
+ if (first < 0 || count < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (!count)
+ return;
+
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ CheckedInt<GC3Dint> checkedFirst(first);
+ CheckedInt<GC3Dint> checkedCount(count);
+ CheckedInt<GC3Dint> checkedSum = checkedFirst + checkedCount;
+ if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ } else {
+ if (!validateRenderingState(0)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(true);
+ m_context->drawArrays(mode, first, count);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (isContextLost() || !validateDrawMode(mode))
+ return;
+
+ if (!validateStencilSettings())
+ return;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+
+ if (count < 0 || offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (!count)
+ return;
+
+ if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ int numElements = 0;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ if (!validateElementArraySize(count, type, offset)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!count)
+ return;
+ if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
+ if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+ } else {
+ if (!validateRenderingState(0)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, offset, numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(true);
+ m_context->drawElements(mode, count, type, offset);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::enable(GC3Denum cap)
+{
+ if (isContextLost() || !validateCapability(cap))
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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(target, attachment))
+ return;
+ if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (buffer && buffer->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ bool reattachDepth = false;
+ bool reattachStencil = false;
+ bool reattachDepthStencilDepth = false;
+ bool reattachDepthStencilStencil = false;
+ 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);
+ if (!bufferObject) {
+ reattachDepth = true;
+ reattachStencil = true;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilDepth = true;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilStencil = true;
+ break;
+ default:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+ if (reattachDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ return;
+ if (level) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (texture && texture->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+ 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(target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(program))
+ return 0;
+ ActiveInfo info;
+ if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
+ return 0;
+ 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(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]");
+ 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(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())
+ return -1;
+ if (!validateLocationLength(name))
+ return -1;
+ if (!validateString(name))
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ 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.
+ return WebGLContextAttributes::create(m_context->getContextAttributes());
+}
+
+GC3Denum WebGLRenderingContext::getError()
+{
+ return m_context->getError();
+}
+
+WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
+{
+ if (isContextLost())
+ return 0;
+
+ if (equalIgnoringCase(name, "OES_standard_derivatives")
+ && m_context->getExtensions()->supports("GL_OES_standard_derivatives")) {
+ if (!m_oesStandardDerivatives) {
+ m_context->getExtensions()->ensureEnabled("GL_OES_standard_derivatives");
+ m_oesStandardDerivatives = OESStandardDerivatives::create(this);
+ }
+ return m_oesStandardDerivatives.get();
+ }
+ if (equalIgnoringCase(name, "OES_texture_float")
+ && m_context->getExtensions()->supports("GL_OES_texture_float")) {
+ if (!m_oesTextureFloat) {
+ m_context->getExtensions()->ensureEnabled("GL_OES_texture_float");
+ m_oesTextureFloat = OESTextureFloat::create(this);
+ }
+ return m_oesTextureFloat.get();
+ }
+ if (equalIgnoringCase(name, "OES_vertex_array_object")
+ && m_context->getExtensions()->supports("GL_OES_vertex_array_object")) {
+ if (!m_oesVertexArrayObject) {
+ m_context->getExtensions()->ensureEnabled("GL_OES_vertex_array_object");
+ m_oesVertexArrayObject = OESVertexArrayObject::create(this);
+ }
+ return m_oesVertexArrayObject.get();
+ }
+ if (equalIgnoringCase(name, "WEBKIT_WEBGL_lose_context")
+ // FIXME: remove this after a certain grace period.
+ || equalIgnoringCase(name, "WEBKIT_lose_context")) {
+ if (!m_webglLoseContext)
+ m_webglLoseContext = WebGLLoseContext::create(this);
+ return m_webglLoseContext.get();
+ }
+ if (equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_textures")) {
+ // Use WEBKIT_ prefix until extension is official.
+ if (!m_webglCompressedTextures)
+ m_webglCompressedTextures = WebGLCompressedTextures::create(this);
+ return m_webglCompressedTextures.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();
+ }
+ }
+
+ return 0;
+}
+
+WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ return WebGLGetInfo();
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+
+ WebGLObject* object = m_framebufferBinding->getAttachment(attachment);
+ if (!object) {
+ if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return WebGLGetInfo(GraphicsContext3D::NONE);
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+ // specifies INVALID_OPERATION.
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ ASSERT(object->isTexture() || object->isRenderbuffer());
+ if (object->isTexture()) {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GraphicsContext3D::TEXTURE);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(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);
+ }
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ } else {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ 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 WebGLGetInfo(PassRefPtr<WebGLBuffer>(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:
+ if (m_webglCompressedTextures)
+ return m_webglCompressedTextures->getCompressedTextureFormats();
+ // Defined as null in the spec
+ return WebGLGetInfo();
+ 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));
+ case GraphicsContext3D::DEPTH_BITS:
+ 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 WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer()));
+ case GraphicsContext3D::FRAMEBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(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::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_COMPRESSED_TEXTURE_FORMATS:
+ // WebGL 1.0 specifies that there are no compressed texture formats.
+ return WebGLGetInfo(static_cast<int>(0));
+ case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
+ // FIXME: should we always return 0 for this?
+ 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 WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GraphicsContext3D::RENDERER:
+ return WebGLGetInfo(String("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 WebGLGetInfo("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:
+ 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 WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
+ case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
+ return WebGLGetInfo(m_unpackFlipY);
+ case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ return WebGLGetInfo(m_unpackColorspaceConversion);
+ case GraphicsContext3D::VENDOR:
+ return WebGLGetInfo(String("WebKit"));
+ case GraphicsContext3D::VERSION:
+ return WebGLGetInfo("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);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ 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();
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(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:
+ case GraphicsContext3D::ACTIVE_ATTRIBUTES:
+ case GraphicsContext3D::ACTIVE_UNIFORMS:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(value);
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(program))
+ return "";
+ WebGLStateRestorer(this, false);
+ return 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(shader))
+ return "";
+ WebGLStateRestorer(this, false);
+ return m_context->getShaderInfoLog(objectOrZero(shader));
+}
+
+String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(shader))
+ return "";
+ return 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_standard_derivatives"))
+ result.append("OES_standard_derivatives");
+ if (m_context->getExtensions()->supports("GL_OES_vertex_array_object"))
+ result.append("OES_vertex_array_object");
+ result.append("WEBKIT_WEBGL_lose_context");
+ if (WebGLCompressedTextures::supported(this))
+ result.append("WEBKIT_WEBGL_compressed_textures");
+
+ 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(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));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return WebGLGetInfo();
+ if (!uniformLocation || uniformLocation->program() != program) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+ GC3Dint location = uniformLocation->location();
+
+ WebGLStateRestorer(this, false);
+ // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
+ 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 WebGLGetInfo();
+ // Strip "[0]" from the name if it's an array.
+ if (info.size > 1 && 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 name = info.name;
+ if (info.size > 1 && index >= 1) {
+ name.append('[');
+ name.append(String::number(index));
+ name.append(']');
+ }
+ // Now need to look this up by name again to find its location
+ GC3Dint loc = m_context->getUniformLocation(objectOrZero(program), name);
+ if (loc == location) {
+ // Found it. Use the type in the ActiveInfo to determine the return type.
+ GC3Denum baseType;
+ unsigned int length;
+ switch (info.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
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+ }
+ switch (baseType) {
+ case GraphicsContext3D::FLOAT: {
+ GC3Dfloat value[16] = {0};
+ 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};
+ 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};
+ 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
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return 0;
+ if (!validateLocationLength(name))
+ return 0;
+ if (!validateString(name))
+ return 0;
+ WebGLStateRestorer(this, false);
+ GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
+ if (uniformLocation == -1)
+ return 0;
+ return WebGLUniformLocation::create(program, uniformLocation);
+}
+
+WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+ }
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+GC3Dsizeiptr WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+{
+ if (isContextLost())
+ return 0;
+ GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
+ cleanupAfterGraphicsCall(false);
+ return 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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()
+{
+ return m_contextLost;
+}
+
+GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
+{
+ if (!validateCapability(cap) || isContextLost())
+ return 0;
+ 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)
+{
+ if (!shader || isContextLost())
+ return 0;
+
+ return m_context->isShader(shader->object());
+}
+
+GC3Dboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLost())
+ return 0;
+
+ if (!texture->hasEverBeenBound())
+ 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(program))
+ return;
+ if (!isGLES2Compliant()) {
+ if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
+ program->setLinkStatus(false);
+ return;
+ }
+ }
+
+ m_context->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+ // cache link status
+ GC3Dint value = 0;
+ m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::LINK_STATUS, &value);
+ program->setLinkStatus(static_cast<bool>(value));
+ // Need to cache link status before caching active attribute locations.
+ program->cacheActiveAttribLocations();
+ 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 {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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 {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ // Validate array type against pixel type.
+ if (!pixels->isUnsignedByteArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned int totalBytesRequired;
+ unsigned int padding;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ m_context->synthesizeGLError(error);
+ return;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ clearIfComposited();
+ void* data = pixels->baseAddress();
+
+ {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->readPixels(x, y, width, height, format, type, data);
+ }
+
+#if OS(DARWIN)
+ // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
+ // when alpha is off, readPixels should set alpha to 255 instead of 0.
+ if (!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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!validateSize(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ }
+}
+
+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(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(shader))
+ return;
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString(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(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(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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, void* pixels, ExceptionCode& ec)
+{
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+ if (!pixels) {
+ bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
+ border, format, type, m_unpackAlignment);
+ if (!succeed)
+ return;
+ } else {
+ 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,
+ bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
+ format, type, data.data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+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(width, height, format, type, pixels))
+ 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())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
+ format, type, data.data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!validateHTMLImageElement(image))
+ return;
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->imageForRenderer(image->renderer()),
+ 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())
+ return;
+ if (!canvas || !canvas->buffer()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ 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(),
+ m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return 0;
+ }
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_videoCache.imageBuffer(size);
+ if (!buf) {
+ m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
+ return 0;
+ }
+ if (wouldTaintOrigin(video)) {
+ ec = SECURITY_ERR;
+ 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(CopyBackingStore);
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), 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(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)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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, void* pixels, ExceptionCode& ec)
+{
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters(target, level, format, width, height, 0, format, type))
+ return;
+ if (!validateSize(xoffset, yoffset))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (tex->getInternalFormat(target, level) != format || tex->getType(target, level) != type) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ 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, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
+ format, type, data.data(), ec);
+}
+
+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(width, height, format, type, pixels))
+ 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);
+ 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())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
+ format, type, data.data(), ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!validateHTMLImageElement(image))
+ return;
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->imageForRenderer(image->renderer()),
+ 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())
+ return;
+ if (!canvas || !canvas->buffer()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ 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(),
+ 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())
+ return;
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v->data(), v->length());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v, size);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 1))
+ return;
+
+ m_context->uniform1iv(location->location(), v->data(), v->length());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ return;
+
+ m_context->uniform1iv(location->location(), v, size);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v, size / 2);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v, size / 2);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v, size / 3);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v, size / 3);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v, size / 4);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v, size / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound(program, deleted))
+ return;
+ if (deleted)
+ program = 0;
+ if (program && !program->getLinkStatus()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached();
+ 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(program))
+ return;
+ m_context->validateProgram(objectOrZero(program));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
+{
+ vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl(index, v, size, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
+{
+ vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl(index, v, size, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
+{
+ vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl(index, v, size, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ vertexAttribfImpl(index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 4);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl(index, v, size, 4);
+}
+
+void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!m_boundArrayBuffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if ((stride % typeSize) || (offset % typeSize)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ GC3Dsizei bytesPerElement = size * typeSize;
+
+ GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.bufferBinding = m_boundArrayBuffer;
+ state.bytesPerElement = bytesPerElement;
+ state.size = size;
+ state.type = type;
+ state.normalized = normalized;
+ state.stride = validatedStride;
+ state.originalStride = stride;
+ state.offset = offset;
+ m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize(width, height))
+ return;
+ m_context->viewport(x, y, width, height);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
+{
+ if (isContextLost()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ m_contextLost = true;
+ m_contextLostMode = mode;
+
+ 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;
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
+
+ // 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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ if (!m_restoreAllowed) {
+ if (m_contextLostMode == SyntheticLostContext)
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ if (!m_restoreTimer.isActive())
+ m_restoreTimer.startOneShot(0);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+PlatformLayer* WebGLRenderingContext::platformLayer() const
+{
+#if PLATFORM(CHROMIUM)
+ if (m_drawingBuffer)
+ return m_drawingBuffer->platformLayer();
+#endif
+
+ return m_context->platformLayer();
+}
+#endif
+
+void WebGLRenderingContext::removeObject(WebGLObject* object)
+{
+ m_canvasObjects.remove(object);
+}
+
+void WebGLRenderingContext::addObject(WebGLObject* object)
+{
+ ASSERT(!isContextLost());
+ removeObject(object);
+ m_canvasObjects.add(object);
+}
+
+void WebGLRenderingContext::detachAndRemoveAllObjects()
+{
+ while (m_canvasObjects.size() > 0) {
+ HashSet<WebGLObject*>::iterator it = m_canvasObjects.begin();
+ (*it)->detachContext();
+ }
+}
+
+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::handleNPOTTextures(bool prepareToDraw)
+{
+ bool resetActiveUnit = false;
+ for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
+ if ((m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
+ || (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())) {
+ 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) {
+ tex2D = m_blackTexture2D.get();
+ texCubeMap = m_blackTextureCubeMap.get();
+ } else {
+ tex2D = m_textureUnits[ii].m_texture2DBinding.get();
+ texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
+ }
+ if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
+ if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
+ 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)
+{
+ switch (colorBufferFormat) {
+ case GraphicsContext3D::ALPHA:
+ if (texInternalFormat == GraphicsContext3D::ALPHA)
+ return true;
+ break;
+ case GraphicsContext3D::RGB:
+ if (texInternalFormat == GraphicsContext3D::LUMINANCE
+ || texInternalFormat == GraphicsContext3D::RGB)
+ return true;
+ break;
+ case GraphicsContext3D::RGBA:
+ return true;
+ }
+ return false;
+}
+
+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(GC3Denum target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* tex = 0;
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ tex = m_textureUnits[m_activeTextureUnit].m_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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!tex)
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return tex;
+}
+
+bool WebGLRenderingContext::validateLocationLength(const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateSize(GC3Dint x, GC3Dint y)
+{
+ if (x < 0 || y < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateString(const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Denum type)
+{
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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;
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ case GraphicsContext3D::RGB:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
+ && type != GraphicsContext3D::FLOAT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level)
+{
+ if (level < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (level > m_maxTextureLevel) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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(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(format, type) || !validateTexFuncLevel(target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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 (width != height || width > m_maxCubeMapTextureSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ if (format != internalformat) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+
+ if (border) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels)
+{
+ if (!pixels)
+ return true;
+
+ if (!validateTexFuncFormatAndType(format, type))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ if (!pixels->isUnsignedByteArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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->isUnsignedShortArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ case GraphicsContext3D::FLOAT: // OES_texture_float
+ if (!pixels->isFloatArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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) {
+ m_context->synthesizeGLError(error);
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateDrawMode(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateStencilSettings()
+{
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateStencilFunc(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+void WebGLRenderingContext::printWarningToConsole(const String& message)
+{
+ canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
+ message, 0, canvas()->document()->url().string());
+}
+
+bool WebGLRenderingContext::validateFramebufferFuncParameters(GC3Denum target, GC3Denum attachment)
+{
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateBlendEquation(GC3Denum mode)
+{
+ switch (mode) {
+ case GraphicsContext3D::FUNC_ADD:
+ case GraphicsContext3D::FUNC_SUBTRACT:
+ case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateBlendFuncFactors(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))) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateCapability(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:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (transpose) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (size < requiredMinSize || (size % requiredMinSize)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!buffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return 0;
+ }
+ switch (usage) {
+ case GraphicsContext3D::STREAM_DRAW:
+ case GraphicsContext3D::STATIC_DRAW:
+ case GraphicsContext3D::DYNAMIC_DRAW:
+ return buffer;
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+}
+
+bool WebGLRenderingContext::validateHTMLImageElement(HTMLImageElement* image)
+{
+ if (!image || !image->cachedImage()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ const KURL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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(GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ vertexAttribfvImpl(index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (size < expectedSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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])) {
+ OwnArrayPtr<GC3Dfloat> bufferData = adoptArrayPtr(new 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;
+ }
+
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->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.
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ // Construct a new drawing buffer with the new GraphicsContext3D.
+ if (m_drawingBuffer) {
+ m_drawingBuffer->discardResources();
+ m_drawingBuffer = DrawingBuffer::create(m_context.get(), m_drawingBuffer->size(), !m_attributes.preserveDrawingBuffer);
+ }
+
+ m_context = context;
+ m_contextLost = false;
+ initializeNewContext();
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
+}
+
+WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(adoptArrayPtr(new OwnPtr<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->size() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ OwnPtr<ImageBuffer> temp = ImageBuffer::create(size);
+ if (!temp)
+ return 0;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = temp.release();
+
+ 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 WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
new file mode 100644
index 000000000..8f1efd9b0
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -0,0 +1,651 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLRenderingContext_h
+#define WebGLRenderingContext_h
+
+#include "CanvasRenderingContext.h"
+#include "DrawingBuffer.h"
+#include "GraphicsContext3D.h"
+#include "PlatformString.h"
+#include "Timer.h"
+#include "WebGLGetInfo.h"
+
+#include <wtf/Float32Array.h>
+#include <wtf/Int32Array.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/Uint8Array.h>
+
+namespace WebCore {
+
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESVertexArrayObject;
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLCompressedTextures;
+class WebGLContextAttributes;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArrayObjectOES;
+
+typedef int ExceptionCode;
+
+class WebGLRenderingContext : public CanvasRenderingContext {
+public:
+ static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
+ virtual ~WebGLRenderingContext();
+
+ virtual bool is3d() const { return true; }
+ virtual bool isAccelerated() const { return true; }
+ virtual bool paintsIntoCanvasBuffer() const;
+
+ 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, GC3Dsizeiptr 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, GC3Dintptr offset, ArrayBuffer* data, ExceptionCode&);
+ void bufferSubData(GC3Denum target, GC3Dintptr 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, GC3Dsizei imageSize, const void* data);
+ // void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* 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, GC3Dintptr 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&);
+
+ // TBD
+ // void glGetShaderPrecisionFormat (GC3Denum shadertype, GC3Denum precisiontype, GC3Dint* range, GC3Dint* precision);
+
+ 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&);
+ GC3Dsizeiptr getVertexAttribOffset(GC3Duint index, GC3Denum pname);
+
+ void hint(GC3Denum target, GC3Denum mode);
+ GC3Dboolean isBuffer(WebGLBuffer*);
+ bool isContextLost();
+ 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, GC3Dintptr 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();
+
+ GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const;
+#endif
+
+ void reshape(int width, int height);
+
+ void markLayerComposited();
+ virtual void paintRenderingResultsToCanvas();
+ virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
+
+ void removeObject(WebGLObject*);
+
+ unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
+
+ private:
+ friend class WebGLFramebuffer;
+ friend class WebGLObject;
+ friend class OESVertexArrayObject;
+ friend class WebGLDebugShaders;
+ friend class WebGLCompressedTextures;
+
+ WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
+ void initializeNewContext();
+ void setupFlags();
+
+ void addObject(WebGLObject*);
+ void detachAndRemoveAllObjects();
+
+ 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, int& numElementsRequired);
+
+ // Precise but slow index validation -- only done if conservative checks fail
+ bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, int& numElementsRequired);
+ // If numElements <= 0, we only check if each enabled vertex attribute is bound to a buffer.
+ bool validateRenderingState(int numElements);
+
+ bool validateWebGLObject(WebGLObject*);
+
+#if ENABLE(VIDEO)
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
+#endif
+
+ RefPtr<GraphicsContext3D> m_context;
+
+ // 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<WebGLObject*> m_canvasObjects;
+
+ // 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;
+ class TextureUnitState {
+ public:
+ RefPtr<WebGLTexture> m_texture2DBinding;
+ RefPtr<WebGLTexture> m_textureCubeMapBinding;
+ };
+ Vector<TextureUnitState> m_textureUnits;
+ unsigned long m_activeTextureUnit;
+
+ RefPtr<WebGLTexture> m_blackTexture2D;
+ RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+ // 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);
+ OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_videoCache;
+
+ GC3Dint m_maxTextureSize;
+ GC3Dint m_maxCubeMapTextureSize;
+ GC3Dint m_maxRenderbufferSize;
+ GC3Dint m_maxViewportDims[2];
+ GC3Dint m_maxTextureLevel;
+ GC3Dint m_maxCubeMapTextureLevel;
+
+ 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;
+
+ long m_stencilBits;
+ 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;
+
+ // Enabled extension objects.
+ OwnPtr<OESTextureFloat> m_oesTextureFloat;
+ OwnPtr<OESStandardDerivatives> m_oesStandardDerivatives;
+ OwnPtr<OESVertexArrayObject> m_oesVertexArrayObject;
+ OwnPtr<WebGLLoseContext> m_webglLoseContext;
+ OwnPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
+ OwnPtr<WebGLDebugShaders> m_webglDebugShaders;
+ OwnPtr<WebGLCompressedTextures> m_webglCompressedTextures;
+
+ // 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);
+
+ void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type, void* pixels, ExceptionCode&);
+ void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, Image*,
+ bool flipY, bool premultiplyAlpha, ExceptionCode&);
+ void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, void* pixels, ExceptionCode&);
+ void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type,
+ Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode&);
+
+ void handleNPOTTextures(bool prepareToDraw);
+
+ 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 String&);
+
+ // Helper function to check if size is non-negative.
+ // Generate GL error and return false for negative inputs; otherwise, return true.
+ bool validateSize(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 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(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(GC3Denum format, GC3Denum type);
+
+ // Helper function to check input level for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if level is invalid.
+ bool validateTexFuncLevel(GC3Denum target, GC3Dint level);
+
+ // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncParameters(GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type);
+
+ // 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(GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(GC3Denum);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings();
+
+ // Helper function to validate stencil func.
+ bool validateStencilFunc(GC3Denum);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
+
+ // 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(GC3Denum target, GC3Denum attachment);
+
+ // Helper function to validate blend equation mode.
+ bool validateBlendEquation(GC3Denum);
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(GC3Denum src, GC3Denum dst);
+
+ // Helper function to validate a GL capability.
+ bool validateCapability(GC3Denum);
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const WebGLUniformLocation*, void*, GC3Dsizei size, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei size, GC3Dsizei mod);
+
+ // Helper function to validate parameters for bufferData.
+ // Return the current bound buffer to target, or 0 if parameters are invalid.
+ WebGLBuffer* validateBufferDataParameters(GC3Denum target, GC3Denum usage);
+
+ // Helper function for tex{Sub}Image2D to make sure image is ready.
+ bool validateHTMLImageElement(HTMLImageElement*);
+
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
+ void vertexAttribfvImpl(GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
+ void vertexAttribfvImpl(GC3Duint index, GC3Dfloat*, GC3Dsizei size, 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(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;
+
+ friend class WebGLStateRestorer;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
new file mode 100644
index 000000000..5103af01a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ Conditional=WEBGL,
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54,
+ CustomMarkFunction,
+ DontCheckEnums
+ ] WebGLRenderingContext : CanvasRenderingContext {
+
+ /* ClearBufferMask */
+ const unsigned int DEPTH_BUFFER_BIT = 0x00000100;
+ const unsigned int STENCIL_BUFFER_BIT = 0x00000400;
+ const unsigned int COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const unsigned int POINTS = 0x0000;
+ const unsigned int LINES = 0x0001;
+ const unsigned int LINE_LOOP = 0x0002;
+ const unsigned int LINE_STRIP = 0x0003;
+ const unsigned int TRIANGLES = 0x0004;
+ const unsigned int TRIANGLE_STRIP = 0x0005;
+ const unsigned int TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const unsigned int ZERO = 0;
+ const unsigned int ONE = 1;
+ const unsigned int SRC_COLOR = 0x0300;
+ const unsigned int ONE_MINUS_SRC_COLOR = 0x0301;
+ const unsigned int SRC_ALPHA = 0x0302;
+ const unsigned int ONE_MINUS_SRC_ALPHA = 0x0303;
+ const unsigned int DST_ALPHA = 0x0304;
+ const unsigned int ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const unsigned int DST_COLOR = 0x0306;
+ const unsigned int ONE_MINUS_DST_COLOR = 0x0307;
+ const unsigned int SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const unsigned int FUNC_ADD = 0x8006;
+ const unsigned int BLEND_EQUATION = 0x8009;
+ const unsigned int BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const unsigned int BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const unsigned int FUNC_SUBTRACT = 0x800A;
+ const unsigned int FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const unsigned int BLEND_DST_RGB = 0x80C8;
+ const unsigned int BLEND_SRC_RGB = 0x80C9;
+ const unsigned int BLEND_DST_ALPHA = 0x80CA;
+ const unsigned int BLEND_SRC_ALPHA = 0x80CB;
+ const unsigned int CONSTANT_COLOR = 0x8001;
+ const unsigned int ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const unsigned int CONSTANT_ALPHA = 0x8003;
+ const unsigned int ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const unsigned int BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const unsigned int ARRAY_BUFFER = 0x8892;
+ const unsigned int ELEMENT_ARRAY_BUFFER = 0x8893;
+ const unsigned int ARRAY_BUFFER_BINDING = 0x8894;
+ const unsigned int ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const unsigned int STREAM_DRAW = 0x88E0;
+ const unsigned int STATIC_DRAW = 0x88E4;
+ const unsigned int DYNAMIC_DRAW = 0x88E8;
+
+ const unsigned int BUFFER_SIZE = 0x8764;
+ const unsigned int BUFFER_USAGE = 0x8765;
+
+ const unsigned int CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const unsigned int FRONT = 0x0404;
+ const unsigned int BACK = 0x0405;
+ const unsigned int FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const unsigned int TEXTURE_2D = 0x0DE1;
+ const unsigned int CULL_FACE = 0x0B44;
+ const unsigned int BLEND = 0x0BE2;
+ const unsigned int DITHER = 0x0BD0;
+ const unsigned int STENCIL_TEST = 0x0B90;
+ const unsigned int DEPTH_TEST = 0x0B71;
+ const unsigned int SCISSOR_TEST = 0x0C11;
+ const unsigned int POLYGON_OFFSET_FILL = 0x8037;
+ const unsigned int SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const unsigned int SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const unsigned int NO_ERROR = 0;
+ const unsigned int INVALID_ENUM = 0x0500;
+ const unsigned int INVALID_VALUE = 0x0501;
+ const unsigned int INVALID_OPERATION = 0x0502;
+ const unsigned int OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const unsigned int CW = 0x0900;
+ const unsigned int CCW = 0x0901;
+
+ /* GetPName */
+ const unsigned int LINE_WIDTH = 0x0B21;
+ const unsigned int ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const unsigned int ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const unsigned int CULL_FACE_MODE = 0x0B45;
+ const unsigned int FRONT_FACE = 0x0B46;
+ const unsigned int DEPTH_RANGE = 0x0B70;
+ const unsigned int DEPTH_WRITEMASK = 0x0B72;
+ const unsigned int DEPTH_CLEAR_VALUE = 0x0B73;
+ const unsigned int DEPTH_FUNC = 0x0B74;
+ const unsigned int STENCIL_CLEAR_VALUE = 0x0B91;
+ const unsigned int STENCIL_FUNC = 0x0B92;
+ const unsigned int STENCIL_FAIL = 0x0B94;
+ const unsigned int STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const unsigned int STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const unsigned int STENCIL_REF = 0x0B97;
+ const unsigned int STENCIL_VALUE_MASK = 0x0B93;
+ const unsigned int STENCIL_WRITEMASK = 0x0B98;
+ const unsigned int STENCIL_BACK_FUNC = 0x8800;
+ const unsigned int STENCIL_BACK_FAIL = 0x8801;
+ const unsigned int STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const unsigned int STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const unsigned int STENCIL_BACK_REF = 0x8CA3;
+ const unsigned int STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const unsigned int STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const unsigned int VIEWPORT = 0x0BA2;
+ const unsigned int SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const unsigned int COLOR_CLEAR_VALUE = 0x0C22;
+ const unsigned int COLOR_WRITEMASK = 0x0C23;
+ const unsigned int UNPACK_ALIGNMENT = 0x0CF5;
+ const unsigned int PACK_ALIGNMENT = 0x0D05;
+ const unsigned int MAX_TEXTURE_SIZE = 0x0D33;
+ const unsigned int MAX_VIEWPORT_DIMS = 0x0D3A;
+ const unsigned int SUBPIXEL_BITS = 0x0D50;
+ const unsigned int RED_BITS = 0x0D52;
+ const unsigned int GREEN_BITS = 0x0D53;
+ const unsigned int BLUE_BITS = 0x0D54;
+ const unsigned int ALPHA_BITS = 0x0D55;
+ const unsigned int DEPTH_BITS = 0x0D56;
+ const unsigned int STENCIL_BITS = 0x0D57;
+ const unsigned int POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const unsigned int POLYGON_OFFSET_FACTOR = 0x8038;
+ const unsigned int TEXTURE_BINDING_2D = 0x8069;
+ const unsigned int SAMPLE_BUFFERS = 0x80A8;
+ const unsigned int SAMPLES = 0x80A9;
+ const unsigned int SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const unsigned int SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const unsigned int NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2;
+ const unsigned int COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const unsigned int DONT_CARE = 0x1100;
+ const unsigned int FASTEST = 0x1101;
+ const unsigned int NICEST = 0x1102;
+
+ /* HintTarget */
+ const unsigned int GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const unsigned int BYTE = 0x1400;
+ const unsigned int UNSIGNED_BYTE = 0x1401;
+ const unsigned int SHORT = 0x1402;
+ const unsigned int UNSIGNED_SHORT = 0x1403;
+ const unsigned int INT = 0x1404;
+ const unsigned int UNSIGNED_INT = 0x1405;
+ const unsigned int FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const unsigned int DEPTH_COMPONENT = 0x1902;
+ const unsigned int ALPHA = 0x1906;
+ const unsigned int RGB = 0x1907;
+ const unsigned int RGBA = 0x1908;
+ const unsigned int LUMINANCE = 0x1909;
+ const unsigned int LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const unsigned int UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const unsigned int UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const unsigned int UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const unsigned int FRAGMENT_SHADER = 0x8B30;
+ const unsigned int VERTEX_SHADER = 0x8B31;
+ const unsigned int MAX_VERTEX_ATTRIBS = 0x8869;
+ const unsigned int MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const unsigned int MAX_VARYING_VECTORS = 0x8DFC;
+ const unsigned int MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const unsigned int MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const unsigned int MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const unsigned int MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const unsigned int SHADER_TYPE = 0x8B4F;
+ const unsigned int DELETE_STATUS = 0x8B80;
+ const unsigned int LINK_STATUS = 0x8B82;
+ const unsigned int VALIDATE_STATUS = 0x8B83;
+ const unsigned int ATTACHED_SHADERS = 0x8B85;
+ const unsigned int ACTIVE_UNIFORMS = 0x8B86;
+ const unsigned int ACTIVE_ATTRIBUTES = 0x8B89;
+ const unsigned int SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const unsigned int CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const unsigned int NEVER = 0x0200;
+ const unsigned int LESS = 0x0201;
+ const unsigned int EQUAL = 0x0202;
+ const unsigned int LEQUAL = 0x0203;
+ const unsigned int GREATER = 0x0204;
+ const unsigned int NOTEQUAL = 0x0205;
+ const unsigned int GEQUAL = 0x0206;
+ const unsigned int ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const unsigned int KEEP = 0x1E00;
+ const unsigned int REPLACE = 0x1E01;
+ const unsigned int INCR = 0x1E02;
+ const unsigned int DECR = 0x1E03;
+ const unsigned int INVERT = 0x150A;
+ const unsigned int INCR_WRAP = 0x8507;
+ const unsigned int DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const unsigned int VENDOR = 0x1F00;
+ const unsigned int RENDERER = 0x1F01;
+ const unsigned int VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const unsigned int NEAREST = 0x2600;
+ const unsigned int LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const unsigned int NEAREST_MIPMAP_NEAREST = 0x2700;
+ const unsigned int LINEAR_MIPMAP_NEAREST = 0x2701;
+ const unsigned int NEAREST_MIPMAP_LINEAR = 0x2702;
+ const unsigned int LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const unsigned int TEXTURE_MAG_FILTER = 0x2800;
+ const unsigned int TEXTURE_MIN_FILTER = 0x2801;
+ const unsigned int TEXTURE_WRAP_S = 0x2802;
+ const unsigned int TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const unsigned int TEXTURE = 0x1702;
+
+ const unsigned int TEXTURE_CUBE_MAP = 0x8513;
+ const unsigned int TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const unsigned int MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const unsigned int TEXTURE0 = 0x84C0;
+ const unsigned int TEXTURE1 = 0x84C1;
+ const unsigned int TEXTURE2 = 0x84C2;
+ const unsigned int TEXTURE3 = 0x84C3;
+ const unsigned int TEXTURE4 = 0x84C4;
+ const unsigned int TEXTURE5 = 0x84C5;
+ const unsigned int TEXTURE6 = 0x84C6;
+ const unsigned int TEXTURE7 = 0x84C7;
+ const unsigned int TEXTURE8 = 0x84C8;
+ const unsigned int TEXTURE9 = 0x84C9;
+ const unsigned int TEXTURE10 = 0x84CA;
+ const unsigned int TEXTURE11 = 0x84CB;
+ const unsigned int TEXTURE12 = 0x84CC;
+ const unsigned int TEXTURE13 = 0x84CD;
+ const unsigned int TEXTURE14 = 0x84CE;
+ const unsigned int TEXTURE15 = 0x84CF;
+ const unsigned int TEXTURE16 = 0x84D0;
+ const unsigned int TEXTURE17 = 0x84D1;
+ const unsigned int TEXTURE18 = 0x84D2;
+ const unsigned int TEXTURE19 = 0x84D3;
+ const unsigned int TEXTURE20 = 0x84D4;
+ const unsigned int TEXTURE21 = 0x84D5;
+ const unsigned int TEXTURE22 = 0x84D6;
+ const unsigned int TEXTURE23 = 0x84D7;
+ const unsigned int TEXTURE24 = 0x84D8;
+ const unsigned int TEXTURE25 = 0x84D9;
+ const unsigned int TEXTURE26 = 0x84DA;
+ const unsigned int TEXTURE27 = 0x84DB;
+ const unsigned int TEXTURE28 = 0x84DC;
+ const unsigned int TEXTURE29 = 0x84DD;
+ const unsigned int TEXTURE30 = 0x84DE;
+ const unsigned int TEXTURE31 = 0x84DF;
+ const unsigned int ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const unsigned int REPEAT = 0x2901;
+ const unsigned int CLAMP_TO_EDGE = 0x812F;
+ const unsigned int MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const unsigned int FLOAT_VEC2 = 0x8B50;
+ const unsigned int FLOAT_VEC3 = 0x8B51;
+ const unsigned int FLOAT_VEC4 = 0x8B52;
+ const unsigned int INT_VEC2 = 0x8B53;
+ const unsigned int INT_VEC3 = 0x8B54;
+ const unsigned int INT_VEC4 = 0x8B55;
+ const unsigned int BOOL = 0x8B56;
+ const unsigned int BOOL_VEC2 = 0x8B57;
+ const unsigned int BOOL_VEC3 = 0x8B58;
+ const unsigned int BOOL_VEC4 = 0x8B59;
+ const unsigned int FLOAT_MAT2 = 0x8B5A;
+ const unsigned int FLOAT_MAT3 = 0x8B5B;
+ const unsigned int FLOAT_MAT4 = 0x8B5C;
+ const unsigned int SAMPLER_2D = 0x8B5E;
+ const unsigned int SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const unsigned int VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const unsigned int VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const unsigned int VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const unsigned int VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const unsigned int VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const unsigned int VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const unsigned int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Shader Source */
+ const unsigned int COMPILE_STATUS = 0x8B81;
+ const unsigned int SHADER_COMPILER = 0x8DFA;
+
+ /* Shader Precision-Specified Types */
+ const unsigned int LOW_FLOAT = 0x8DF0;
+ const unsigned int MEDIUM_FLOAT = 0x8DF1;
+ const unsigned int HIGH_FLOAT = 0x8DF2;
+ const unsigned int LOW_INT = 0x8DF3;
+ const unsigned int MEDIUM_INT = 0x8DF4;
+ const unsigned int HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const unsigned int FRAMEBUFFER = 0x8D40;
+ const unsigned int RENDERBUFFER = 0x8D41;
+
+ const unsigned int RGBA4 = 0x8056;
+ const unsigned int RGB5_A1 = 0x8057;
+ const unsigned int RGB565 = 0x8D62;
+ const unsigned int DEPTH_COMPONENT16 = 0x81A5;
+ const unsigned int STENCIL_INDEX = 0x1901;
+ const unsigned int STENCIL_INDEX8 = 0x8D48;
+ const unsigned int DEPTH_STENCIL = 0x84F9;
+
+ const unsigned int RENDERBUFFER_WIDTH = 0x8D42;
+ const unsigned int RENDERBUFFER_HEIGHT = 0x8D43;
+ const unsigned int RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const unsigned int RENDERBUFFER_RED_SIZE = 0x8D50;
+ const unsigned int RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const unsigned int RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const unsigned int RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const unsigned int RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const unsigned int RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const unsigned int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const unsigned int COLOR_ATTACHMENT0 = 0x8CE0;
+ const unsigned int DEPTH_ATTACHMENT = 0x8D00;
+ const unsigned int STENCIL_ATTACHMENT = 0x8D20;
+ const unsigned int DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const unsigned int NONE = 0;
+
+ const unsigned int FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const unsigned int FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const unsigned int FRAMEBUFFER_BINDING = 0x8CA6;
+ const unsigned int RENDERBUFFER_BINDING = 0x8CA7;
+ const unsigned int MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const unsigned int INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const unsigned int UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const unsigned int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const unsigned int CONTEXT_LOST_WEBGL = 0x9242;
+ const unsigned int UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const unsigned int BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ readonly attribute long drawingBufferWidth;
+ readonly attribute long drawingBufferHeight;
+
+ [StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException);
+ [StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void bindAttribLocation(in WebGLProgram program, in unsigned long index, in DOMString name) raises(DOMException);
+ [StrictTypeChecking] void bindBuffer(in unsigned long target, in WebGLBuffer buffer) raises(DOMException);
+ [StrictTypeChecking] void bindFramebuffer(in unsigned long target, in WebGLFramebuffer framebuffer) raises(DOMException);
+ [StrictTypeChecking] void bindRenderbuffer(in unsigned long target, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void bindTexture(in unsigned long target, in WebGLTexture texture) raises(DOMException);
+ [StrictTypeChecking] void blendColor(in float red, in float green, in float blue, in float alpha);
+ [StrictTypeChecking] void blendEquation( in unsigned long mode );
+ [StrictTypeChecking] void blendEquationSeparate(in unsigned long modeRGB, in unsigned long modeAlpha);
+ [StrictTypeChecking] void blendFunc(in unsigned long sfactor, in unsigned long dfactor);
+ [StrictTypeChecking] void blendFuncSeparate(in unsigned long srcRGB, in unsigned long dstRGB, in unsigned long srcAlpha, in unsigned long dstAlpha);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBuffer data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBufferView data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in long size, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBuffer data) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBufferView data) raises (DOMException);
+
+ [StrictTypeChecking] unsigned long checkFramebufferStatus(in unsigned long target);
+ [StrictTypeChecking] void clear(in unsigned long mask);
+ [StrictTypeChecking] void clearColor(in float red, in float green, in float blue, in float alpha);
+ [StrictTypeChecking] void clearDepth(in float depth);
+ [StrictTypeChecking] void clearStencil(in long s);
+ [StrictTypeChecking] void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
+ [StrictTypeChecking] void compileShader(in WebGLShader shader) raises(DOMException);
+
+ //void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
+ //void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
+
+ [StrictTypeChecking] void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in long width, in long height, in long border);
+ [StrictTypeChecking] void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in long width, in long height);
+
+ [StrictTypeChecking] WebGLBuffer createBuffer();
+ [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
+ [StrictTypeChecking] WebGLProgram createProgram();
+ [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
+ [StrictTypeChecking] WebGLShader createShader(in unsigned long type) raises(DOMException);
+ [StrictTypeChecking] WebGLTexture createTexture();
+
+ [StrictTypeChecking] void cullFace(in unsigned long mode);
+
+ [StrictTypeChecking] void deleteBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] void deleteFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] void deleteProgram(in WebGLProgram program);
+ [StrictTypeChecking] void deleteRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] void deleteShader(in WebGLShader shader);
+ [StrictTypeChecking] void deleteTexture(in WebGLTexture texture);
+
+ [StrictTypeChecking] void depthFunc(in unsigned long func);
+ [StrictTypeChecking] void depthMask(in boolean flag);
+ // FIXME: this differs from the current WebGL spec (depthRangef)
+ [StrictTypeChecking] void depthRange(in float zNear, in float zFar);
+ [StrictTypeChecking] void detachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void disable(in unsigned long cap);
+ [StrictTypeChecking] void disableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void drawArrays(in unsigned long mode, in long first, in long count) raises(DOMException);
+ [StrictTypeChecking] void drawElements(in unsigned long mode, in long count, in unsigned long type, in long offset) raises(DOMException);
+
+ [StrictTypeChecking] void enable(in unsigned long cap);
+ [StrictTypeChecking] void enableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void finish();
+ [StrictTypeChecking] void flush();
+ [StrictTypeChecking] void framebufferRenderbuffer(in unsigned long target, in unsigned long attachment, in unsigned long renderbuffertarget, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void framebufferTexture2D(in unsigned long target, in unsigned long attachment, in unsigned long textarget, in WebGLTexture texture, in long level) raises(DOMException);
+ [StrictTypeChecking] void frontFace(in unsigned long mode);
+ [StrictTypeChecking] void generateMipmap(in unsigned long target);
+
+ [StrictTypeChecking] WebGLActiveInfo getActiveAttrib(in WebGLProgram program, in unsigned long index) raises (DOMException);
+ [StrictTypeChecking] WebGLActiveInfo getActiveUniform(in WebGLProgram program, in unsigned long index) raises (DOMException);
+
+ [StrictTypeChecking, Custom] void getAttachedShaders(in WebGLProgram program) raises (DOMException);
+
+ [StrictTypeChecking] int getAttribLocation(in WebGLProgram program, in DOMString name);
+
+ // any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getBufferParameter();
+
+ [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
+
+ [StrictTypeChecking] unsigned long getError();
+
+ // object getExtension(in DOMString name);
+ [StrictTypeChecking, Custom] void getExtension(in DOMString name);
+
+ // any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getFramebufferAttachmentParameter();
+ // any getParameter(in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getParameter();
+ // any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getProgramParameter();
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
+ // any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getRenderbufferParameter();
+ // any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
+
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
+
+ // TBD
+ // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
+
+ // DOMString[] getSupportedExtensions()
+ [StrictTypeChecking, Custom] void getSupportedExtensions();
+
+ // any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getTexParameter();
+
+ // any getUniform(in WebGLProgram program, in WebGLUniformLocation location) raises(DOMException);
+ [StrictTypeChecking, Custom] void getUniform();
+
+ [StrictTypeChecking] WebGLUniformLocation getUniformLocation(in WebGLProgram program, in DOMString name) raises(DOMException);
+
+ // any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getVertexAttrib();
+
+ [StrictTypeChecking] long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
+
+ [StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode);
+ [StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] boolean isContextLost();
+ [StrictTypeChecking] boolean isEnabled(in unsigned long cap);
+ [StrictTypeChecking] boolean isFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] boolean isProgram(in WebGLProgram program);
+ [StrictTypeChecking] boolean isRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] boolean isShader(in WebGLShader shader);
+ [StrictTypeChecking] boolean isTexture(in WebGLTexture texture);
+ [StrictTypeChecking] void lineWidth(in float width);
+ [StrictTypeChecking] void linkProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void pixelStorei(in unsigned long pname, in long param);
+ [StrictTypeChecking] void polygonOffset(in float factor, in float units);
+
+ [StrictTypeChecking] void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises(DOMException);
+
+ [StrictTypeChecking] void releaseShaderCompiler();
+ [StrictTypeChecking] void renderbufferStorage(in unsigned long target, in unsigned long internalformat, in long width, in long height);
+ [StrictTypeChecking] void sampleCoverage(in float value, in boolean invert);
+ [StrictTypeChecking] void scissor(in long x, in long y, in long width, in long height);
+ [StrictTypeChecking] void shaderSource(in WebGLShader shader, in DOMString string) raises(DOMException);
+ [StrictTypeChecking] void stencilFunc(in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilFuncSeparate(in unsigned long face, in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilMask(in unsigned long mask);
+ [StrictTypeChecking] void stencilMaskSeparate(in unsigned long face, in unsigned long mask);
+ [StrictTypeChecking] void stencilOp(in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+ [StrictTypeChecking] void stencilOpSeparate(in unsigned long face, in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+
+ [StrictTypeChecking] void texParameterf(in unsigned long target, in unsigned long pname, in float param);
+ [StrictTypeChecking] void texParameteri(in unsigned long target, in unsigned long pname, in long param);
+
+ // Supported forms:
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long width, in long height,
+ in long border, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+#endif
+
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in long width, in long height,
+ in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+#endif
+
+ [StrictTypeChecking] void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform1i(in WebGLUniformLocation location, in long x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2f(in WebGLUniformLocation location, in float x, in float y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2i(in WebGLUniformLocation location, in long x, in long y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3f(in WebGLUniformLocation location, in float x, in float y, in float z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3i(in WebGLUniformLocation location, in long x, in long y, in long z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4f(in WebGLUniformLocation location, in float x, in float y, in float z, in float w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4i(in WebGLUniformLocation location, in long x, in long y, in long z, in long w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+
+ [StrictTypeChecking, Custom] void uniformMatrix2fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix3fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix4fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+
+ [StrictTypeChecking] void useProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void validateProgram(in WebGLProgram program) raises(DOMException);
+
+ [StrictTypeChecking] void vertexAttrib1f(in unsigned long indx, in float x);
+ [StrictTypeChecking, Custom] void vertexAttrib1fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib2f(in unsigned long indx, in float x, in float y);
+ [StrictTypeChecking, Custom] void vertexAttrib2fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib3f(in unsigned long indx, in float x, in float y, in float z);
+ [StrictTypeChecking, Custom] void vertexAttrib3fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib4f(in unsigned long indx, in float x, in float y, in float z, in float w);
+ [StrictTypeChecking, Custom] void vertexAttrib4fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttribPointer(in unsigned long indx, in long size, in unsigned long type, in boolean normalized,
+ in long stride, in long offset) raises(DOMException);
+
+ [StrictTypeChecking] void viewport(in long x, in long y, in long width, in long height);
+ };
+}
+
diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp
new file mode 100644
index 000000000..59695e4c9
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLShader.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type)
+{
+ return adoptRef(new WebGLShader(ctx, type));
+}
+
+WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
+ : WebGLObject(ctx)
+ , m_type(type)
+ , m_source("")
+{
+ setObject(context()->graphicsContext3D()->createShader(type));
+}
+
+void WebGLShader::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteShader(object);
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h
new file mode 100644
index 000000000..1d7a10c1c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLShader_h
+#define WebGLShader_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLShader : public WebGLObject {
+public:
+ virtual ~WebGLShader() { deleteObject(); }
+
+ static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
+
+ GC3Denum getType() const { return m_type; }
+ const String& getSource() const { return m_source; }
+
+ void setSource(const String& source) { m_source = source; }
+
+private:
+ WebGLShader(WebGLRenderingContext*, GC3Denum);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+ virtual bool isShader() const { return true; }
+
+ GC3Denum m_type;
+ String m_source;
+};
+
+} // namespace WebCore
+
+#endif // WebGLShader_h
diff --git a/Source/WebCore/html/canvas/WebGLShader.idl b/Source/WebCore/html/canvas/WebGLShader.idl
new file mode 100644
index 000000000..2aeb704d6
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLShader {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp
new file mode 100644
index 000000000..e8e8bf824
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLTexture.h"
+
+#include "WebGLFramebuffer.h"
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLTexture(ctx));
+}
+
+WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_target(0)
+ , m_minFilter(GraphicsContext3D::NEAREST_MIPMAP_LINEAR)
+ , m_magFilter(GraphicsContext3D::LINEAR)
+ , m_wrapS(GraphicsContext3D::REPEAT)
+ , m_wrapT(GraphicsContext3D::REPEAT)
+ , m_isNPOT(false)
+ , m_isComplete(false)
+ , m_needToUseBlackTexture(false)
+{
+ setObject(context()->graphicsContext3D()->createTexture());
+}
+
+void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
+{
+ if (!object())
+ return;
+ // Target is finalized the first time bindTexture() is called.
+ if (m_target)
+ return;
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ m_target = target;
+ m_info.resize(1);
+ m_info[0].resize(maxLevel);
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ m_target = target;
+ m_info.resize(6);
+ for (int ii = 0; ii < 6; ++ii)
+ m_info[ii].resize(maxLevel);
+ break;
+ }
+}
+
+void WebGLTexture::setParameteri(GC3Denum pname, GC3Dint param)
+{
+ if (!object() || !m_target)
+ return;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ switch (param) {
+ case GraphicsContext3D::NEAREST:
+ case GraphicsContext3D::LINEAR:
+ case GraphicsContext3D::NEAREST_MIPMAP_NEAREST:
+ case GraphicsContext3D::LINEAR_MIPMAP_NEAREST:
+ case GraphicsContext3D::NEAREST_MIPMAP_LINEAR:
+ case GraphicsContext3D::LINEAR_MIPMAP_LINEAR:
+ m_minFilter = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ switch (param) {
+ case GraphicsContext3D::NEAREST:
+ case GraphicsContext3D::LINEAR:
+ m_magFilter = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ switch (param) {
+ case GraphicsContext3D::CLAMP_TO_EDGE:
+ case GraphicsContext3D::MIRRORED_REPEAT:
+ case GraphicsContext3D::REPEAT:
+ m_wrapS = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ switch (param) {
+ case GraphicsContext3D::CLAMP_TO_EDGE:
+ case GraphicsContext3D::MIRRORED_REPEAT:
+ case GraphicsContext3D::REPEAT:
+ m_wrapT = param;
+ break;
+ }
+ break;
+ default:
+ return;
+ }
+ update();
+}
+
+void WebGLTexture::setParameterf(GC3Denum pname, GC3Dfloat param)
+{
+ if (!object() || !m_target)
+ return;
+ GC3Dint iparam = static_cast<GC3Dint>(param);
+ setParameteri(pname, iparam);
+}
+
+void WebGLTexture::setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type)
+{
+ if (!object() || !m_target)
+ return;
+ // We assume level, internalFormat, width, height, and type have all been
+ // validated already.
+ int index = mapTargetToIndex(target);
+ if (index < 0)
+ return;
+ m_info[index][level].setInfo(internalFormat, width, height, type);
+ update();
+}
+
+void WebGLTexture::generateMipmapLevelInfo()
+{
+ if (!object() || !m_target)
+ return;
+ if (!canGenerateMipmaps())
+ return;
+ if (!m_isComplete) {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ const LevelInfo& info0 = m_info[ii][0];
+ GC3Dsizei width = info0.width;
+ GC3Dsizei height = info0.height;
+ GC3Dint levelCount = computeLevelCount(width, height);
+ for (GC3Dint level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ LevelInfo& info = m_info[ii][level];
+ info.setInfo(info0.internalFormat, width, height, info0.type);
+ }
+ }
+ m_isComplete = true;
+ }
+ m_needToUseBlackTexture = false;
+}
+
+GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->internalFormat;
+}
+
+GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->type;
+}
+
+GC3Dsizei WebGLTexture::getWidth(GC3Denum target, GC3Dint level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->width;
+}
+
+GC3Dsizei WebGLTexture::getHeight(GC3Denum target, GC3Dint level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->height;
+}
+
+bool WebGLTexture::isNPOT(GC3Dsizei width, GC3Dsizei height)
+{
+ ASSERT(width >= 0 && height >= 0);
+ if (!width || !height)
+ return false;
+ if ((width & (width - 1)) || (height & (height - 1)))
+ return true;
+ return false;
+}
+
+bool WebGLTexture::isNPOT() const
+{
+ if (!object())
+ return false;
+ return m_isNPOT;
+}
+
+bool WebGLTexture::needToUseBlackTexture() const
+{
+ if (!object())
+ return false;
+ return m_needToUseBlackTexture;
+}
+
+void WebGLTexture::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteTexture(object);
+}
+
+int WebGLTexture::mapTargetToIndex(GC3Denum target) const
+{
+ if (m_target == GraphicsContext3D::TEXTURE_2D) {
+ if (target == GraphicsContext3D::TEXTURE_2D)
+ return 0;
+ } else if (m_target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ return 0;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ return 1;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ return 2;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ return 3;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ return 4;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return 5;
+ }
+ }
+ return -1;
+}
+
+bool WebGLTexture::canGenerateMipmaps()
+{
+ if (isNPOT())
+ return false;
+ const LevelInfo& first = m_info[0][0];
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ 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)
+ return false;
+ }
+ return true;
+}
+
+GC3Dint WebGLTexture::computeLevelCount(GC3Dsizei width, GC3Dsizei height)
+{
+ // return 1 + log2Floor(std::max(width, height));
+ GC3Dsizei n = std::max(width, height);
+ if (n <= 0)
+ return 0;
+ GC3Dint log = 0;
+ GC3Dsizei value = n;
+ for (int ii = 4; ii >= 0; --ii) {
+ int shift = (1 << ii);
+ GC3Dsizei x = (value >> shift);
+ if (x) {
+ value = x;
+ log += shift;
+ }
+ }
+ ASSERT(value == 1);
+ return log + 1;
+}
+
+void WebGLTexture::update()
+{
+ m_isNPOT = false;
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) {
+ m_isNPOT = true;
+ break;
+ }
+ }
+ m_isComplete = true;
+ const LevelInfo& first = m_info[0][0];
+ GC3Dint levelCount = computeLevelCount(first.width, first.height);
+ if (levelCount < 1)
+ m_isComplete = false;
+ else {
+ for (size_t ii = 0; ii < m_info.size() && m_isComplete; ++ii) {
+ 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) {
+ m_isComplete = false;
+ break;
+ }
+ GC3Dsizei width = info0.width;
+ GC3Dsizei height = info0.height;
+ for (GC3Dint level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ const LevelInfo& info = m_info[ii][level];
+ if (!info.valid
+ || info.width != width || info.height != height
+ || info.internalFormat != info0.internalFormat || info.type != info0.type) {
+ m_isComplete = false;
+ break;
+ }
+
+ }
+ }
+ }
+
+ m_needToUseBlackTexture = false;
+ // NPOT
+ if (m_isNPOT && ((m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
+ || m_wrapS != GraphicsContext3D::CLAMP_TO_EDGE || m_wrapT != GraphicsContext3D::CLAMP_TO_EDGE))
+ m_needToUseBlackTexture = true;
+ // Completeness
+ if (!m_isComplete && m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
+ m_needToUseBlackTexture = true;
+}
+
+const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GC3Denum target, GC3Dint level) const
+{
+ if (!object() || !m_target)
+ return 0;
+ int targetIndex = mapTargetToIndex(target);
+ if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
+ return 0;
+ if (level < 0 || level >= static_cast<GC3Dint>(m_info[targetIndex].size()))
+ return 0;
+ return &(m_info[targetIndex][level]);
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h
new file mode 100644
index 000000000..6bd12723c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLTexture_h
+#define WebGLTexture_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WebGLTexture : public WebGLObject {
+public:
+ virtual ~WebGLTexture() { deleteObject(); }
+
+ static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+
+ void setTarget(GC3Denum target, GC3Dint maxLevel);
+ void setParameteri(GC3Denum pname, GC3Dint param);
+ void setParameterf(GC3Denum pname, GC3Dfloat param);
+
+ GC3Denum getTarget() const { return m_target; }
+
+ int getMinFilter() const { return m_minFilter; }
+
+ void setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type);
+
+ bool canGenerateMipmaps();
+ // Generate all level information.
+ void generateMipmapLevelInfo();
+
+ GC3Denum getInternalFormat(GC3Denum target, GC3Dint level) const;
+ GC3Denum getType(GC3Denum target, GC3Dint level) const;
+ GC3Dsizei getWidth(GC3Denum target, GC3Dint level) const;
+ GC3Dsizei getHeight(GC3Denum target, GC3Dint level) const;
+
+ // Whether width/height is NotPowerOfTwo.
+ static bool isNPOT(GC3Dsizei, GC3Dsizei);
+
+ bool isNPOT() const;
+ // Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
+ bool needToUseBlackTexture() const;
+
+ bool hasEverBeenBound() const { return object() && m_target; }
+
+ static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
+
+protected:
+ WebGLTexture(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ class LevelInfo {
+ public:
+ LevelInfo()
+ : valid(false)
+ , internalFormat(0)
+ , width(0)
+ , height(0)
+ , type(0)
+ {
+ }
+
+ void setInfo(GC3Denum internalFmt, GC3Dsizei w, GC3Dsizei h, GC3Denum tp)
+ {
+ valid = true;
+ internalFormat = internalFmt;
+ width = w;
+ height = h;
+ type = tp;
+ }
+
+ bool valid;
+ GC3Denum internalFormat;
+ GC3Dsizei width;
+ GC3Dsizei height;
+ GC3Denum type;
+ };
+
+ virtual bool isTexture() const { return true; }
+
+ void update();
+
+ int mapTargetToIndex(GC3Denum) const;
+
+ const LevelInfo* getLevelInfo(GC3Denum target, GC3Dint level) const;
+
+ GC3Denum m_target;
+
+ GC3Denum m_minFilter;
+ GC3Denum m_magFilter;
+ GC3Denum m_wrapS;
+ GC3Denum m_wrapT;
+
+ Vector<Vector<LevelInfo> > m_info;
+
+ bool m_isNPOT;
+ bool m_isComplete;
+ bool m_needToUseBlackTexture;
+};
+
+} // namespace WebCore
+
+#endif // WebGLTexture_h
diff --git a/Source/WebCore/html/canvas/WebGLTexture.idl b/Source/WebCore/html/canvas/WebGLTexture.idl
new file mode 100644
index 000000000..8e72dd34d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLTexture {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
new file mode 100644
index 000000000..1aeddb568
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLUniformLocation.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location)
+{
+ return adoptRef(new WebGLUniformLocation(program, location));
+}
+
+WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GC3Dint location)
+ : m_program(program)
+ , m_location(location)
+{
+ ASSERT(m_program);
+ m_linkCount = m_program->getLinkCount();
+}
+
+WebGLProgram* WebGLUniformLocation::program() const
+{
+ // If the program has been linked again, then this UniformLocation is no
+ // longer valid.
+ if (m_program->getLinkCount() != m_linkCount)
+ return 0;
+ return m_program.get();
+}
+
+GC3Dint WebGLUniformLocation::location() const
+{
+ // If the program has been linked again, then this UniformLocation is no
+ // longer valid.
+ ASSERT(m_program->getLinkCount() == m_linkCount);
+ return m_location;
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.h b/Source/WebCore/html/canvas/WebGLUniformLocation.h
new file mode 100644
index 000000000..6e05c7a4c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.h
@@ -0,0 +1,59 @@
+/*
+ * 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLUniformLocation_h
+#define WebGLUniformLocation_h
+
+#include "WebGLObject.h"
+#include "WebGLProgram.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLUniformLocation : public RefCounted<WebGLUniformLocation> {
+public:
+ virtual ~WebGLUniformLocation() { }
+
+ static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location);
+
+ WebGLProgram* program() const;
+
+ GC3Dint location() const;
+
+protected:
+ WebGLUniformLocation(WebGLProgram*, GC3Dint location);
+
+private:
+ RefPtr<WebGLProgram> m_program;
+ GC3Dint m_location;
+ unsigned m_linkCount;
+};
+
+} // namespace WebCore
+
+#endif // WebGLUniformLocation_h
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.idl b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
new file mode 100644
index 000000000..eb3167cd9
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
@@ -0,0 +1,32 @@
+/*
+ * 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLUniformLocation {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
new file mode 100644
index 000000000..d14c96c01
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLVertexArrayObjectOES.h"
+
+#include "Extensions3D.h"
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
+{
+ return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
+}
+
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
+ : WebGLObject(ctx)
+ , m_type(type)
+ , m_hasEverBeenBound(false)
+ , m_boundElementArrayBuffer(0)
+{
+ m_vertexAttribState.resize(ctx->getMaxVertexAttribs());
+
+ Extensions3D* extensions = context()->graphicsContext3D()->getExtensions();
+ switch (m_type) {
+ case VaoTypeDefault:
+ break;
+ default:
+ setObject(extensions->createVertexArrayOES());
+ break;
+ }
+}
+
+void WebGLVertexArrayObjectOES::deleteObjectImpl(Platform3DObject object)
+{
+ Extensions3D* extensions = context()->graphicsContext3D()->getExtensions();
+ switch (m_type) {
+ case VaoTypeDefault:
+ break;
+ default:
+ extensions->deleteVertexArrayOES(object);
+ break;
+ }
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
new file mode 100644
index 000000000..f49a78069
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLVertexArrayObjectOES_h
+#define WebGLVertexArrayObjectOES_h
+
+#include "WebGLBuffer.h"
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLVertexArrayObjectOES : public WebGLObject {
+public:
+ enum VaoType {
+ VaoTypeDefault,
+ VaoTypeUser,
+ };
+
+ virtual ~WebGLVertexArrayObjectOES() { deleteObject(); }
+
+ 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)
+ {
+ }
+
+ bool enabled;
+ RefPtr<WebGLBuffer> bufferBinding;
+ GC3Dsizei bytesPerElement;
+ GC3Dint size;
+ GC3Denum type;
+ bool normalized;
+ GC3Dsizei stride;
+ GC3Dsizei originalStride;
+ GC3Dintptr offset;
+ };
+
+ 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> buffer) { m_boundElementArrayBuffer = buffer; }
+
+ VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
+
+private:
+ WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+ virtual bool isVertexArray() const { return true; }
+
+ VaoType m_type;
+ bool m_hasEverBeenBound;
+ RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
+ Vector<VertexAttribState> m_vertexAttribState;
+};
+
+} // namespace WebCore
+
+#endif // WebGLVertexArrayObjectOES_h
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
new file mode 100644
index 000000000..0abbe0746
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=WEBGL
+ ] WebGLVertexArrayObjectOES {
+ };
+}