summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/canvas
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-16 16:25:10 +0100
committerBen Murdoch <benm@google.com>2011-05-23 18:54:14 +0100
commitab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb (patch)
treedb769fadd053248f85db67434a5b275224defef7 /Source/WebCore/html/canvas
parent52e2557aeb8477967e97fd24f20f8f407a10fa15 (diff)
downloadexternal_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.zip
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.gz
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.bz2
Merge WebKit at r76408: Initial merge by git.
Change-Id: I5b91decbd693ccbf5c1b8354b37cd68cc9a1ea53
Diffstat (limited to 'Source/WebCore/html/canvas')
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h3
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp9
-rw-r--r--Source/WebCore/html/canvas/CheckedInt.h103
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.cpp54
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.h48
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.idl30
-rw-r--r--Source/WebCore/html/canvas/TypedArrayBase.h14
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp16
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.h1
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp230
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h2
11 files changed, 461 insertions, 49 deletions
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
index a25e8a1..a143596 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -41,7 +41,8 @@ class HTMLVideoElement;
class KURL;
class WebGLObject;
-class CanvasRenderingContext : public Noncopyable {
+class CanvasRenderingContext {
+ WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
public:
CanvasRenderingContext(HTMLCanvasElement*);
virtual ~CanvasRenderingContext() { }
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 62c5793..e029128 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -57,6 +57,7 @@
#include "Settings.h"
#include "StrokeStyleApplier.h"
#include "TextMetrics.h"
+#include "TextRun.h"
#if ENABLE(ACCELERATED_2D_CANVAS)
#include "Chrome.h"
@@ -170,7 +171,7 @@ void CanvasRenderingContext2D::reset()
m_path.clear();
#if ENABLE(ACCELERATED_2D_CANVAS)
if (GraphicsContext* c = drawingContext()) {
- if (m_context3D) {
+ if (m_context3D && m_drawingBuffer) {
m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
}
@@ -537,7 +538,7 @@ void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float
return;
AffineTransform transform(m11, m12, m21, m22, dx, dy);
- AffineTransform newTransform = transform * state().m_transform;
+ AffineTransform newTransform = state().m_transform * transform;
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
return;
@@ -562,7 +563,7 @@ void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, flo
return;
c->concatCTM(c->getCTM().inverse());
c->concatCTM(canvas()->baseTransform());
- state().m_transform.multiply(ctm.inverse());
+ state().m_transform = ctm.inverse() * state().m_transform;
m_path.transform(ctm);
state().m_invertibleCTM = true;
@@ -1895,7 +1896,7 @@ void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
PlatformLayer* CanvasRenderingContext2D::platformLayer() const
{
- return m_drawingBuffer->platformLayer();
+ return m_drawingBuffer ? m_drawingBuffer->platformLayer() : 0;
}
#endif
diff --git a/Source/WebCore/html/canvas/CheckedInt.h b/Source/WebCore/html/canvas/CheckedInt.h
index 861e8e6..b83ac19 100644
--- a/Source/WebCore/html/canvas/CheckedInt.h
+++ b/Source/WebCore/html/canvas/CheckedInt.h
@@ -60,29 +60,93 @@ namespace CheckedInt_internal {
struct unsupported_type {};
-template<typename T> struct integer_type_manually_recorded_info
-{
- enum { is_supported = 0 };
- typedef unsupported_type twice_bigger_type;
-};
+template<typename T> struct integer_type_manually_recorded_info;
-#define CHECKEDINT_REGISTER_SUPPORTED_TYPE(T,_twice_bigger_type) \
+#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; \
- static void TYPE_NOT_SUPPORTED_BY_CheckedInt() {} \
+ typedef _unsigned_type unsigned_type; \
};
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(int8_t, int16_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint8_t, uint16_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(int16_t, int32_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint16_t, uint32_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(int32_t, int64_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint32_t, uint64_t)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(int64_t, unsupported_type)
-CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint64_t, unsupported_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,
@@ -348,8 +412,7 @@ protected:
template<typename U>
CheckedInt(const U& value, bool isValid) : mValue(value), mIsValid(isValid)
{
- CheckedInt_internal::integer_type_manually_recorded_info<T>
- ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
}
public:
@@ -366,15 +429,13 @@ public:
: mValue(value),
mIsValid(CheckedInt_internal::is_in_range<T>(value))
{
- CheckedInt_internal::integer_type_manually_recorded_info<T>
- ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
}
/** Constructs a valid checked integer with uninitialized value */
CheckedInt() : mIsValid(1)
{
- CheckedInt_internal::integer_type_manually_recorded_info<T>
- ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ CheckedInt_internal::TYPE_NOT_SUPPORTED_BY_CheckedInt<T>::run();
}
/** \returns the actual value */
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
new file mode 100644
index 0000000..25aae2f
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "OESStandardDerivatives.h"
+
+namespace WebCore {
+
+OESStandardDerivatives::OESStandardDerivatives() : WebGLExtension()
+{
+}
+
+OESStandardDerivatives::~OESStandardDerivatives()
+{
+}
+
+WebGLExtension::ExtensionName OESStandardDerivatives::getName() const
+{
+ return OESStandardDerivativesName;
+}
+
+PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create()
+{
+ return adoptRef(new OESStandardDerivatives);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.h b/Source/WebCore/html/canvas/OESStandardDerivatives.h
new file mode 100644
index 0000000..c74e24f
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.h
@@ -0,0 +1,48 @@
+/*
+ * 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/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class OESStandardDerivatives : public WebGLExtension {
+public:
+ static PassRefPtr<OESStandardDerivatives> create();
+
+ virtual ~OESStandardDerivatives();
+ virtual ExtensionName getName() const;
+
+private:
+ OESStandardDerivatives();
+};
+
+} // 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 0000000..a9d1dd6
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.idl
@@ -0,0 +1,30 @@
+/*
+ * 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=3D_CANVAS, OmitConstructor, DontCheckEnums] OESStandardDerivatives {
+ const unsigned int FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+ };
+}
diff --git a/Source/WebCore/html/canvas/TypedArrayBase.h b/Source/WebCore/html/canvas/TypedArrayBase.h
index 2bef6f0..a828620 100644
--- a/Source/WebCore/html/canvas/TypedArrayBase.h
+++ b/Source/WebCore/html/canvas/TypedArrayBase.h
@@ -60,7 +60,12 @@ class TypedArrayBase : public ArrayBufferView {
return m_length;
}
- protected:
+ virtual unsigned byteLength() const
+ {
+ return m_length * sizeof(T);
+ }
+
+protected:
TypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
: ArrayBufferView(buffer, byteOffset)
, m_length(length)
@@ -110,13 +115,6 @@ class TypedArrayBase : public ArrayBufferView {
// We do not want to have to access this via a virtual function in subclasses,
// which is why it is protected rather than private.
unsigned m_length;
-
- private:
- // Overridden from ArrayBufferView.
- virtual unsigned byteLength() const
- {
- return m_length * sizeof(T);
- }
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
index 4566bfa..849472b 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -61,9 +61,9 @@ bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOff
return false;
if (array && byteLength) {
- CheckedInt<int32_t> checkedOffset(byteOffset);
- CheckedInt<int32_t> checkedLength(byteLength);
- CheckedInt<int32_t> checkedMax = checkedOffset + checkedLength;
+ 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;
}
@@ -124,11 +124,11 @@ bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, ArrayBuffer* arr
return false;
if (byteLength) {
- CheckedInt<int32_t> checkedBufferOffset(offset);
- CheckedInt<int32_t> checkedArrayOffset(arrayByteOffset);
- CheckedInt<int32_t> checkedLength(byteLength);
- CheckedInt<int32_t> checkedArrayMax = checkedArrayOffset + checkedLength;
- CheckedInt<int32_t> checkedBufferMax = checkedBufferOffset + checkedLength;
+ 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;
}
diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h
index f2d6b7b..d135c18 100644
--- a/Source/WebCore/html/canvas/WebGLExtension.h
+++ b/Source/WebCore/html/canvas/WebGLExtension.h
@@ -36,6 +36,7 @@ public:
enum ExtensionName {
WebKitLoseContextName,
OESTextureFloatName,
+ OESStandardDerivativesName,
};
virtual ~WebGLExtension();
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index c445e2b..a3b9699 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -44,6 +44,7 @@
#include "ImageData.h"
#include "IntSize.h"
#include "NotImplemented.h"
+#include "OESStandardDerivatives.h"
#include "OESTextureFloat.h"
#include "RenderBox.h"
#include "RenderLayer.h"
@@ -62,6 +63,7 @@
#include <wtf/ByteArray.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassOwnArrayPtr.h>
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -101,12 +103,11 @@ namespace {
// Return true if a character belongs to the ASCII subset as defined in
// GLSL ES 1.0 spec section 3.1.
- // We make exceptions for " ' `.
bool validateCharacter(unsigned char c)
{
// Printing characters are valid except " $ ` @ \ ' DEL.
if (c >= 32 && c <= 126
- && c != '$' && c != '@' && c != '\\')
+ && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
return true;
// Horizontal tab, line feed, vertical tab, form feed, carriage return
// are also valid.
@@ -115,6 +116,189 @@ namespace {
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 {
@@ -1574,6 +1758,14 @@ 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();
+ }
+ return m_oesStandardDerivatives.get();
+ }
if (equalIgnoringCase(name, "OES_texture_float")
&& m_context->getExtensions()->supports("GL_OES_texture_float")) {
if (!m_oesTextureFloat) {
@@ -1581,7 +1773,8 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
m_oesTextureFloat = OESTextureFloat::create();
}
return m_oesTextureFloat.get();
- } else if (equalIgnoringCase(name, "WEBKIT_lose_context")) {
+ }
+ if (equalIgnoringCase(name, "WEBKIT_lose_context")) {
if (!m_webkitLoseContext)
m_webkitLoseContext = WebKitLoseContext::create(this);
return m_webkitLoseContext.get();
@@ -1823,6 +2016,11 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
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 getUnsignedLongParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
default:
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return WebGLGetInfo();
@@ -1990,6 +2188,8 @@ 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");
result.append("WEBKIT_lose_context");
return result;
}
@@ -2234,7 +2434,17 @@ void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
{
if (isContextLost())
return;
- if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
+ 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;
}
@@ -2547,9 +2757,10 @@ void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& stri
UNUSED_PARAM(ec);
if (isContextLost() || !validateWebGLObject(shader))
return;
- if (!validateString(string))
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString(stringWithoutComments))
return;
- m_context->shaderSource(objectOrZero(shader), string);
+ m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
cleanupAfterGraphicsCall(false);
}
@@ -4352,11 +4563,16 @@ void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
int WebGLRenderingContext::getNumberOfExtensions()
{
- return (m_webkitLoseContext ? 1 : 0) + (m_oesTextureFloat ? 1 : 0);
+ return (m_oesStandardDerivatives ? 1 : 0) + (m_webkitLoseContext ? 1 : 0) + (m_oesTextureFloat ? 1 : 0);
}
WebGLExtension* WebGLRenderingContext::getExtensionNumber(int i)
{
+ if (m_oesStandardDerivatives) {
+ if (!i)
+ return m_oesStandardDerivatives.get();
+ --i;
+ }
if (m_webkitLoseContext) {
if (!i)
return m_webkitLoseContext.get();
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index d9b738c..01b5438 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -57,6 +57,7 @@ class HTMLVideoElement;
class ImageBuffer;
class ImageData;
class IntSize;
+class OESStandardDerivatives;
class OESTextureFloat;
class WebGLRenderingContext : public CanvasRenderingContext {
@@ -452,6 +453,7 @@ public:
// Enabled extension objects.
RefPtr<OESTextureFloat> m_oesTextureFloat;
+ RefPtr<OESStandardDerivatives> m_oesStandardDerivatives;
RefPtr<WebKitLoseContext> m_webkitLoseContext;
// Helpers for getParameter and others