diff options
Diffstat (limited to 'Source/WebCore/html/canvas')
20 files changed, 602 insertions, 143 deletions
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp index 9ef2dba..a549782 100644 --- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -174,6 +174,11 @@ void CanvasRenderingContext2D::reset() 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())); +#if USE(ACCELERATED_COMPOSITING) + RenderBox* renderBox = canvas()->renderBox(); + if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing()) + renderBox->layer()->contentChanged(RenderLayer::CanvasChanged); +#endif } } #endif @@ -446,7 +451,7 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati if (!c) return; c->setCompositeOperation(op); -#if ENABLE(ACCELERATED_2D_CANVAS) +#if ENABLE(ACCELERATED_2D_CANVAS) && !ENABLE(SKIA_GPU) if (isAccelerated() && op != CompositeSourceOver) { c->setSharedGraphicsContext3D(0, 0, IntSize()); m_drawingBuffer.clear(); @@ -877,6 +882,8 @@ bool CanvasRenderingContext2D::isPointInPath(const float x, const float y) 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); } @@ -1771,7 +1778,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo unsigned length = text.length(); const UChar* string = text.characters(); - TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override, false, false); + TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override); // Draw the item text at the correct point. FloatPoint location(x, y); diff --git a/Source/WebCore/html/canvas/Int32Array.h b/Source/WebCore/html/canvas/Int32Array.h index c657300..3a98eed 100644 --- a/Source/WebCore/html/canvas/Int32Array.h +++ b/Source/WebCore/html/canvas/Int32Array.h @@ -38,8 +38,8 @@ public: static PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); // Can’t use "using" here due to a bug in the RVCT compiler. - void set(TypedArrayBase<int>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<int>::set(array, offset, ec); } - void set(unsigned index, double value) { return IntegralTypedArrayBase<int>::set(index, value); } + void set(TypedArrayBase<int>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<int>::set(array, offset, ec); } + void set(unsigned index, double value) { IntegralTypedArrayBase<int>::set(index, value); } PassRefPtr<Int32Array> subarray(int start) const; PassRefPtr<Int32Array> subarray(int start, int end) const; diff --git a/Source/WebCore/html/canvas/Int8Array.h b/Source/WebCore/html/canvas/Int8Array.h index aabdb97..2d3fc89 100644 --- a/Source/WebCore/html/canvas/Int8Array.h +++ b/Source/WebCore/html/canvas/Int8Array.h @@ -40,8 +40,8 @@ public: static PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); // Can’t use "using" here due to a bug in the RVCT compiler. - void set(TypedArrayBase<signed char>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<signed char>::set(array, offset, ec); } - void set(unsigned index, double value) { return IntegralTypedArrayBase<signed char>::set(index, value); } + void set(TypedArrayBase<signed char>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<signed char>::set(array, offset, ec); } + void set(unsigned index, double value) { IntegralTypedArrayBase<signed char>::set(index, value); } PassRefPtr<Int8Array> subarray(int start) const; PassRefPtr<Int8Array> subarray(int start, int end) const; diff --git a/Source/WebCore/html/canvas/IntegralTypedArrayBase.h b/Source/WebCore/html/canvas/IntegralTypedArrayBase.h index b87d832..0b26844 100644 --- a/Source/WebCore/html/canvas/IntegralTypedArrayBase.h +++ b/Source/WebCore/html/canvas/IntegralTypedArrayBase.h @@ -45,11 +45,9 @@ class IntegralTypedArrayBase : public TypedArrayBase<T> { return; if (isnan(value)) // Clamp NaN to 0 value = 0; - if (value < std::numeric_limits<T>::min()) - value = std::numeric_limits<T>::min(); - else if (value > std::numeric_limits<T>::max()) - value = std::numeric_limits<T>::max(); - TypedArrayBase<T>::data()[index] = static_cast<T>(value); + // The double cast is necessary to get the correct wrapping + // for out-of-range values with Int32Array and Uint32Array. + TypedArrayBase<T>::data()[index] = static_cast<T>(static_cast<int64_t>(value)); } // Invoked by the indexed getter. Does not perform range checks; caller diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp new file mode 100644 index 0000000..5fb71c8 --- /dev/null +++ b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp @@ -0,0 +1,116 @@ +/* + * 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() + , m_context(context) +{ +} + +OESVertexArrayObject::~OESVertexArrayObject() +{ +} + +WebGLExtension::ExtensionName OESVertexArrayObject::getName() const +{ + return OESVertexArrayObjectName; +} + +PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context) +{ + return adoptRef(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 0000000..d9792da --- /dev/null +++ b/Source/WebCore/html/canvas/OESVertexArrayObject.h @@ -0,0 +1,63 @@ +/* + * 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 "ExceptionCode.h" +#include "GraphicsTypes3D.h" +#include "WebGLExtension.h" +#include "WebGLVertexArrayObjectOES.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/UnusedParam.h> + +namespace WebCore { + +class WebGLRenderingContext; +class WebGLVertexArrayObjectOES; + +class OESVertexArrayObject : public WebGLExtension { +public: + static PassRefPtr<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*); + + WebGLRenderingContext* m_context; +}; + +} // 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 0000000..911ebbc --- /dev/null +++ b/Source/WebCore/html/canvas/OESVertexArrayObject.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 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, OmitConstructor, DontCheckEnums] OESVertexArrayObject { + const unsigned int VERTEX_ARRAY_BINDING_OES = 0x85B5; + + [StrictTypeChecking] WebGLVertexArrayObjectOES createVertexArrayOES(); + [StrictTypeChecking] void deleteVertexArrayOES(in WebGLVertexArrayObjectOES arrayObject); + [StrictTypeChecking] boolean isVertexArrayOES(in WebGLVertexArrayObjectOES arrayObject); + [StrictTypeChecking] void bindVertexArrayOES(in WebGLVertexArrayObjectOES arrayObject) raises(DOMException); + }; +} diff --git a/Source/WebCore/html/canvas/Uint16Array.h b/Source/WebCore/html/canvas/Uint16Array.h index 8ef04a4..0b02d09 100644 --- a/Source/WebCore/html/canvas/Uint16Array.h +++ b/Source/WebCore/html/canvas/Uint16Array.h @@ -40,8 +40,8 @@ public: static PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); // Can’t use "using" here due to a bug in the RVCT compiler. - void set(TypedArrayBase<unsigned short>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned short>::set(array, offset, ec); } - void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned short>::set(index, value); } + void set(TypedArrayBase<unsigned short>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<unsigned short>::set(array, offset, ec); } + void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned short>::set(index, value); } PassRefPtr<Uint16Array> subarray(int start) const; PassRefPtr<Uint16Array> subarray(int start, int end) const; diff --git a/Source/WebCore/html/canvas/Uint32Array.h b/Source/WebCore/html/canvas/Uint32Array.h index 196a67f..15a7ab6 100644 --- a/Source/WebCore/html/canvas/Uint32Array.h +++ b/Source/WebCore/html/canvas/Uint32Array.h @@ -40,8 +40,8 @@ public: static PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); // Can’t use "using" here due to a bug in the RVCT compiler. - void set(TypedArrayBase<unsigned int>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned int>::set(array, offset, ec); } - void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned int>::set(index, value); } + void set(TypedArrayBase<unsigned int>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<unsigned int>::set(array, offset, ec); } + void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned int>::set(index, value); } PassRefPtr<Uint32Array> subarray(int start) const; PassRefPtr<Uint32Array> subarray(int start, int end) const; diff --git a/Source/WebCore/html/canvas/Uint8Array.h b/Source/WebCore/html/canvas/Uint8Array.h index a3a42dc..3da1eaa 100644 --- a/Source/WebCore/html/canvas/Uint8Array.h +++ b/Source/WebCore/html/canvas/Uint8Array.h @@ -40,8 +40,8 @@ public: static PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); // Can’t use "using" here due to a bug in the RVCT compiler. - void set(TypedArrayBase<unsigned char>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned char>::set(array, offset, ec); } - void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned char>::set(index, value); } + void set(TypedArrayBase<unsigned char>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<unsigned char>::set(array, offset, ec); } + void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned char>::set(index, value); } PassRefPtr<Uint8Array> subarray(int start) const; PassRefPtr<Uint8Array> subarray(int start, int end) const; diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h index d135c18..9a6753f 100644 --- a/Source/WebCore/html/canvas/WebGLExtension.h +++ b/Source/WebCore/html/canvas/WebGLExtension.h @@ -37,6 +37,7 @@ public: WebKitLoseContextName, OESTextureFloatName, OESStandardDerivativesName, + OESVertexArrayObjectName, }; virtual ~WebGLExtension(); diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp index d0c8c65..17be974 100644 --- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp +++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp @@ -38,6 +38,7 @@ #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" #include "WebGLTexture.h" +#include "WebGLVertexArrayObjectOES.h" namespace WebCore { @@ -134,6 +135,12 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value) { } +WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value) + : m_type(kTypeWebGLVertexArrayObjectOES) + , m_webglVertexArrayObject(value) +{ +} + WebGLGetInfo::~WebGLGetInfo() { } @@ -227,6 +234,12 @@ PassRefPtr<Uint8Array> WebGLGetInfo::getWebGLUnsignedByteArray() const 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 index 91f9233..bc2aacc 100644 --- a/Source/WebCore/html/canvas/WebGLGetInfo.h +++ b/Source/WebCore/html/canvas/WebGLGetInfo.h @@ -36,6 +36,7 @@ #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" #include "WebGLTexture.h" +#include "WebGLVertexArrayObjectOES.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> @@ -65,7 +66,8 @@ public: kTypeWebGLProgram, kTypeWebGLRenderbuffer, kTypeWebGLTexture, - kTypeWebGLUnsignedByteArray + kTypeWebGLUnsignedByteArray, + kTypeWebGLVertexArrayObjectOES, }; WebGLGetInfo(bool value); @@ -86,6 +88,7 @@ public: WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value); WebGLGetInfo(PassRefPtr<WebGLTexture> value); WebGLGetInfo(PassRefPtr<Uint8Array> value); + WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value); virtual ~WebGLGetInfo(); @@ -107,6 +110,7 @@ public: PassRefPtr<WebGLRenderbuffer> getWebGLRenderbuffer() const; PassRefPtr<WebGLTexture> getWebGLTexture() const; PassRefPtr<Uint8Array> getWebGLUnsignedByteArray() const; + PassRefPtr<WebGLVertexArrayObjectOES> getWebGLVertexArrayObjectOES() const; private: Type m_type; @@ -126,6 +130,7 @@ private: RefPtr<WebGLRenderbuffer> m_webglRenderbuffer; RefPtr<WebGLTexture> m_webglTexture; RefPtr<Uint8Array> m_webglUnsignedByteArray; + RefPtr<WebGLVertexArrayObjectOES> m_webglVertexArrayObject; }; } // namespace WebCore diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index bd155c9..cc7a23b 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -46,6 +46,7 @@ #include "NotImplemented.h" #include "OESStandardDerivatives.h" #include "OESTextureFloat.h" +#include "OESVertexArrayObject.h" #include "RenderBox.h" #include "RenderLayer.h" #include "Settings.h" @@ -66,6 +67,10 @@ #include <wtf/PassOwnArrayPtr.h> #include <wtf/text/StringBuilder.h> +#if PLATFORM(QT) +#undef emit +#endif + namespace WebCore { const double secondsBetweenRestoreAttempts = 1.0; @@ -398,7 +403,6 @@ void WebGLRenderingContext::initializeNewContext() m_unpackPremultiplyAlpha = false; m_unpackColorspaceConversion = GraphicsContext3D::BROWSER_DEFAULT_WEBGL; m_boundArrayBuffer = 0; - m_boundElementArrayBuffer = 0; m_currentProgram = 0; m_framebufferBinding = 0; m_renderbufferBinding = 0; @@ -408,7 +412,6 @@ void WebGLRenderingContext::initializeNewContext() m_stencilFuncRefBack = 0; m_stencilFuncMask = 0xFFFFFFFF; m_stencilFuncMaskBack = 0xFFFFFFFF; - m_vertexAttribState.clear(); GC3Dint numCombinedTextureImageUnits = 0; m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits); @@ -418,13 +421,19 @@ void WebGLRenderingContext::initializeNewContext() 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_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault); + addObject(m_defaultVertexArrayObject.get()); + m_boundVertexArrayObject = m_defaultVertexArrayObject; + + m_vertexAttribValue.resize(m_maxVertexAttribs); if (!isGLES2NPOTStrict()) createFallbackBlackTextures1x1(); @@ -457,6 +466,8 @@ WebGLRenderingContext::~WebGLRenderingContext() { detachAndRemoveAllObjects(); m_context->setContextLostCallback(0); + if (m_webkitLoseContext) + m_webkitLoseContext->contextDestroyed(); } void WebGLRenderingContext::markContextChanged() @@ -596,7 +607,7 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc if (target == GraphicsContext3D::ARRAY_BUFFER) m_boundArrayBuffer = buffer; else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) - m_boundElementArrayBuffer = buffer; + m_boundVertexArrayObject->setElementArrayBuffer(buffer); else { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return; @@ -1112,10 +1123,11 @@ void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) return; if (m_boundArrayBuffer == buffer) m_boundArrayBuffer = 0; - if (m_boundElementArrayBuffer == buffer) - m_boundElementArrayBuffer = 0; + RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer(); + if (elementArrayBuffer == buffer) + m_boundVertexArrayObject->setElementArrayBuffer(0); if (!isGLES2Compliant()) { - VertexAttribState& state = m_vertexAttribState[0]; + WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0); if (buffer == state.bufferBinding) { state.bufferBinding = m_vertexAttrib0Buffer; state.bytesPerElement = 0; @@ -1236,8 +1248,8 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo return; } - if (index < m_vertexAttribState.size()) - m_vertexAttribState[index].enabled = false; + WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index); + state.enabled = false; if (index > 0 || isGLES2Compliant()) { m_context->disableVertexAttribArray(index); @@ -1247,7 +1259,9 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo bool WebGLRenderingContext::validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset) { - if (!m_boundElementArrayBuffer) + RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer(); + + if (!elementArrayBuffer) return false; if (offset < 0) @@ -1261,11 +1275,11 @@ bool WebGLRenderingContext::validateElementArraySize(GC3Dsizei count, GC3Denum t // Make uoffset an element offset. offset /= 2; - GC3Dsizeiptr n = m_boundElementArrayBuffer->byteLength() / 2; + GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 2; if (offset > n || count > n - offset) return false; } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { - GC3Dsizeiptr n = m_boundElementArrayBuffer->byteLength(); + GC3Dsizeiptr n = elementArrayBuffer->byteLength(); if (offset > n || count > n - offset) return false; } @@ -1279,18 +1293,20 @@ bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, int& n // 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 (!m_boundElementArrayBuffer) + if (!elementArrayBuffer) return false; - GC3Dsizeiptr numElements = m_boundElementArrayBuffer->byteLength(); + GC3Dsizeiptr numElements = elementArrayBuffer->byteLength(); // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative. if (!numElements) return false; - const ArrayBuffer* buffer = m_boundElementArrayBuffer->elementArrayBuffer(); + const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer(); ASSERT(buffer); - int maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type); + int maxIndex = elementArrayBuffer->getCachedMaxIndex(type); if (maxIndex < 0) { // Compute the maximum index in the entire buffer for the given type of index. switch (type) { @@ -1310,7 +1326,7 @@ bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, int& n default: return false; } - m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex); + elementArrayBuffer->setCachedMaxIndex(type, maxIndex); } if (maxIndex >= 0) { @@ -1327,8 +1343,10 @@ bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum { ASSERT(count >= 0 && offset >= 0); int lastIndex = -1; + + RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer(); - if (!m_boundElementArrayBuffer) + if (!elementArrayBuffer) return false; if (!count) { @@ -1336,7 +1354,7 @@ bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum return true; } - if (!m_boundElementArrayBuffer->elementArrayBuffer()) + if (!elementArrayBuffer->elementArrayBuffer()) return false; unsigned long uoffset = offset; @@ -1345,14 +1363,14 @@ bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum if (type == GraphicsContext3D::UNSIGNED_SHORT) { // Make uoffset an element offset. uoffset /= sizeof(GC3Dushort); - const GC3Dushort* p = static_cast<const GC3Dushort*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; + 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*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; + const GC3Dubyte* p = static_cast<const GC3Dubyte*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset; while (n-- > 0) { if (*p > lastIndex) lastIndex = *p; @@ -1370,12 +1388,11 @@ bool WebGLRenderingContext::validateRenderingState(int numElementsRequired) if (!m_currentProgram) return false; - int numAttribStates = static_cast<int>(m_vertexAttribState.size()); - // Look in each enabled vertex attrib and check if they've been bound to a buffer. - for (int i = 0; i < numAttribStates; ++i) { - if (m_vertexAttribState[i].enabled - && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object())) + 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; } @@ -1387,8 +1404,8 @@ bool WebGLRenderingContext::validateRenderingState(int numElementsRequired) int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations(); for (int i = 0; i < numActiveAttribLocations; ++i) { int loc = m_currentProgram->getActiveAttribLocation(i); - if (loc >=0 && loc < numAttribStates) { - const VertexAttribState& state = m_vertexAttribState[loc]; + 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 @@ -1502,7 +1519,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu if (!count) return; - if (!m_boundElementArrayBuffer) { + if (!m_boundVertexArrayObject->getElementArrayBuffer()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } @@ -1568,10 +1585,8 @@ void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCod return; } - if (index >= m_vertexAttribState.size()) - m_vertexAttribState.resize(index + 1); - - m_vertexAttribState[index].enabled = true; + WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index); + state.enabled = true; m_context->enableVertexAttribArray(index); cleanupAfterGraphicsCall(false); @@ -1845,6 +1860,14 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } 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_lose_context")) { if (!m_webkitLoseContext) m_webkitLoseContext = WebKitLoseContext::create(this); @@ -1965,7 +1988,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::DITHER: return getBooleanParameter(pname); case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING: - return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer)); + return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer())); case GraphicsContext3D::FRAMEBUFFER_BINDING: return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding)); case GraphicsContext3D::FRONT_FACE: @@ -2091,6 +2114,14 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES); 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(); @@ -2252,6 +2283,8 @@ Vector<String> WebGLRenderingContext::getSupportedExtensions() 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_lose_context"); return result; } @@ -2447,40 +2480,26 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna 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_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer) - || index >= m_vertexAttribState.size() - || !m_vertexAttribState[index].bufferBinding - || !m_vertexAttribState[index].bufferBinding->object()) + if ((!isGLES2Compliant() && !index && m_boundVertexArrayObject->getVertexAttribState(0).bufferBinding == m_vertexAttrib0Buffer) + || !state.bufferBinding + || !state.bufferBinding->object()) return WebGLGetInfo(); - return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding)); + return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding)); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED: - if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(false); - return WebGLGetInfo(m_vertexAttribState[index].enabled); + return WebGLGetInfo(state.enabled); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED: - if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(false); - return WebGLGetInfo(m_vertexAttribState[index].normalized); + return WebGLGetInfo(state.normalized); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE: - if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<int>(4)); - return WebGLGetInfo(m_vertexAttribState[index].size); + return WebGLGetInfo(state.size); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE: - if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<int>(0)); - return WebGLGetInfo(m_vertexAttribState[index].originalStride); + return WebGLGetInfo(state.originalStride); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE: - if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<unsigned int>(GraphicsContext3D::FLOAT)); - return WebGLGetInfo(m_vertexAttribState[index].type); + return WebGLGetInfo(state.type); case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: - if (index >= m_vertexAttribState.size()) { - float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - return WebGLGetInfo(Float32Array::create(value, 4)); - } - return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4)); + return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4)); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -3718,19 +3737,17 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC } GC3Dsizei bytesPerElement = size * typeSize; - if (index >= m_vertexAttribState.size()) - m_vertexAttribState.resize(index + 1); - GC3Dsizei validatedStride = stride ? stride : bytesPerElement; - m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer; - m_vertexAttribState[index].bytesPerElement = bytesPerElement; - m_vertexAttribState[index].size = size; - m_vertexAttribState[index].type = type; - m_vertexAttribState[index].normalized = normalized; - m_vertexAttribState[index].stride = validatedStride; - m_vertexAttribState[index].originalStride = stride; - m_vertexAttribState[index].offset = offset; + 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); } @@ -4467,7 +4484,7 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target WebGLBuffer* buffer = 0; switch (target) { case GraphicsContext3D::ELEMENT_ARRAY_BUFFER: - buffer = m_boundElementArrayBuffer.get(); + buffer = m_boundVertexArrayObject->getElementArrayBuffer().get(); break; case GraphicsContext3D::ARRAY_BUFFER: buffer = m_boundArrayBuffer.get(); @@ -4516,12 +4533,11 @@ void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expected } cleanupAfterGraphicsCall(false); } - if (index >= m_vertexAttribState.size()) - m_vertexAttribState.resize(index + 1); - m_vertexAttribState[index].value[0] = v0; - m_vertexAttribState[index].value[1] = v1; - m_vertexAttribState[index].value[2] = v2; - m_vertexAttribState[index].value[3] = v3; + 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) @@ -4569,21 +4585,21 @@ void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, GC3Dfloat* v, GC3 } cleanupAfterGraphicsCall(false); } - if (index >= m_vertexAttribState.size()) - m_vertexAttribState.resize(index + 1); - m_vertexAttribState[index].initValue(); + VertexAttribValue& attribValue = m_vertexAttribValue[index]; + attribValue.initValue(); for (int ii = 0; ii < expectedSize; ++ii) - m_vertexAttribState[index].value[ii] = v[ii]; + attribValue.value[ii] = v[ii]; } void WebGLRenderingContext::initVertexAttrib0() { - m_vertexAttribState.resize(1); + 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); - m_vertexAttribState[0].bufferBinding = m_vertexAttrib0Buffer; + state.bufferBinding = m_vertexAttrib0Buffer; m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0); m_context->enableVertexAttribArray(0); m_vertexAttrib0BufferSize = 0; @@ -4597,7 +4613,8 @@ void WebGLRenderingContext::initVertexAttrib0() bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex) { - const VertexAttribState& state = m_vertexAttribState[0]; + const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0); + const VertexAttribValue& attribValue = m_vertexAttribValue[0]; if (!m_currentProgram) return false; bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0(); @@ -4617,21 +4634,21 @@ bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex) } if (usingVertexAttrib0 && (m_forceAttrib0BufferRefill - || state.value[0] != m_vertexAttrib0BufferValue[0] - || state.value[1] != m_vertexAttrib0BufferValue[1] - || state.value[2] != m_vertexAttrib0BufferValue[2] - || state.value[3] != m_vertexAttrib0BufferValue[3])) { + || 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] = state.value[0]; - bufferData[ii * 4 + 1] = state.value[1]; - bufferData[ii * 4 + 2] = state.value[2]; - bufferData[ii * 4 + 3] = state.value[3]; + 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] = state.value[0]; - m_vertexAttrib0BufferValue[1] = state.value[1]; - m_vertexAttrib0BufferValue[2] = state.value[2]; - m_vertexAttrib0BufferValue[3] = state.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()); } @@ -4641,7 +4658,7 @@ bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex) void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation() { - const VertexAttribState& state = m_vertexAttribState[0]; + 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); @@ -4651,11 +4668,16 @@ void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation() int WebGLRenderingContext::getNumberOfExtensions() { - return (m_oesStandardDerivatives ? 1 : 0) + (m_webkitLoseContext ? 1 : 0) + (m_oesTextureFloat ? 1 : 0); + return (m_oesVertexArrayObject ? 1 : 0) + (m_oesStandardDerivatives ? 1 : 0) + (m_webkitLoseContext ? 1 : 0) + (m_oesTextureFloat ? 1 : 0); } WebGLExtension* WebGLRenderingContext::getExtensionNumber(int i) { + if (m_oesVertexArrayObject) { + if (!i) + return m_oesVertexArrayObject.get(); + --i; + } if (m_oesStandardDerivatives) { if (!i) return m_oesStandardDerivatives.get(); diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h index dd71620..13145c8 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.h +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h @@ -59,6 +59,8 @@ class ImageData; class IntSize; class OESStandardDerivatives; class OESTextureFloat; +class OESVertexArrayObject; +class WebGLVertexArrayObjectOES; class WebGLRenderingContext : public CanvasRenderingContext { public: @@ -286,6 +288,8 @@ public: virtual void paintRenderingResultsToCanvas(); void removeObject(WebGLObject*); + + unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; } // Helpers for JSC bindings. int getNumberOfExtensions(); @@ -293,6 +297,7 @@ public: private: friend class WebGLObject; + friend class OESVertexArrayObject; WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes); void initializeNewContext(); @@ -362,24 +367,24 @@ public: // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER RefPtr<WebGLBuffer> m_boundArrayBuffer; - RefPtr<WebGLBuffer> m_boundElementArrayBuffer; - - // Cached values for vertex attrib range checks - class VertexAttribState { + + 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: - VertexAttribState() - : enabled(false) - , bytesPerElement(0) - , size(4) - , type(GraphicsContext3D::FLOAT) - , normalized(false) - , stride(16) - , originalStride(0) - , offset(0) + VertexAttribValue() { initValue(); } - + void initValue() { value[0] = 0.0f; @@ -387,20 +392,10 @@ public: value[2] = 0.0f; value[3] = 1.0f; } - - bool enabled; - RefPtr<WebGLBuffer> bufferBinding; - GC3Dsizei bytesPerElement; - GC3Dint size; - GC3Denum type; - bool normalized; - GC3Dsizei stride; - GC3Dsizei originalStride; - GC3Dintptr offset; + GC3Dfloat value[4]; }; - - Vector<VertexAttribState> m_vertexAttribState; + Vector<VertexAttribValue> m_vertexAttribValue; unsigned m_maxVertexAttribs; RefPtr<WebGLBuffer> m_vertexAttrib0Buffer; long m_vertexAttrib0BufferSize; @@ -462,6 +457,7 @@ public: // Enabled extension objects. RefPtr<OESTextureFloat> m_oesTextureFloat; RefPtr<OESStandardDerivatives> m_oesStandardDerivatives; + RefPtr<OESVertexArrayObject> m_oesVertexArrayObject; RefPtr<WebKitLoseContext> m_webkitLoseContext; // Helpers for getParameter and others diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp new file mode 100644 index 0000000..d14c96c --- /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 0000000..f49a780 --- /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 0000000..8582b36 --- /dev/null +++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl @@ -0,0 +1,29 @@ +/* + * 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 { + }; +} diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.cpp b/Source/WebCore/html/canvas/WebKitLoseContext.cpp index 05e82f4..c594e32 100644 --- a/Source/WebCore/html/canvas/WebKitLoseContext.cpp +++ b/Source/WebCore/html/canvas/WebKitLoseContext.cpp @@ -55,7 +55,8 @@ PassRefPtr<WebKitLoseContext> WebKitLoseContext::create(WebGLRenderingContext* c void WebKitLoseContext::loseContext() { - m_context->forceLostContext(); + if (m_context) + m_context->forceLostContext(); } } // namespace WebCore diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.h b/Source/WebCore/html/canvas/WebKitLoseContext.h index e25e084..b713bef 100644 --- a/Source/WebCore/html/canvas/WebKitLoseContext.h +++ b/Source/WebCore/html/canvas/WebKitLoseContext.h @@ -42,6 +42,7 @@ public: virtual ExtensionName getName() const; void loseContext(); + void contextDestroyed() { m_context = 0; } private: WebKitLoseContext(WebGLRenderingContext*); |