--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -749,40 +749,39 @@ public:
// -----------------------------------------------------------------------------
// Buffer Objects (WebGLContextBuffers.cpp)
void BindBuffer(GLenum target, WebGLBuffer* buffer);
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buf);
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
WebGLintptr offset, WebGLsizeiptr size);
private:
- template<typename BufferT>
- void BufferDataT(GLenum target, const BufferT& data, GLenum usage);
+ void BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data, GLenum usage);
public:
void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
- void BufferData(GLenum target, const dom::ArrayBufferView& data,
- GLenum usage);
+ void BufferData(GLenum target, const dom::ArrayBufferView& srcData, GLenum usage,
+ GLuint srcElemOffset = 0, GLuint srcElemCountOverride = 0);
void BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeData,
GLenum usage);
- void BufferData(GLenum target, const dom::SharedArrayBuffer& data,
- GLenum usage);
+ void BufferData(GLenum target, const dom::SharedArrayBuffer& data, GLenum usage);
private:
- template<typename BufferT>
- void BufferSubDataT(GLenum target, WebGLsizeiptr byteOffset,
- const BufferT& data);
+ void BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
+ size_t srcDataLen, const uint8_t* srcData);
public:
- void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::ArrayBufferView& data);
- void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::Nullable<dom::ArrayBuffer>& maybeData);
- void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::SharedArrayBuffer& data);
+ void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::ArrayBufferView& src, GLuint srcElemOffset = 0,
+ GLuint srcElemCountOverride = 0);
+ void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::Nullable<dom::ArrayBuffer>& maybeSrc);
+ void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::SharedArrayBuffer& src);
+
already_AddRefed<WebGLBuffer> CreateBuffer();
void DeleteBuffer(WebGLBuffer* buf);
bool IsBuffer(WebGLBuffer* buf);
protected:
// bound buffer state
WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
WebGLRefPtr<WebGLBuffer> mBoundCopyReadBuffer;
--- a/dom/canvas/WebGLContextBuffers.cpp
+++ b/dom/canvas/WebGLContextBuffers.cpp
@@ -299,182 +299,182 @@ WebGLContext::BindBufferRange(GLenum tar
if (buffer) {
buffer->SetContentAfterBind(target);
}
}
////////////////////////////////////////
void
+WebGLContext::BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data,
+ GLenum usage)
+{
+ const char funcName[] = "bufferData";
+
+ const auto& buffer = ValidateBufferSelection(funcName, target);
+ if (!buffer)
+ return;
+
+ buffer->BufferData(target, dataLen, data, usage);
+}
+
+////
+
+void
WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
{
const char funcName[] = "bufferData";
if (IsContextLost())
return;
if (!ValidateNonNegative(funcName, "size", size))
return;
- // careful: WebGLsizeiptr is always 64-bit, but GLsizeiptr is like intptr_t.
- if (!CheckedInt<GLsizeiptr>(size).isValid())
- return ErrorOutOfMemory("%s: bad size", funcName);
-
- const auto& buffer = ValidateBufferSelection(funcName, target);
- if (!buffer)
- return;
-
////
- UniquePtr<uint8_t> zeroBuffer((uint8_t*)calloc(size, 1));
+ const UniqueBuffer zeroBuffer(calloc(size, 1));
if (!zeroBuffer)
return ErrorOutOfMemory("%s: Failed to allocate zeros.", funcName);
- buffer->BufferData(target, size_t(size), zeroBuffer.get(), usage);
+ BufferDataImpl(target, size_t(size), zeroBuffer.get(), usage);
+}
+
+void
+WebGLContext::BufferData(GLenum target, const dom::SharedArrayBuffer& src, GLenum usage)
+{
+ if (IsContextLost())
+ return;
+
+ src.ComputeLengthAndData();
+ BufferDataImpl(target, src.LengthAllowShared(), src.DataAllowShared(), usage);
}
-// BufferT may be one of
-// const dom::ArrayBuffer&
-// const dom::SharedArrayBuffer&
-// const dom::ArrayBufferView&
-template<typename BufferT>
void
-WebGLContext::BufferDataT(GLenum target,
- const BufferT& data,
- GLenum usage)
+WebGLContext::BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
+ GLenum usage)
+{
+ if (IsContextLost())
+ return;
+
+ if (maybeSrc.IsNull())
+ return ErrorInvalidValue("bufferData: null object passed");
+ auto& src = maybeSrc.Value();
+
+ src.ComputeLengthAndData();
+ BufferDataImpl(target, src.LengthAllowShared(), src.DataAllowShared(), usage);
+}
+
+void
+WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& src, GLenum usage,
+ GLuint srcElemOffset, GLuint srcElemCountOverride)
{
const char funcName[] = "bufferData";
if (IsContextLost())
return;
- data.ComputeLengthAndData();
-
- // Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
- // is like intptr_t.
- if (!CheckedInt<GLsizeiptr>(data.LengthAllowShared()).isValid())
- return ErrorOutOfMemory("bufferData: bad size");
-
- const auto& buffer = ValidateBufferSelection(funcName, target);
- if (!buffer)
+ uint8_t* bytes;
+ size_t byteLen;
+ if (!ValidateArrayBufferView(funcName, src, srcElemOffset, srcElemCountOverride,
+ &bytes, &byteLen))
+ {
return;
-
- // Warning: Possibly shared memory. See bug 1225033.
- buffer->BufferData(target, data.LengthAllowShared(), data.DataAllowShared(), usage);
-}
+ }
-void
-WebGLContext::BufferData(GLenum target,
- const dom::SharedArrayBuffer& data,
- GLenum usage)
-{
- BufferDataT(target, data, usage);
-}
-
-void
-WebGLContext::BufferData(GLenum target,
- const dom::Nullable<dom::ArrayBuffer>& maybeData,
- GLenum usage)
-{
- if (maybeData.IsNull()) {
- // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
- return ErrorInvalidValue("bufferData: null object passed");
- }
- BufferDataT(target, maybeData.Value(), usage);
-}
-
-void
-WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
- GLenum usage)
-{
- BufferDataT(target, data, usage);
+ BufferDataImpl(target, byteLen, bytes, usage);
}
////////////////////////////////////////
-// BufferT may be one of
-// const dom::ArrayBuffer&
-// const dom::SharedArrayBuffer&
-// const dom::ArrayBufferView&
-template<typename BufferT>
void
-WebGLContext::BufferSubDataT(GLenum target,
- WebGLsizeiptr byteOffset,
- const BufferT& data)
+WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
+ size_t dataLen, const uint8_t* data)
{
const char funcName[] = "bufferSubData";
- if (IsContextLost())
- return;
- if (!ValidateNonNegative(funcName, "byteOffset", byteOffset))
+ if (!ValidateNonNegative(funcName, "byteOffset", dstByteOffset))
return;
const auto& buffer = ValidateBufferSelection(funcName, target);
if (!buffer)
return;
if (buffer->mNumActiveTFOs) {
ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback"
" object.",
"bufferSubData");
return;
}
- data.ComputeLengthAndData();
+ if (!buffer->ValidateRange(funcName, dstByteOffset, dataLen))
+ return;
- const auto checked_neededByteLength =
- CheckedInt<size_t>(byteOffset) + data.LengthAllowShared();
-
- if (!checked_neededByteLength.isValid()) {
- ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
- " byte length.");
+ if (!CheckedInt<GLintptr>(dataLen).isValid()) {
+ ErrorOutOfMemory("%s: Size too large.", funcName);
return;
}
+ const GLintptr glDataLen(dataLen);
- if (checked_neededByteLength.value() > buffer->ByteLength()) {
- ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
- " %d bytes, but buffer only has %d bytes.",
- checked_neededByteLength.value(),
- buffer->ByteLength());
- return;
- }
+ ////
MakeContextCurrent();
const ScopedLazyBind lazyBind(gl, target, buffer);
// Warning: Possibly shared memory. See bug 1225033.
- gl->fBufferSubData(target, byteOffset, data.LengthAllowShared(),
- data.DataAllowShared());
+ gl->fBufferSubData(target, dstByteOffset, glDataLen, data);
// Warning: Possibly shared memory. See bug 1225033.
- buffer->ElementArrayCacheBufferSubData(byteOffset, data.DataAllowShared(),
- data.LengthAllowShared());
+ buffer->ElementArrayCacheBufferSubData(dstByteOffset, data, size_t(glDataLen));
+}
+
+void
+WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::Nullable<dom::ArrayBuffer>& maybeSrc)
+{
+ if (IsContextLost())
+ return;
+
+ if (maybeSrc.IsNull())
+ return ErrorInvalidValue("BufferSubData: returnedData is null.");
+ auto& src = maybeSrc.Value();
+
+ src.ComputeLengthAndData();
+ BufferSubDataImpl(target, dstByteOffset, src.LengthAllowShared(),
+ src.DataAllowShared());
}
void
-WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::Nullable<dom::ArrayBuffer>& maybeData)
+WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::SharedArrayBuffer& src)
{
- if (maybeData.IsNull()) {
- ErrorInvalidValue("BufferSubData: returnedData is null.");
+ if (IsContextLost())
return;
- }
- BufferSubDataT(target, byteOffset, maybeData.Value());
+
+ src.ComputeLengthAndData();
+ BufferSubDataImpl(target, dstByteOffset, src.LengthAllowShared(),
+ src.DataAllowShared());
}
void
-WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::SharedArrayBuffer& data)
+WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
+ const dom::ArrayBufferView& src, GLuint srcElemOffset,
+ GLuint srcElemCountOverride)
{
- BufferSubDataT(target, byteOffset, data);
-}
+ const char funcName[] = "bufferSubData";
+ if (IsContextLost())
+ return;
-void
-WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
- const dom::ArrayBufferView& data)
-{
- BufferSubDataT(target, byteOffset, data);
+ uint8_t* bytes;
+ size_t byteLen;
+ if (!ValidateArrayBufferView(funcName, src, srcElemOffset, srcElemCountOverride,
+ &bytes, &byteLen))
+ {
+ return;
+ }
+
+ BufferSubDataImpl(target, dstByteOffset, byteLen, bytes);
}
////////////////////////////////////////
already_AddRefed<WebGLBuffer>
WebGLContext::CreateBuffer()
{
if (IsContextLost())