зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1147441 - Add SharedArrayBuffer support to WebGL and WebGL 2. r=jgilbert, r=bzbarsky
--HG-- extra : histedit_source : 141390e44859f0cdb1692979f08f873ad3480754
This commit is contained in:
Родитель
b564e1db32
Коммит
ba964b1f9c
|
@ -24,6 +24,7 @@ class WebGLVertexArrayObject;
|
|||
namespace dom {
|
||||
class OwningUnsignedLongOrUint32ArrayOrBoolean;
|
||||
class OwningWebGLBufferOrLongLong;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
} // namespace dom
|
||||
|
||||
class WebGL2Context
|
||||
|
@ -51,8 +52,16 @@ public:
|
|||
|
||||
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
|
||||
GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
|
||||
|
||||
private:
|
||||
template<typename BufferT>
|
||||
void GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data);
|
||||
|
||||
public:
|
||||
void GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData);
|
||||
void GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::SharedArrayBuffer& data);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -88,12 +97,12 @@ public:
|
|||
void TexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum format, GLenum type, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
|
@ -109,10 +118,10 @@ public:
|
|||
GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferView& data);
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& data);
|
||||
void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLsizei imageSize, const dom::ArrayBufferView& data);
|
||||
GLenum format, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& data);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
@ -138,9 +138,12 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
|
|||
}
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
WebGL2Context::GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -159,11 +162,6 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
if (offset < 0)
|
||||
return ErrorInvalidValue("getBufferSubData: negative offset");
|
||||
|
||||
// If returnedData is null then an INVALID_VALUE error is
|
||||
// generated.
|
||||
if (maybeData.IsNull())
|
||||
return ErrorInvalidValue("getBufferSubData: returnedData is null");
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
|
@ -171,7 +169,6 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
|
||||
// If offset + returnedData.byteLength would extend beyond the end
|
||||
// of the buffer an INVALID_VALUE error is generated.
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + data.Length();
|
||||
|
@ -225,4 +222,22 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
}
|
||||
}
|
||||
|
||||
void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
{
|
||||
// If returnedData is null then an INVALID_VALUE error is
|
||||
// generated.
|
||||
if (maybeData.IsNull())
|
||||
return ErrorInvalidValue("getBufferSubData: returnedData is null");
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
GetBufferSubDataT(target, offset, data);
|
||||
}
|
||||
|
||||
void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::SharedArrayBuffer& data)
|
||||
{
|
||||
GetBufferSubDataT(target, offset, data);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -39,7 +39,7 @@ void
|
|||
WebGL2Context::TexImage3D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
const char funcName[] = "texImage3D";
|
||||
|
@ -59,7 +59,7 @@ WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
const char funcName[] = "texSubImage3D";
|
||||
|
@ -95,7 +95,7 @@ WebGL2Context::CopyTexSubImage3D(GLenum target, GLint level,
|
|||
void
|
||||
WebGL2Context::CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferView& view)
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
GenerateWarning("compressedTexImage3D: Not implemented.");
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ WebGL2Context::CompressedTexImage3D(GLenum target, GLint level, GLenum internalF
|
|||
void
|
||||
WebGL2Context::CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLsizei imageSize, const dom::ArrayBufferView& view)
|
||||
GLenum unpackFormat, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
GenerateWarning("compressedTexSubImage3D: Not implemented.");
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
|
@ -100,6 +100,7 @@ class Element;
|
|||
class ImageData;
|
||||
class OwningHTMLCanvasElementOrOffscreenCanvas;
|
||||
struct WebGLContextAttributes;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
template<typename> struct Nullable;
|
||||
} // namespace dom
|
||||
|
||||
|
@ -528,7 +529,7 @@ public:
|
|||
void PolygonOffset(GLfloat factor, GLfloat units);
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void RenderbufferStorage(GLenum target, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
@ -749,8 +750,8 @@ public:
|
|||
WebGLintptr offset, WebGLsizeiptr size);
|
||||
|
||||
private:
|
||||
void BufferDataUnchecked(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
|
||||
void BufferData(GLenum target, WebGLsizeiptr size, void* data, GLenum usage);
|
||||
template<typename BufferT>
|
||||
void BufferDataT(GLenum target, const BufferT& data, GLenum usage);
|
||||
|
||||
public:
|
||||
void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
|
||||
|
@ -758,16 +759,25 @@ public:
|
|||
GLenum usage);
|
||||
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::SharedArrayBufferView& data,
|
||||
GLenum usage);
|
||||
|
||||
private:
|
||||
void BufferSubDataUnchecked(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
|
||||
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
|
||||
template<typename BufferT>
|
||||
void BufferSubDataT(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const BufferT& data);
|
||||
|
||||
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 byteOffset,
|
||||
const dom::SharedArrayBufferView& data);
|
||||
already_AddRefed<WebGLBuffer> CreateBuffer();
|
||||
void DeleteBuffer(WebGLBuffer* buf);
|
||||
bool IsBuffer(WebGLBuffer* buf);
|
||||
|
@ -864,10 +874,10 @@ protected:
|
|||
public:
|
||||
void CompressedTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
void CompressedTexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, const dom::ArrayBufferView& view);
|
||||
GLenum unpackFormat, const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CopyTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
|
@ -878,7 +888,7 @@ public:
|
|||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv);
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -891,7 +901,7 @@ public:
|
|||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv);
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -1634,6 +1644,11 @@ ValidateTexImageTarget(WebGLContext* webgl, GLenum rawTexImageTarget,
|
|||
// Returns x rounded to the next highest multiple of y.
|
||||
CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y);
|
||||
|
||||
void
|
||||
ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
|
||||
void** const out_data, size_t* const out_length,
|
||||
js::Scalar::Type* const out_type);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,25 +182,25 @@ WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
|
|||
}
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
// const dom::ArrayBufferView&
|
||||
// const dom::SharedArrayBufferView&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData,
|
||||
GLenum usage)
|
||||
WebGLContext::BufferDataT(GLenum target,
|
||||
const BufferT& data,
|
||||
GLenum usage)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (maybeData.IsNull()) {
|
||||
// see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
|
||||
return ErrorInvalidValue("bufferData: null object passed");
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
return;
|
||||
|
||||
const WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
|
||||
|
@ -231,20 +231,61 @@ WebGLContext::BufferData(GLenum target,
|
|||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target, const dom::SharedArrayBufferView& data,
|
||||
GLenum usage)
|
||||
{
|
||||
BufferDataT(target, data, usage);
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
// const dom::ArrayBufferView&
|
||||
// const dom::SharedArrayBufferView&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGLContext::BufferSubDataT(GLenum target,
|
||||
WebGLsizeiptr byteOffset,
|
||||
const BufferT& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||
return;
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
|
@ -252,119 +293,60 @@ WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
|
|||
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
|
||||
// is like intptr_t.
|
||||
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
|
||||
return ErrorOutOfMemory("bufferData: bad size");
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
InvalidateBufferFetching();
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
|
||||
if (error) {
|
||||
GenerateWarning("bufferData generated error %s", ErrorName(error));
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(data.Length());
|
||||
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length()))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (maybeData.IsNull()) {
|
||||
// see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
|
||||
return;
|
||||
}
|
||||
BufferSubDataT(target, byteOffset, maybeData.Value());
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("bufferData: no buffer bound!");
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBuffer& data)
|
||||
{
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::ArrayBufferView& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("bufferSubData: no buffer bound!");
|
||||
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBufferView& data)
|
||||
{
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
already_AddRefed<WebGLBuffer>
|
||||
|
|
|
@ -1381,10 +1381,32 @@ IsFormatAndTypeUnpackable(GLenum format, GLenum type)
|
|||
}
|
||||
}
|
||||
|
||||
// This function is temporary, and will be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1176214 lands, which will
|
||||
// collapse the SharedArrayBufferView and ArrayBufferView into one.
|
||||
void
|
||||
ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
|
||||
void** const out_data, size_t* const out_length,
|
||||
js::Scalar::Type* const out_type)
|
||||
{
|
||||
if (view.IsArrayBufferView()) {
|
||||
const dom::ArrayBufferView& pixbuf = view.GetAsArrayBufferView();
|
||||
pixbuf.ComputeLengthAndData();
|
||||
*out_length = pixbuf.Length();
|
||||
*out_data = pixbuf.Data();
|
||||
*out_type = JS_GetArrayBufferViewType(pixbuf.Obj());
|
||||
} else {
|
||||
const dom::SharedArrayBufferView& pixbuf = view.GetAsSharedArrayBufferView();
|
||||
pixbuf.ComputeLengthAndData();
|
||||
*out_length = pixbuf.Length();
|
||||
*out_data = pixbuf.Data();
|
||||
*out_type = JS_GetSharedArrayBufferViewType(pixbuf.Obj());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLenum format,
|
||||
GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum type, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -1460,8 +1482,13 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
|||
MOZ_CRASH("bad `type`");
|
||||
}
|
||||
|
||||
const dom::ArrayBufferView& pixbuf = pixels.Value();
|
||||
int dataType = pixbuf.Type();
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView &view = pixels.Value();
|
||||
// Compute length and data. Don't reenter after this point, lest the
|
||||
// precomputed go out of sync with the instant length/data.
|
||||
size_t dataByteLen;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &dataByteLen, &dataType);
|
||||
|
||||
// Check the pixels param type
|
||||
if (dataType != requiredDataType)
|
||||
|
@ -1479,15 +1506,9 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
|||
if (!checked_neededByteLength.isValid())
|
||||
return ErrorInvalidOperation("readPixels: integer overflow computing the needed buffer size");
|
||||
|
||||
// Compute length and data. Don't reenter after this point, lest the
|
||||
// precomputed go out of sync with the instant length/data.
|
||||
pixbuf.ComputeLengthAndData();
|
||||
|
||||
uint32_t dataByteLen = pixbuf.Length();
|
||||
if (checked_neededByteLength.value() > dataByteLen)
|
||||
return ErrorInvalidOperation("readPixels: buffer too small");
|
||||
|
||||
void* data = pixbuf.Data();
|
||||
if (!data) {
|
||||
ErrorOutOfMemory("readPixels: buffer storage is null. Did we run out of memory?");
|
||||
return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
|
|
|
@ -298,7 +298,7 @@ void
|
|||
WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
|
@ -356,7 +356,7 @@ void
|
|||
WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
|
@ -434,7 +434,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOf
|
|||
void
|
||||
WebGLContext::CompressedTexImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLint border, const dom::ArrayBufferView& view)
|
||||
GLint border, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
WebGLTexture* tex;
|
||||
|
@ -452,7 +452,7 @@ void
|
|||
WebGLContext::CompressedTexSubImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLsizei width,
|
||||
GLsizei height, GLenum unpackFormat,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
WebGLTexture* tex;
|
||||
|
|
|
@ -24,6 +24,7 @@ class ErrorResult;
|
|||
namespace dom {
|
||||
class Element;
|
||||
class ImageData;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
} // namespace dom
|
||||
|
||||
// Zero is not an integer power of two.
|
||||
|
@ -108,24 +109,24 @@ public:
|
|||
|
||||
void CompressedTexImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLint border, const dom::ArrayBufferView& view);
|
||||
GLint border, const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CompressedTexImage3D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLsizei depth, GLint border, GLsizei imageSize,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
|
||||
void CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLsizei width,
|
||||
GLsizei height, GLenum unpackFormat,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CompressedTexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLsizei imageSize,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
|
||||
void CopyTexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
|
@ -144,7 +145,7 @@ public:
|
|||
void TexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -156,7 +157,7 @@ public:
|
|||
void TexImage3D(TexImageTarget target, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLint border,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
|
||||
|
||||
|
@ -169,7 +170,7 @@ public:
|
|||
void TexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLenum unpackFormat, GLenum unpackType,
|
||||
|
@ -181,7 +182,7 @@ public:
|
|||
void TexSubImage3D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
|
||||
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexSubImage3D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLenum unpackFormat,
|
||||
|
|
|
@ -58,7 +58,7 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
GLint level,
|
||||
GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexImage;
|
||||
const WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
|
||||
|
@ -76,9 +76,11 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
return;
|
||||
}
|
||||
|
||||
view.ComputeLengthAndData();
|
||||
size_t byteLength;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &byteLength, &dataType);
|
||||
|
||||
uint32_t byteLength = view.Length();
|
||||
if (!mContext->ValidateCompTexImageDataSize(level, internalFormat, width, height, byteLength, func, dims)) {
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +98,7 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
|
||||
mContext->MakeContextCurrent();
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalFormat, width, height, border, byteLength, view.Data());
|
||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalFormat, width, height, border, byteLength, data);
|
||||
|
||||
SetImageInfo(texImageTarget, level, width, height, 1, internalFormat,
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
|
@ -106,7 +108,7 @@ void
|
|||
WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum internalFormat,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexSubImage;
|
||||
const WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
|
||||
|
@ -131,9 +133,11 @@ WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level
|
|||
return mContext->ErrorInvalidOperation("compressedTexImage2D: internalFormat does not match the existing image");
|
||||
}
|
||||
|
||||
view.ComputeLengthAndData();
|
||||
size_t byteLength;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &byteLength, &dataType);
|
||||
|
||||
uint32_t byteLength = view.Length();
|
||||
if (!mContext->ValidateCompTexImageDataSize(level, internalFormat, width, height, byteLength, func, dims))
|
||||
return;
|
||||
|
||||
|
@ -161,7 +165,7 @@ WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level
|
|||
|
||||
mContext->MakeContextCurrent();
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xOffset, yOffset, width, height, internalFormat, byteLength, view.Data());
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xOffset, yOffset, width, height, internalFormat, byteLength, data);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -614,23 +618,19 @@ void
|
|||
WebGLTexture::TexImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType, const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
GLenum unpackType, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
void* data;
|
||||
uint32_t length;
|
||||
size_t length;
|
||||
js::Scalar::Type jsArrayType;
|
||||
if (maybeView.IsNull()) {
|
||||
data = nullptr;
|
||||
length = 0;
|
||||
jsArrayType = js::Scalar::MaxTypedArrayViewType;
|
||||
} else {
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
data = view.Data();
|
||||
length = view.Length();
|
||||
jsArrayType = view.Type();
|
||||
const auto& view = maybeView.Value();
|
||||
ComputeLengthAndData(view, &data, &length, &jsArrayType);
|
||||
}
|
||||
|
||||
const char funcName[] = "texImage2D";
|
||||
|
@ -850,14 +850,17 @@ WebGLTexture::TexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
if (maybeView.IsNull())
|
||||
return mContext->ErrorInvalidValue("texSubImage2D: pixels must not be null!");
|
||||
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
const auto& view = maybeView.Value();
|
||||
size_t length;
|
||||
void* data;
|
||||
js::Scalar::Type jsArrayType;
|
||||
ComputeLengthAndData(view, &data, &length, &jsArrayType);
|
||||
|
||||
const char funcName[] = "texSubImage2D";
|
||||
if (!DoesTargetMatchDimensions(mContext, texImageTarget, 2, funcName))
|
||||
|
@ -865,7 +868,7 @@ WebGLTexture::TexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
|||
|
||||
return TexSubImage2D_base(texImageTarget, level, xOffset, yOffset,
|
||||
width, height, 0, unpackFormat, unpackType,
|
||||
view.Data(), view.Length(), view.Type(),
|
||||
data, length, jsArrayType,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
|
@ -1211,7 +1214,7 @@ void
|
|||
WebGLTexture::TexImage3D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
void* data;
|
||||
|
@ -1222,12 +1225,8 @@ WebGLTexture::TexImage3D(TexImageTarget texImageTarget, GLint level, GLenum inte
|
|||
dataLength = 0;
|
||||
jsArrayType = js::Scalar::MaxTypedArrayViewType;
|
||||
} else {
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
data = view.Data();
|
||||
dataLength = view.Length();
|
||||
jsArrayType = view.Type();
|
||||
const auto& view = maybeView.Value();
|
||||
ComputeLengthAndData(view, &data, &dataLength, &jsArrayType);
|
||||
}
|
||||
|
||||
const char funcName[] = "texImage3D";
|
||||
|
@ -1318,14 +1317,17 @@ WebGLTexture::TexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
if (maybeView.IsNull())
|
||||
return mContext->ErrorInvalidValue("texSubImage3D: pixels must not be null!");
|
||||
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
const auto& view = maybeView.Value();
|
||||
void* data;
|
||||
size_t dataLength;
|
||||
js::Scalar::Type jsArrayType;
|
||||
ComputeLengthAndData(view, &data, &dataLength, &jsArrayType);
|
||||
|
||||
const char funcName[] = "texSubImage3D";
|
||||
if (!DoesTargetMatchDimensions(mContext, texImageTarget, 3, funcName))
|
||||
|
@ -1358,10 +1360,6 @@ WebGLTexture::TexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
|||
return mContext->ErrorInvalidOperation("texSubImage3D: type differs from that of the existing image");
|
||||
}
|
||||
|
||||
js::Scalar::Type jsArrayType = view.Type();
|
||||
void* data = view.Data();
|
||||
size_t dataLength = view.Length();
|
||||
|
||||
if (!mContext->ValidateTexInputData(unpackType, jsArrayType, func, dims))
|
||||
return;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ skip-if = android_version == '10' || android_version == '18' #Android 2.3 and 4.
|
|||
[webgl-mochitest/test_noprog_draw.html]
|
||||
[webgl-mochitest/test_privileged_exts.html]
|
||||
[webgl-mochitest/test_renderer_strings.html]
|
||||
[webgl-mochitest/test_sab_with_webgl.html]
|
||||
[webgl-mochitest/test_texsubimage_float.html]
|
||||
[webgl-mochitest/test_uninit_data.html]
|
||||
[webgl-mochitest/test_webgl_available.html]
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<script src='/tests/SimpleTest/SimpleTest.js'></script>
|
||||
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id='c' width='200' height='200'></canvas>
|
||||
<canvas id='c2' width='200' height='200'></canvas>
|
||||
|
||||
<script>
|
||||
|
||||
var gl;
|
||||
|
||||
function RGBAToString(arr) {
|
||||
return '[' + arr[0].toPrecision(4) + ', ' +
|
||||
arr[1].toPrecision(4) + ', ' +
|
||||
arr[2].toPrecision(4) + ', ' +
|
||||
arr[3].toPrecision(4) + ']';
|
||||
}
|
||||
|
||||
function TestScreenColor(gl, r, g, b, a) {
|
||||
var arr = new SharedArrayBuffer(4);
|
||||
var view = new SharedUint8Array(arr);
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, view);
|
||||
|
||||
var err = gl.getError();
|
||||
ok(err == 0, 'Should be no errors.');
|
||||
if (err)
|
||||
return;
|
||||
|
||||
var floatArr;
|
||||
floatArr = new Float32Array(4);
|
||||
floatArr[0] = view[0] / 255.0;
|
||||
floatArr[1] = view[1] / 255.0;
|
||||
floatArr[2] = view[2] / 255.0;
|
||||
floatArr[3] = view[3] / 255.0;
|
||||
|
||||
var testText = RGBAToString(floatArr);
|
||||
var refText = RGBAToString([r, g, b, a]);
|
||||
|
||||
var eps = 1.0 / 255.0;
|
||||
var isSame = (Math.abs(floatArr[0] - r) < eps &&
|
||||
Math.abs(floatArr[1] - g) < eps &&
|
||||
Math.abs(floatArr[2] - b) < eps &&
|
||||
Math.abs(floatArr[3] - a) < eps);
|
||||
|
||||
ok(isSame, 'Should be ' + refText + ', was ' + testText + ',');
|
||||
}
|
||||
|
||||
// Give ourselves a scope to return early from:
|
||||
(function() {
|
||||
var canvas = document.getElementById('c');
|
||||
var attribs = {
|
||||
antialias: false,
|
||||
depth: false,
|
||||
};
|
||||
gl = canvas.getContext('experimental-webgl', attribs);
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
todo(false, 'SharedArrayBuffer is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (SharedFloat32Array === 'undefined') {
|
||||
todo(false, 'SharedFloat32Array is unavailable.');
|
||||
return;
|
||||
}
|
||||
|
||||
var vs = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vs, "attribute vec2 aVertCoord; void main(void) { gl_Position = vec4(aVertCoord, 0.0, 1.0); }");
|
||||
gl.compileShader(vs);
|
||||
var fs = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
gl.shaderSource(fs, "precision mediump float; uniform vec4 uFragColor; void main(void) { gl_FragColor = uFragColor; }");
|
||||
gl.compileShader(fs);
|
||||
var prog = gl.createProgram();
|
||||
gl.attachShader(prog, vs);
|
||||
gl.attachShader(prog, fs);
|
||||
gl.linkProgram(prog);
|
||||
|
||||
var success = gl.getProgramParameter(prog, gl.LINK_STATUS);
|
||||
if (!success) {
|
||||
console.log('Error linking program for \'' + vsId + '\' and \'' + fsId + '\'.');
|
||||
console.log('\nLink log: ' + gl.getProgramInfoLog(prog));
|
||||
console.log('\nVert shader log: ' + gl.getShaderInfoLog(vs));
|
||||
console.log('\nFrag shader log: ' + gl.getShaderInfoLog(fs));
|
||||
}
|
||||
ok(prog, 'Program should link.');
|
||||
if (!prog) {
|
||||
return;
|
||||
}
|
||||
|
||||
prog.aVertCoord = gl.getAttribLocation(prog, 'aVertCoord');
|
||||
prog.uFragColor = gl.getUniformLocation(prog, 'uFragColor');
|
||||
|
||||
gl.useProgram(prog);
|
||||
|
||||
// Test gl.bufferData(), gl.bufferSubData() and gl.readPixels() APIs with SAB as input.
|
||||
var arr = new SharedArrayBuffer(8*4);
|
||||
var view = new SharedFloat32Array(arr);
|
||||
view.set(new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]));
|
||||
var vb = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, arr, gl.STATIC_DRAW);
|
||||
ok(gl.getError() == 0, 'bufferData with SAB as input parameter works ok.');
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, arr);
|
||||
ok(gl.getError() == 0, 'bufferSubData with SAB as input parameter works ok.');
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.clearColor(0, 0, 0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.uniform4f(prog.uFragColor, 0.2, 0.4, 0.6, 1.0);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
var arr = new Uint8Array(4);
|
||||
TestScreenColor(gl, 0.2, 0.4, 0.6, 1.0);
|
||||
|
||||
// Test gl.texImage2D() and gl.texSubImage2D() APIs with SAB as input.
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
var width = 4;
|
||||
var height = 4;
|
||||
var numChannels = 4;
|
||||
var sab = new SharedArrayBuffer(width * height * numChannels);
|
||||
var data = new SharedUint8Array(sab);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
data[i] = i;
|
||||
}
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texImage2D() with SAB as input parameter works ok.');
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texSubImage2D() with SAB as input parameter works ok.');
|
||||
|
||||
ok(gl.getError() == 0, 'Should be no errors after test.');
|
||||
})();
|
||||
|
||||
// Test WebGL 2
|
||||
(function() {
|
||||
var canvas = document.getElementById('c2');
|
||||
var attribs = {
|
||||
antialias: false,
|
||||
depth: false,
|
||||
};
|
||||
gl = canvas.getContext('webgl2', attribs);
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL 2 is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
todo(false, 'SharedArrayBuffer is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (SharedFloat32Array === 'undefined') {
|
||||
todo(false, 'SharedFloat32Array is unavailable.');
|
||||
return;
|
||||
}
|
||||
|
||||
var arr = new SharedArrayBuffer(8*4);
|
||||
var view = new SharedFloat32Array(arr);
|
||||
view.set(new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]));
|
||||
var vb = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, arr, gl.STATIC_DRAW);
|
||||
|
||||
var arr2 = new SharedArrayBuffer(8*4);
|
||||
gl.getBufferSubData(gl.ARRAY_BUFFER, 0, arr2);
|
||||
var view2 = new SharedFloat32Array(arr2);
|
||||
var equal = true;
|
||||
for(var i = 0; i < 8; ++i) {
|
||||
if (view[i] != view2[i]) equal = false;
|
||||
}
|
||||
ok(equal, 'getBufferSubData with SAB as input parameter works ok.');
|
||||
|
||||
// Test gl.texImage3D() and gl.texSubImage3D() APIs with SAB as input.
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_3D, tex);
|
||||
var width = 4;
|
||||
var height = 4;
|
||||
var depth = 4;
|
||||
var numChannels = 4;
|
||||
var sab = new SharedArrayBuffer(width * height * depth* numChannels);
|
||||
var data = new SharedUint8Array(sab);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
data[i] = i;
|
||||
}
|
||||
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texImage3D() with SAB as input parameter works ok.');
|
||||
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texSubImage3D() with SAB as input parameter works ok.');
|
||||
|
||||
ok(gl.getError() == 0, 'Should be no errors after test.');
|
||||
})();
|
||||
|
||||
ok(true, 'TEST COMPLETE');
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -319,6 +319,7 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
|||
void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset,
|
||||
GLintptr writeOffset, GLsizeiptr size);
|
||||
void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer? returnedData);
|
||||
void getBufferSubData(GLenum target, GLintptr offset, SharedArrayBuffer returnedData);
|
||||
|
||||
/* Framebuffer objects */
|
||||
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
|
||||
|
@ -347,10 +348,10 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
|||
void texImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum format,
|
||||
GLenum type, ArrayBufferView? pixels);
|
||||
GLenum type, (ArrayBufferView or SharedArrayBufferView)? pixels);
|
||||
[Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
|
||||
ArrayBufferView? pixels);
|
||||
(ArrayBufferView or SharedArrayBufferView)? pixels);
|
||||
[Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLenum format, GLenum type, ImageData? data);
|
||||
[Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
|
@ -363,10 +364,10 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
|||
GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, ArrayBufferView data);
|
||||
GLint border, GLsizei imageSize, (ArrayBufferView or SharedArrayBufferView) data);
|
||||
void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLsizei imageSize, ArrayBufferView data);
|
||||
GLenum format, GLsizei imageSize, (ArrayBufferView or SharedArrayBufferView) data);
|
||||
|
||||
/* Programs and shaders */
|
||||
[WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram? program, DOMString name);
|
||||
|
|
|
@ -552,9 +552,13 @@ interface WebGLRenderingContext {
|
|||
|
||||
void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
|
||||
void bufferData(GLenum target, ArrayBufferView data, GLenum usage);
|
||||
void bufferData(GLenum target, SharedArrayBufferView data, GLenum usage);
|
||||
void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
|
||||
void bufferData(GLenum target, SharedArrayBuffer data, GLenum usage);
|
||||
void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView data);
|
||||
void bufferSubData(GLenum target, GLintptr offset, SharedArrayBufferView data);
|
||||
void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
|
||||
void bufferSubData(GLenum target, GLintptr offset, SharedArrayBuffer data);
|
||||
|
||||
[WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target);
|
||||
void clear(GLbitfield mask);
|
||||
|
@ -566,11 +570,11 @@ interface WebGLRenderingContext {
|
|||
|
||||
void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
ArrayBufferView data);
|
||||
(ArrayBufferView or SharedArrayBufferView) data);
|
||||
void compressedTexSubImage2D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLenum format,
|
||||
ArrayBufferView data);
|
||||
(ArrayBufferView or SharedArrayBufferView) data);
|
||||
|
||||
void copyTexImage2D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
|
@ -673,7 +677,7 @@ interface WebGLRenderingContext {
|
|||
|
||||
[Throws]
|
||||
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type, ArrayBufferView? pixels);
|
||||
GLenum format, GLenum type, (ArrayBufferView or SharedArrayBufferView)? pixels);
|
||||
|
||||
void renderbufferStorage(GLenum target, GLenum internalformat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
@ -693,7 +697,7 @@ interface WebGLRenderingContext {
|
|||
[Throws]
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum format,
|
||||
GLenum type, ArrayBufferView? pixels);
|
||||
GLenum type, (ArrayBufferView or SharedArrayBufferView)? pixels);
|
||||
[Throws]
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLenum format, GLenum type, ImageData? pixels);
|
||||
|
@ -713,7 +717,7 @@ interface WebGLRenderingContext {
|
|||
[Throws]
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type, ArrayBufferView? pixels);
|
||||
GLenum format, GLenum type, (ArrayBufferView or SharedArrayBufferView)? pixels);
|
||||
[Throws]
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLenum format, GLenum type, ImageData? pixels);
|
||||
|
|
Загрузка…
Ссылка в новой задаче