diff options
Diffstat (limited to 'WebCore/html/canvas')
37 files changed, 553 insertions, 49 deletions
diff --git a/WebCore/html/canvas/ArrayBuffer.cpp b/WebCore/html/canvas/ArrayBuffer.cpp index ee8f149..2136f64 100644 --- a/WebCore/html/canvas/ArrayBuffer.cpp +++ b/WebCore/html/canvas/ArrayBuffer.cpp @@ -85,7 +85,10 @@ ArrayBuffer::~ArrayBuffer() void* ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize) { void* result; - // Do not allow 32-bit overflow of the total size + // Do not allow 32-bit overflow of the total size. + // FIXME: Why not? The tryFastCalloc function already checks its arguments, + // and will fail if there is any overflow, so why should we include a + // redudant unnecessarily restrictive check here? if (numElements) { unsigned totalSize = numElements * elementByteSize; if (totalSize / numElements != elementByteSize) diff --git a/WebCore/html/canvas/ArrayBufferView.h b/WebCore/html/canvas/ArrayBufferView.h index ee685b1..701abbc 100644 --- a/WebCore/html/canvas/ArrayBufferView.h +++ b/WebCore/html/canvas/ArrayBufferView.h @@ -46,6 +46,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> { virtual bool isIntArray() const { return false; } virtual bool isUnsignedIntArray() const { return false; } virtual bool isFloatArray() const { return false; } + virtual bool isDataView() const { return false; } PassRefPtr<ArrayBuffer> buffer() const { @@ -62,9 +63,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> { return m_byteOffset; } - virtual unsigned length() const = 0; virtual unsigned byteLength() const = 0; - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const = 0; virtual ~ArrayBufferView(); diff --git a/WebCore/html/canvas/ArrayBufferView.idl b/WebCore/html/canvas/ArrayBufferView.idl index 74a3fe3..be217c1 100644 --- a/WebCore/html/canvas/ArrayBufferView.idl +++ b/WebCore/html/canvas/ArrayBufferView.idl @@ -28,8 +28,5 @@ module html { readonly attribute ArrayBuffer buffer; readonly attribute unsigned long byteOffset; readonly attribute unsigned long byteLength; - readonly attribute unsigned long length; - - [Custom] ArrayBufferView slice(in long start, in long end); }; } diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp index b9f86ce..eb552c6 100644 --- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -813,9 +813,7 @@ void CanvasRenderingContext2D::fill() return; if (!m_path.isEmpty()) { - c->beginPath(); - c->addPath(m_path); - c->fillPath(); + c->fillPath(m_path); didDraw(m_path.boundingRect()); } @@ -833,9 +831,6 @@ void CanvasRenderingContext2D::stroke() return; if (!m_path.isEmpty()) { - c->beginPath(); - c->addPath(m_path); - #if PLATFORM(QT) // Fast approximation of the stroke's bounding rect. // This yields a slightly oversized rect but is very fast @@ -846,7 +841,7 @@ void CanvasRenderingContext2D::stroke() CanvasStrokeStyleApplier strokeApplier(this); FloatRect boundingRect = m_path.strokeBoundingRect(&strokeApplier); #endif - c->strokePath(); + c->strokePath(m_path); didDraw(boundingRect); } diff --git a/WebCore/html/canvas/DataView.cpp b/WebCore/html/canvas/DataView.cpp new file mode 100755 index 0000000..d030211 --- /dev/null +++ b/WebCore/html/canvas/DataView.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) || ENABLE(BLOB) + +#include "DataView.h" + +namespace { + +template<typename T> +union Value { + T data; + char bytes[sizeof(T)]; +}; + +} + +namespace WebCore { + +PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength) +{ + if (byteOffset + byteLength > buffer->byteLength()) + return 0; + return adoptRef(new DataView(buffer, byteOffset, byteLength)); +} + +DataView::DataView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength) + : ArrayBufferView(buffer, byteOffset) + , m_byteLength(byteLength) +{ +} + +static bool needToFlipBytes(bool littleEndian) +{ +#if CPU(BIG_ENDIAN) + return littleEndian; +#else + return !littleEndian; +#endif +} + +inline void swapBytes(char* p, char* q) +{ + char temp = *p; + *p = *q; + *q = temp; +} + +static void flipBytesFor16Bits(char* p) +{ + swapBytes(p, p + 1); +} + +static void flipBytesFor32Bits(char* p) +{ + swapBytes(p, p + 3); + swapBytes(p + 1, p + 2); +} + +static void flipBytesFor64Bits(char* p) +{ + swapBytes(p, p + 7); + swapBytes(p + 1, p + 6); + swapBytes(p + 2, p + 5); + swapBytes(p + 3, p + 4); +} + +static void flipBytesIfNeeded(char* value, size_t size, bool littleEndian) +{ + if (!needToFlipBytes(littleEndian)) + return; + + switch (size) { + case 1: + // Nothing to do. + break; + case 2: + flipBytesFor16Bits(value); + break; + case 4: + flipBytesFor32Bits(value); + break; + case 8: + flipBytesFor64Bits(value); + break; + default: + ASSERT_NOT_REACHED(); + break; + } +} + +template<typename T> +T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) const +{ + if (beyondRange<T>(byteOffset)) { + ec = INDEX_SIZE_ERR; + return 0; + } + + // We do not want to load the data directly since it would cause a bus error on architectures that don't support unaligned loads. + Value<T> value; + memcpy(value.bytes, static_cast<const char*>(m_baseAddress) + byteOffset, sizeof(T)); + flipBytesIfNeeded(value.bytes, sizeof(T), littleEndian); + return value.data; +} + +template<typename T> +void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode& ec) +{ + if (beyondRange<T>(byteOffset)) { + ec = INDEX_SIZE_ERR; + return; + } + + // We do not want to store the data directly since it would cause a bus error on architectures that don't support unaligned stores. + Value<T> tempValue; + tempValue.data = value; + flipBytesIfNeeded(tempValue.bytes, sizeof(T), littleEndian); + memcpy(static_cast<char*>(m_baseAddress) + byteOffset, tempValue.bytes, sizeof(T)); +} + +char DataView::getInt8(unsigned byteOffset, ExceptionCode& ec) +{ + return getData<char>(byteOffset, false, ec); +} + +unsigned char DataView::getUint8(unsigned byteOffset, ExceptionCode& ec) +{ + return getData<unsigned char>(byteOffset, false, ec); +} + +short DataView::getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<short>(byteOffset, littleEndian, ec); +} + +unsigned short DataView::getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<unsigned short>(byteOffset, littleEndian, ec); +} + +int DataView::getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<int>(byteOffset, littleEndian, ec); +} + +unsigned DataView::getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<unsigned>(byteOffset, littleEndian, ec); +} + +float DataView::getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<float>(byteOffset, littleEndian, ec); +} + +double DataView::getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) +{ + return getData<double>(byteOffset, littleEndian, ec); +} + +void DataView::setInt8(unsigned byteOffset, char value, ExceptionCode& ec) +{ + setData<char>(byteOffset, value, false, ec); +} + +void DataView::setUint8(unsigned byteOffset, unsigned char value, ExceptionCode& ec) +{ + setData<unsigned char>(byteOffset, value, false, ec); +} + +void DataView::setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode& ec) +{ + setData<short>(byteOffset, value, littleEndian, ec); +} + +void DataView::setUint16(unsigned byteOffset, unsigned short value, bool littleEndian, ExceptionCode& ec) +{ + setData<unsigned short>(byteOffset, value, littleEndian, ec); +} + +void DataView::setInt32(unsigned byteOffset, int value, bool littleEndian, ExceptionCode& ec) +{ + setData<int>(byteOffset, value, littleEndian, ec); +} + +void DataView::setUint32(unsigned byteOffset, unsigned value, bool littleEndian, ExceptionCode& ec) +{ + setData<unsigned>(byteOffset, value, littleEndian, ec); +} + +void DataView::setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode& ec) +{ + setData<float>(byteOffset, value, littleEndian, ec); +} + +void DataView::setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode& ec) +{ + setData<double>(byteOffset, value, littleEndian, ec); +} + +} + +#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/WebCore/html/canvas/DataView.h b/WebCore/html/canvas/DataView.h new file mode 100755 index 0000000..0681341 --- /dev/null +++ b/WebCore/html/canvas/DataView.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DataView_h +#define DataView_h + +#include "ArrayBufferView.h" +#include "ExceptionCode.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class DataView : public ArrayBufferView { +public: + static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength); + + virtual bool isDataView() const { return true; } + virtual unsigned length() const { return m_byteLength; } + virtual unsigned byteLength() const { return m_byteLength; } + virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; } + + char getInt8(unsigned byteOffset, ExceptionCode&); + unsigned char getUint8(unsigned byteOffset, ExceptionCode&); + short getInt16(unsigned byteOffset, ExceptionCode& ec) { return getInt16(byteOffset, false, ec); } + short getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode&); + unsigned short getUint16(unsigned byteOffset, ExceptionCode& ec) { return getUint16(byteOffset, false, ec); } + unsigned short getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode&); + int getInt32(unsigned byteOffset, ExceptionCode& ec) { return getInt32(byteOffset, false, ec); } + int getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode&); + unsigned getUint32(unsigned byteOffset, ExceptionCode& ec) { return getUint32(byteOffset, false, ec); } + unsigned getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode&); + float getFloat32(unsigned byteOffset, ExceptionCode& ec) { return getFloat32(byteOffset, false, ec); } + float getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode&); + double getFloat64(unsigned byteOffset, ExceptionCode& ec) { return getFloat64(byteOffset, false, ec); } + double getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode&); + + void setInt8(unsigned byteOffset, char value, ExceptionCode&); + void setUint8(unsigned byteOffset, unsigned char value, ExceptionCode&); + void setInt16(unsigned byteOffset, short value, ExceptionCode& ec) { setInt16(byteOffset, value, false, ec); } + void setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode&); + void setUint16(unsigned byteOffset, unsigned short value, ExceptionCode& ec) { setUint16(byteOffset, value, false, ec); } + void setUint16(unsigned byteOffset, unsigned short value, bool littleEndian, ExceptionCode&); + void setInt32(unsigned byteOffset, int value, ExceptionCode& ec) { setInt32(byteOffset, value, false, ec); } + void setInt32(unsigned byteOffset, int value, bool littleEndian, ExceptionCode&); + void setUint32(unsigned byteOffset, unsigned value, ExceptionCode& ec) { setUint32(byteOffset, value, false, ec); } + void setUint32(unsigned byteOffset, unsigned value, bool littleEndian, ExceptionCode&); + void setFloat32(unsigned byteOffset, float value, ExceptionCode& ec) { setFloat32(byteOffset, value, false, ec); } + void setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode&); + void setFloat64(unsigned byteOffset, double value, ExceptionCode& ec) { setFloat64(byteOffset, value, false, ec); } + void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&); + +private: + DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength); + + template<typename T> + inline bool beyondRange(unsigned byteOffset) const { return byteOffset + sizeof(T) > m_byteLength; } + + template<typename T> + T getData(unsigned byteOffset, bool littleEndian, ExceptionCode&) const; + + template<typename T> + void setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode&); + + unsigned m_byteLength; +}; + + +} // namespace WebCore + +#endif // DataView_h diff --git a/WebCore/html/canvas/DataView.idl b/WebCore/html/canvas/DataView.idl new file mode 100755 index 0000000..bef8805 --- /dev/null +++ b/WebCore/html/canvas/DataView.idl @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module html { + + interface [ + Conditional=3D_CANVAS|BLOB, + CanBeConstructed, + CustomConstructFunction, + CustomToJS, + NoStaticTables, + V8CustomConstructor + ] DataView : ArrayBufferView { + // All these methods raise an exception if they would read or write beyond the end of the view. + + // We have to use custom code because our code generator does not support char type. + // char getInt8(in unsigned long byteOffset); + // unsigned char getUint8(in unsigned long byteOffset); + [Custom] DOMObject getInt8() + raises (DOMException); + [Custom] DOMObject getUint8() + raises (DOMException); + + [StrictTypeChecking, RequiresAllArguments=Raise] short getInt16(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] unsigned short getUint16(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] long getInt32(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] unsigned long getUint32(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + + // Use custom code to handle NaN case for JSC. + [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] float getFloat32(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] double getFloat64(in unsigned long byteOffset, in [Optional] boolean littleEndian) + raises (DOMException); + + // We have to use custom code because our code generator does not support char type. + // void setInt8(in unsigned long byteOffset, in byte value); + // void setUint8(in unsigned long byteOffset, in unsigned byte value); + [Custom] void setInt8() + raises (DOMException); + [Custom] void setUint8() + raises (DOMException); + + [StrictTypeChecking, RequiresAllArguments=Raise] void setInt16(in unsigned long byteOffset, in short value, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setUint16(in unsigned long byteOffset, in unsigned short value, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setInt32(in unsigned long byteOffset, in long value, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setUint32(in unsigned long byteOffset, in unsigned long value, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat32(in unsigned long byteOffset, in float value, in [Optional] boolean littleEndian) + raises (DOMException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat64(in unsigned long byteOffset, in double value, in [Optional] boolean littleEndian) + raises (DOMException); + }; + +} diff --git a/WebCore/html/canvas/Float32Array.cpp b/WebCore/html/canvas/Float32Array.cpp index e918d8f..1b26aef 100644 --- a/WebCore/html/canvas/Float32Array.cpp +++ b/WebCore/html/canvas/Float32Array.cpp @@ -52,7 +52,12 @@ Float32Array::Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, { } -PassRefPtr<ArrayBufferView> Float32Array::slice(int start, int end) const +PassRefPtr<Float32Array> Float32Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Float32Array> Float32Array::slice(int start, int end) const { return sliceImpl<Float32Array>(start, end); } diff --git a/WebCore/html/canvas/Float32Array.h b/WebCore/html/canvas/Float32Array.h index ab57087..c03fcc3 100644 --- a/WebCore/html/canvas/Float32Array.h +++ b/WebCore/html/canvas/Float32Array.h @@ -33,7 +33,7 @@ namespace WebCore { class Float32Array : public TypedArrayBase<float> { - public: +public: static PassRefPtr<Float32Array> create(unsigned length); static PassRefPtr<Float32Array> create(const float* array, unsigned length); static PassRefPtr<Float32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -62,7 +62,10 @@ class Float32Array : public TypedArrayBase<float> { return result; } - private: + PassRefPtr<Float32Array> slice(int start) const; + PassRefPtr<Float32Array> slice(int start, int end) const; + +private: Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -71,7 +74,6 @@ class Float32Array : public TypedArrayBase<float> { // Overridden from ArrayBufferView. virtual bool isFloatArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Float32Array.idl b/WebCore/html/canvas/Float32Array.idl index c3c0a2d..b979d29 100644 --- a/WebCore/html/canvas/Float32Array.idl +++ b/WebCore/html/canvas/Float32Array.idl @@ -39,6 +39,9 @@ module html { ] Float32Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 4; + readonly attribute unsigned long length; + Float32Array slice(in long start, in [Optional] long end); + // void set(in Float32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/Int16Array.cpp b/WebCore/html/canvas/Int16Array.cpp index 635ea5e..a3d04bc 100644 --- a/WebCore/html/canvas/Int16Array.cpp +++ b/WebCore/html/canvas/Int16Array.cpp @@ -51,7 +51,12 @@ Int16Array::Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<ArrayBufferView> Int16Array::slice(int start, int end) const +PassRefPtr<Int16Array> Int16Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Int16Array> Int16Array::slice(int start, int end) const { return sliceImpl<Int16Array>(start, end); } diff --git a/WebCore/html/canvas/Int16Array.h b/WebCore/html/canvas/Int16Array.h index 00877ef..a6286c6 100644 --- a/WebCore/html/canvas/Int16Array.h +++ b/WebCore/html/canvas/Int16Array.h @@ -33,7 +33,7 @@ namespace WebCore { class ArrayBuffer; class Int16Array : public IntegralTypedArrayBase<short> { - public: +public: static PassRefPtr<Int16Array> create(unsigned length); static PassRefPtr<Int16Array> create(short* array, unsigned length); static PassRefPtr<Int16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -41,7 +41,10 @@ class Int16Array : public IntegralTypedArrayBase<short> { using TypedArrayBase<short>::set; using IntegralTypedArrayBase<short>::set; - private: + PassRefPtr<Int16Array> slice(int start) const; + PassRefPtr<Int16Array> slice(int start, int end) const; + +private: Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -50,7 +53,6 @@ class Int16Array : public IntegralTypedArrayBase<short> { // Overridden from ArrayBufferView. virtual bool isShortArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Int16Array.idl b/WebCore/html/canvas/Int16Array.idl index 7980a69..f1f5c8b 100644 --- a/WebCore/html/canvas/Int16Array.idl +++ b/WebCore/html/canvas/Int16Array.idl @@ -38,6 +38,9 @@ module html { ] Int16Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 2; + readonly attribute unsigned long length; + Int16Array slice(in long start, in [Optional] long end); + // void set(in Int16Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/Int32Array.cpp b/WebCore/html/canvas/Int32Array.cpp index cc926a3..266c941 100644 --- a/WebCore/html/canvas/Int32Array.cpp +++ b/WebCore/html/canvas/Int32Array.cpp @@ -52,7 +52,12 @@ Int32Array::Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<ArrayBufferView> Int32Array::slice(int start, int end) const +PassRefPtr<Int32Array> Int32Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Int32Array> Int32Array::slice(int start, int end) const { return sliceImpl<Int32Array>(start, end); } diff --git a/WebCore/html/canvas/Int32Array.h b/WebCore/html/canvas/Int32Array.h index bd05450..068a677 100644 --- a/WebCore/html/canvas/Int32Array.h +++ b/WebCore/html/canvas/Int32Array.h @@ -32,7 +32,7 @@ namespace WebCore { class Int32Array : public IntegralTypedArrayBase<int> { - public: +public: static PassRefPtr<Int32Array> create(unsigned length); static PassRefPtr<Int32Array> create(int* array, unsigned length); static PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -42,7 +42,10 @@ class Int32Array : public IntegralTypedArrayBase<int> { using IntegralTypedArrayBase<int>::set; #endif - private: + PassRefPtr<Int32Array> slice(int start) const; + PassRefPtr<Int32Array> slice(int start, int end) const; + +private: Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -51,7 +54,6 @@ class Int32Array : public IntegralTypedArrayBase<int> { // Overridden from ArrayBufferView. virtual bool isIntArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Int32Array.idl b/WebCore/html/canvas/Int32Array.idl index bd1554d..f96b53c 100644 --- a/WebCore/html/canvas/Int32Array.idl +++ b/WebCore/html/canvas/Int32Array.idl @@ -39,6 +39,9 @@ module html { ] Int32Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 4; + readonly attribute unsigned long length; + Int32Array slice(in long start, in [Optional] long end); + // void set(in Int32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/Int8Array.cpp b/WebCore/html/canvas/Int8Array.cpp index c2dd2fa..89ed316 100644 --- a/WebCore/html/canvas/Int8Array.cpp +++ b/WebCore/html/canvas/Int8Array.cpp @@ -52,7 +52,12 @@ Int8Array::Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsign { } -PassRefPtr<ArrayBufferView> Int8Array::slice(int start, int end) const +PassRefPtr<Int8Array> Int8Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Int8Array> Int8Array::slice(int start, int end) const { return sliceImpl<Int8Array>(start, end); } diff --git a/WebCore/html/canvas/Int8Array.h b/WebCore/html/canvas/Int8Array.h index d267f7f..a5df302 100644 --- a/WebCore/html/canvas/Int8Array.h +++ b/WebCore/html/canvas/Int8Array.h @@ -34,7 +34,7 @@ namespace WebCore { class ArrayBuffer; class Int8Array : public IntegralTypedArrayBase<signed char> { - public: +public: static PassRefPtr<Int8Array> create(unsigned length); static PassRefPtr<Int8Array> create(signed char* array, unsigned length); static PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -42,7 +42,10 @@ class Int8Array : public IntegralTypedArrayBase<signed char> { using TypedArrayBase<signed char>::set; using IntegralTypedArrayBase<signed char>::set; - private: + PassRefPtr<Int8Array> slice(int start) const; + PassRefPtr<Int8Array> slice(int start, int end) const; + +private: Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -51,7 +54,6 @@ class Int8Array : public IntegralTypedArrayBase<signed char> { // Overridden from ArrayBufferView. virtual bool isByteArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Int8Array.idl b/WebCore/html/canvas/Int8Array.idl index ec0bdb7..08a608b 100644 --- a/WebCore/html/canvas/Int8Array.idl +++ b/WebCore/html/canvas/Int8Array.idl @@ -39,6 +39,9 @@ module html { ] Int8Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 1; + readonly attribute unsigned long length; + Int8Array slice(in long start, in [Optional] long end); + // void set(in Int8Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/TypedArrayBase.h b/WebCore/html/canvas/TypedArrayBase.h index 77283df..2bef6f0 100644 --- a/WebCore/html/canvas/TypedArrayBase.h +++ b/WebCore/html/canvas/TypedArrayBase.h @@ -55,12 +55,12 @@ class TypedArrayBase : public ArrayBufferView { // Overridden from ArrayBufferView. This must be public because of // rules about inheritance of members in template classes, and // because it is accessed via pointers to subclasses. - virtual unsigned length() const + unsigned length() const { return m_length; } - protected: + protected: TypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length) : ArrayBufferView(buffer, byteOffset) , m_length(length) diff --git a/WebCore/html/canvas/Uint16Array.cpp b/WebCore/html/canvas/Uint16Array.cpp index a0f891c..5312888 100644 --- a/WebCore/html/canvas/Uint16Array.cpp +++ b/WebCore/html/canvas/Uint16Array.cpp @@ -52,7 +52,12 @@ Uint16Array::Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un { } -PassRefPtr<ArrayBufferView> Uint16Array::slice(int start, int end) const +PassRefPtr<Uint16Array> Uint16Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Uint16Array> Uint16Array::slice(int start, int end) const { return sliceImpl<Uint16Array>(start, end); } diff --git a/WebCore/html/canvas/Uint16Array.h b/WebCore/html/canvas/Uint16Array.h index fee31f6..f63b67d 100644 --- a/WebCore/html/canvas/Uint16Array.h +++ b/WebCore/html/canvas/Uint16Array.h @@ -34,7 +34,7 @@ namespace WebCore { class ArrayBuffer; class Uint16Array : public IntegralTypedArrayBase<unsigned short> { - public: +public: static PassRefPtr<Uint16Array> create(unsigned length); static PassRefPtr<Uint16Array> create(unsigned short* array, unsigned length); static PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -42,7 +42,10 @@ class Uint16Array : public IntegralTypedArrayBase<unsigned short> { using TypedArrayBase<unsigned short>::set; using IntegralTypedArrayBase<unsigned short>::set; - private: + PassRefPtr<Uint16Array> slice(int start) const; + PassRefPtr<Uint16Array> slice(int start, int end) const; + +private: Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -51,7 +54,6 @@ class Uint16Array : public IntegralTypedArrayBase<unsigned short> { // Overridden from ArrayBufferView. virtual bool isUnsignedShortArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Uint16Array.idl b/WebCore/html/canvas/Uint16Array.idl index 75a7499..8e778b4 100644 --- a/WebCore/html/canvas/Uint16Array.idl +++ b/WebCore/html/canvas/Uint16Array.idl @@ -39,6 +39,9 @@ module html { ] Uint16Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 2; + readonly attribute unsigned long length; + Uint16Array slice(in long start, in [Optional] long end); + // void set(in Uint16Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/Uint32Array.cpp b/WebCore/html/canvas/Uint32Array.cpp index f49a83a..f5bd959 100644 --- a/WebCore/html/canvas/Uint32Array.cpp +++ b/WebCore/html/canvas/Uint32Array.cpp @@ -52,7 +52,12 @@ Uint32Array::Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un { } -PassRefPtr<ArrayBufferView> Uint32Array::slice(int start, int end) const +PassRefPtr<Uint32Array> Uint32Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Uint32Array> Uint32Array::slice(int start, int end) const { return sliceImpl<Uint32Array>(start, end); } diff --git a/WebCore/html/canvas/Uint32Array.h b/WebCore/html/canvas/Uint32Array.h index db23088..9c0f137 100644 --- a/WebCore/html/canvas/Uint32Array.h +++ b/WebCore/html/canvas/Uint32Array.h @@ -34,7 +34,7 @@ namespace WebCore { class ArrayBuffer; class Uint32Array : public IntegralTypedArrayBase<unsigned int> { - public: +public: static PassRefPtr<Uint32Array> create(unsigned length); static PassRefPtr<Uint32Array> create(unsigned int* array, unsigned length); static PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -42,7 +42,10 @@ class Uint32Array : public IntegralTypedArrayBase<unsigned int> { using TypedArrayBase<unsigned int>::set; using IntegralTypedArrayBase<unsigned int>::set; - private: + PassRefPtr<Uint32Array> slice(int start) const; + PassRefPtr<Uint32Array> slice(int start, int end) const; + +private: Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -51,7 +54,6 @@ class Uint32Array : public IntegralTypedArrayBase<unsigned int> { // Overridden from ArrayBufferView. virtual bool isUnsignedIntArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Uint32Array.idl b/WebCore/html/canvas/Uint32Array.idl index 06e17c6..9fbf30c 100644 --- a/WebCore/html/canvas/Uint32Array.idl +++ b/WebCore/html/canvas/Uint32Array.idl @@ -39,6 +39,9 @@ module html { ] Uint32Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 4; + readonly attribute unsigned long length; + Uint32Array slice(in long start, in [Optional] long end); + // void set(in Uint32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/Uint8Array.cpp b/WebCore/html/canvas/Uint8Array.cpp index 6c785f9..99b8a09 100644 --- a/WebCore/html/canvas/Uint8Array.cpp +++ b/WebCore/html/canvas/Uint8Array.cpp @@ -52,7 +52,12 @@ Uint8Array::Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<ArrayBufferView> Uint8Array::slice(int start, int end) const +PassRefPtr<Uint8Array> Uint8Array::slice(int start) const +{ + return slice(start, length()); +} + +PassRefPtr<Uint8Array> Uint8Array::slice(int start, int end) const { return sliceImpl<Uint8Array>(start, end); } diff --git a/WebCore/html/canvas/Uint8Array.h b/WebCore/html/canvas/Uint8Array.h index fce63da..66154b5 100644 --- a/WebCore/html/canvas/Uint8Array.h +++ b/WebCore/html/canvas/Uint8Array.h @@ -34,7 +34,7 @@ namespace WebCore { class ArrayBuffer; class Uint8Array : public IntegralTypedArrayBase<unsigned char> { - public: +public: static PassRefPtr<Uint8Array> create(unsigned length); static PassRefPtr<Uint8Array> create(unsigned char* array, unsigned length); static PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -44,7 +44,10 @@ class Uint8Array : public IntegralTypedArrayBase<unsigned char> { using IntegralTypedArrayBase<unsigned char>::set; #endif - private: + PassRefPtr<Uint8Array> slice(int start) const; + PassRefPtr<Uint8Array> slice(int start, int end) const; + +private: Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); @@ -53,7 +56,6 @@ class Uint8Array : public IntegralTypedArrayBase<unsigned char> { // Overridden from ArrayBufferView. virtual bool isUnsignedByteArray() const { return true; } - virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const; }; } // namespace WebCore diff --git a/WebCore/html/canvas/Uint8Array.idl b/WebCore/html/canvas/Uint8Array.idl index bd28023..7fe7e21 100644 --- a/WebCore/html/canvas/Uint8Array.idl +++ b/WebCore/html/canvas/Uint8Array.idl @@ -39,6 +39,9 @@ module html { ] Uint8Array : ArrayBufferView { const unsigned int BYTES_PER_ELEMENT = 1; + readonly attribute unsigned long length; + Uint8Array slice(in long start, in [Optional] long end); + // void set(in Uint8Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp index 99d9cad..36ef048 100644 --- a/WebCore/html/canvas/WebGLBuffer.cpp +++ b/WebCore/html/canvas/WebGLBuffer.cpp @@ -170,8 +170,7 @@ unsigned WebGLBuffer::byteLength() const long WebGLBuffer::getCachedMaxIndex(unsigned long type) { - size_t numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry); - for (size_t i = 0; i < numEntries; i++) + for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_maxIndexCache); ++i) if (m_maxIndexCache[i].type == type) return m_maxIndexCache[i].maxIndex; return -1; @@ -179,8 +178,8 @@ long WebGLBuffer::getCachedMaxIndex(unsigned long type) void WebGLBuffer::setCachedMaxIndex(unsigned long type, long value) { - int numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry); - for (int i = 0; i < numEntries; i++) + size_t numEntries = WTF_ARRAY_LENGTH(m_maxIndexCache); + for (size_t i = 0; i < numEntries; ++i) if (m_maxIndexCache[i].type == type) { m_maxIndexCache[i].maxIndex = value; return; diff --git a/WebCore/html/canvas/WebGLBuffer.h b/WebCore/html/canvas/WebGLBuffer.h index f18a9bf..af819a3 100644 --- a/WebCore/html/canvas/WebGLBuffer.h +++ b/WebCore/html/canvas/WebGLBuffer.h @@ -59,6 +59,8 @@ public: unsigned long getTarget() const { return m_target; } void setTarget(unsigned long); + bool hasEverBeenBound() const { return object() && m_target; } + protected: WebGLBuffer(WebGLRenderingContext*); diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp index 5bf3779..9e2db56 100644 --- a/WebCore/html/canvas/WebGLFramebuffer.cpp +++ b/WebCore/html/canvas/WebGLFramebuffer.cpp @@ -75,6 +75,7 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx) : WebGLObject(ctx) + , m_hasEverBeenBound(false) { setObject(context()->graphicsContext3D()->createFramebuffer()); } diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h index 394b770..b86417d 100644 --- a/WebCore/html/canvas/WebGLFramebuffer.h +++ b/WebCore/html/canvas/WebGLFramebuffer.h @@ -56,6 +56,10 @@ public: // Return false does not mean COMPLETE, might still be INCOMPLETE. bool isIncomplete(bool checkInternalFormat) const; + bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; } + + void setHasEverBeenBound() { m_hasEverBeenBound = true; } + protected: WebGLFramebuffer(WebGLRenderingContext*); @@ -76,6 +80,8 @@ private: RefPtr<WebGLObject> m_depthAttachment; RefPtr<WebGLObject> m_stencilAttachment; RefPtr<WebGLObject> m_depthStencilAttachment; + + bool m_hasEverBeenBound; }; } // namespace WebCore diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp index b9efd47..0c3ac84 100644 --- a/WebCore/html/canvas/WebGLRenderbuffer.cpp +++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp @@ -45,6 +45,7 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx) , m_width(0) , m_height(0) , m_isValid(true) + , m_hasEverBeenBound(false) { setObject(context()->graphicsContext3D()->createRenderbuffer()); } diff --git a/WebCore/html/canvas/WebGLRenderbuffer.h b/WebCore/html/canvas/WebGLRenderbuffer.h index 9a23ca5..a432f9d 100644 --- a/WebCore/html/canvas/WebGLRenderbuffer.h +++ b/WebCore/html/canvas/WebGLRenderbuffer.h @@ -60,6 +60,10 @@ public: bool isInitialized() const { return m_initialized; } void setInitialized() { m_initialized = true; } + bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; } + + void setHasEverBeenBound() { m_hasEverBeenBound = true; } + protected: WebGLRenderbuffer(WebGLRenderingContext*); @@ -72,6 +76,8 @@ private: bool m_initialized; unsigned long m_width, m_height; bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported. + + bool m_hasEverBeenBound; }; } // namespace WebCore diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp index 0cbbc8e..b201692 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -310,6 +310,8 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff } m_framebufferBinding = buffer; m_context->bindFramebuffer(target, objectOrZero(buffer)); + if (buffer) + buffer->setHasEverBeenBound(); cleanupAfterGraphicsCall(false); } @@ -328,6 +330,8 @@ void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbu } m_renderbufferBinding = renderBuffer; m_context->bindRenderbuffer(target, objectOrZero(renderBuffer)); + if (renderBuffer) + renderBuffer->setHasEverBeenBound(); cleanupAfterGraphicsCall(false); } @@ -2080,6 +2084,9 @@ bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer) if (!buffer || isContextLost()) return false; + if (!buffer->hasEverBeenBound()) + return false; + return m_context->isBuffer(buffer->object()); } @@ -2100,6 +2107,9 @@ bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer) if (!framebuffer || isContextLost()) return false; + if (!framebuffer->hasEverBeenBound()) + return false; + return m_context->isFramebuffer(framebuffer->object()); } @@ -2116,6 +2126,9 @@ bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer) if (!renderbuffer || isContextLost()) return false; + if (!renderbuffer->hasEverBeenBound()) + return false; + return m_context->isRenderbuffer(renderbuffer->object()); } @@ -2132,6 +2145,9 @@ bool WebGLRenderingContext::isTexture(WebGLTexture* texture) if (!texture || isContextLost()) return false; + if (!texture->hasEverBeenBound()) + return false; + return m_context->isTexture(texture->object()); } @@ -2233,10 +2249,14 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height, m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } - if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) { + if (format != GraphicsContext3D::RGBA && type != GraphicsContext3D::UNSIGNED_BYTE) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + return; + } // Validate array type against pixel type. if ((type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray()) || (type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray())) { @@ -2258,7 +2278,7 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height, // The last row needs no padding. unsigned long totalBytes = bytesPerRow * height - padding; unsigned long num = totalBytes / bytesPerComponent; - if (pixels->length() < num) { + if (pixels->byteLength() / bytesPerComponent < num) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } diff --git a/WebCore/html/canvas/WebGLTexture.h b/WebCore/html/canvas/WebGLTexture.h index 6ee3dcc..493ef7e 100644 --- a/WebCore/html/canvas/WebGLTexture.h +++ b/WebCore/html/canvas/WebGLTexture.h @@ -61,6 +61,8 @@ public: // Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2). bool needToUseBlackTexture() const; + bool hasEverBeenBound() const { return object() && m_target; } + static int computeLevelCount(int width, int height); protected: |