diff options
author | Ben Murdoch <benm@google.com> | 2011-05-16 16:25:10 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-23 18:54:14 +0100 |
commit | ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb (patch) | |
tree | db769fadd053248f85db67434a5b275224defef7 /Source/WebCore/html/canvas | |
parent | 52e2557aeb8477967e97fd24f20f8f407a10fa15 (diff) | |
download | external_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.h | 3 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp | 9 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/CheckedInt.h | 103 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/OESStandardDerivatives.cpp | 54 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/OESStandardDerivatives.h | 48 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/OESStandardDerivatives.idl | 30 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/TypedArrayBase.h | 14 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/WebGLBuffer.cpp | 16 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/WebGLExtension.h | 1 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/WebGLRenderingContext.cpp | 230 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/WebGLRenderingContext.h | 2 |
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 |