--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -238,18 +238,20 @@ public:
// -------------------------------------------------------------------------
// Uniforms and attributes - WebGL2ContextUniforms.cpp
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
////////////////
// GL 3.0 & ES 3.0
- void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
- void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
+ const char* funcName = nullptr);
+ void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
+ const char* funcName = nullptr);
void VertexAttribI4iv(GLuint index, const Int32ListU& list) {
const auto& arr = Int32Arr::From(list);
if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, arr.elemCount))
return;
const auto& itr = arr.elemBytes;
VertexAttribI4i(index, itr[0], itr[1], itr[2], itr[3]);
--- a/dom/canvas/WebGL2ContextFramebuffers.cpp
+++ b/dom/canvas/WebGL2ContextFramebuffers.cpp
@@ -320,18 +320,20 @@ WebGL2Context::ReadBuffer(GLenum mode)
mBoundReadFramebuffer->ReadBuffer(funcName, mode);
return;
}
// Operating on the default framebuffer.
if (mode != LOCAL_GL_NONE &&
mode != LOCAL_GL_BACK)
{
+ nsCString enumName;
+ EnumName(mode, &enumName);
ErrorInvalidOperation("%s: If READ_FRAMEBUFFER is null, `mode` must be BACK or"
- " NONE. Was %s",
- funcName, EnumName(mode));
+ " NONE. Was %s.",
+ funcName, enumName.BeginReading());
return;
}
gl->Screen()->SetReadBuffer(mode);
}
} // namespace mozilla
--- a/dom/canvas/WebGL2ContextSamplers.cpp
+++ b/dom/canvas/WebGL2ContextSamplers.cpp
@@ -134,14 +134,14 @@ WebGL2Context::GetSamplerParameter(JSCon
{
GLfloat param = 0;
gl->fGetSamplerParameterfv(sampler.mGLName, pname, ¶m);
retval.set(JS::Float32Value(param));
}
return;
default:
- ErrorInvalidEnum("%s: invalid pname: %s", funcName, EnumName(pname));
+ ErrorInvalidEnumArg(funcName, "pname", pname);
return;
}
}
} // namespace mozilla
--- a/dom/canvas/WebGL2ContextUniforms.cpp
+++ b/dom/canvas/WebGL2ContextUniforms.cpp
@@ -156,17 +156,17 @@ ValidateUniformEnum(WebGLContext* webgl,
case LOCAL_GL_UNIFORM_BLOCK_INDEX:
case LOCAL_GL_UNIFORM_OFFSET:
case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
return true;
default:
- webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname));
+ webgl->ErrorInvalidEnumArg(info, "pname", pname);
return false;
}
}
void
WebGL2Context::GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
const dom::Sequence<GLuint>& uniformIndices,
GLenum pname, JS::MutableHandleValue retval)
--- a/dom/canvas/WebGL2ContextVertices.cpp
+++ b/dom/canvas/WebGL2ContextVertices.cpp
@@ -71,75 +71,22 @@ WebGL2Context::VertexAttribIPointer(GLui
if (!ValidateAttribPointer(true, index, size, type, LOCAL_GL_FALSE, stride, offset,
"vertexAttribIPointer"))
{
return;
}
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
InvalidateBufferFetching();
MakeContextCurrent();
gl->fVertexAttribIPointer(index, size, type, stride, reinterpret_cast<void*>(offset));
WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
const bool integerFunc = true;
const bool normalized = false;
vd.VertexAttribPointer(integerFunc, mBoundArrayBuffer, size, type, normalized, stride,
offset);
}
-void
-WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
-{
- if (IsContextLost())
- return;
-
- if (!ValidateAttribIndex(index, "vertexAttribI4i"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_INT;
-
- MakeContextCurrent();
-
- if (index) {
- gl->fVertexAttribI4i(index, x, y, z, w);
- } else {
- mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
- mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
- mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
- mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
- if (gl->IsGLES()) {
- gl->fVertexAttribI4i(index, x, y, z, w);
- }
- }
-}
-
-void
-WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
-{
- if (IsContextLost())
- return;
-
- if (!ValidateAttribIndex(index, "vertexAttribI4ui"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_UNSIGNED_INT;
-
- MakeContextCurrent();
-
- if (index) {
- gl->fVertexAttribI4ui(index, x, y, z, w);
- } else {
- mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
- mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
- mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
- mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
- if (gl->IsGLES()) {
- gl->fVertexAttribI4ui(index, x, y, z, w);
- }
- }
-}
-
} // namespace mozilla
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -138,28 +138,16 @@ WebGLContext::WebGLContext()
mDisableExtensions = false;
mIsMesa = false;
mEmitContextLostErrorOnce = false;
mWebGLError = 0;
mUnderlyingGLError = 0;
mActiveTexture = 0;
- mVertexAttrib0Vector[0] = 0;
- mVertexAttrib0Vector[1] = 0;
- mVertexAttrib0Vector[2] = 0;
- mVertexAttrib0Vector[3] = 1;
- mFakeVertexAttrib0BufferObjectVector[0] = 0;
- mFakeVertexAttrib0BufferObjectVector[1] = 0;
- mFakeVertexAttrib0BufferObjectVector[2] = 0;
- mFakeVertexAttrib0BufferObjectVector[3] = 1;
- mFakeVertexAttrib0BufferObjectSize = 0;
- mFakeVertexAttrib0BufferObject = 0;
- mFakeVertexAttrib0BufferStatus = WebGLVertexAttrib0Status::Default;
-
mStencilRefFront = 0;
mStencilRefBack = 0;
mStencilValueMaskFront = 0;
mStencilValueMaskBack = 0;
mStencilWriteMaskFront = 0;
mStencilWriteMaskBack = 0;
mDepthWriteMask = 0;
mStencilClearValue = 0;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -403,27 +403,27 @@ public:
void ErrorInvalidValue(const char* fmt = 0, ...);
void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...);
void ErrorInvalidEnumInfo(const char* info, GLenum enumValue);
void ErrorInvalidEnumInfo(const char* info, const char* funcName,
GLenum enumValue);
void ErrorOutOfMemory(const char* fmt = 0, ...);
void ErrorImplementationBug(const char* fmt = 0, ...);
+ void ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val);
+
const char* ErrorName(GLenum error);
/**
* Return displayable name for GLenum.
* This version is like gl::GLenumToStr but with out the GL_ prefix to
* keep consistency with how errors are reported from WebGL.
+ * Returns hex formatted version of glenum if glenum is unknown.
*/
- // Returns nullptr if glenum is unknown.
- static const char* EnumName(GLenum glenum);
- // Returns hex formatted version of glenum if glenum is unknown.
- static void EnumName(GLenum glenum, nsACString* out_name);
+ static void EnumName(GLenum val, nsCString* out_name);
void DummyReadFramebufferOperation(const char* funcName);
WebGLTexture* ActiveBoundTextureForTarget(const TexTarget texTarget) const {
switch (texTarget.get()) {
case LOCAL_GL_TEXTURE_2D:
return mBound2DTextures[mActiveTexture];
case LOCAL_GL_TEXTURE_CUBE_MAP:
@@ -1281,53 +1281,74 @@ public:
void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
{
retval.set(GetVertexAttrib(cx, index, pname, rv));
}
WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
- void VertexAttrib1f(GLuint index, GLfloat x0);
- void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1);
- void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2);
- void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2,
- GLfloat x3);
+ ////
+
+ void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
+ const char* funcName = nullptr);
+
+ ////
- void VertexAttrib1fv(GLuint idx, const dom::Float32Array& arr) {
- arr.ComputeLengthAndData();
- VertexAttrib1fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
+ void VertexAttrib1f(GLuint index, GLfloat x) {
+ VertexAttrib4f(index, x, 0, 0, 1, "vertexAttrib1f");
+ }
+ void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
+ VertexAttrib4f(index, x, y, 0, 1, "vertexAttrib2f");
+ }
+ void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
+ VertexAttrib4f(index, x, y, z, 1, "vertexAttrib3f");
}
- void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
- VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
+
+ ////
+
+ void VertexAttrib1fv(GLuint index, const Float32ListU& list) {
+ const char funcName[] = "vertexAttrib1fv";
+ const auto& arr = Float32Arr::From(list);
+ if (!ValidateAttribArraySetter(funcName, 1, arr.elemCount))
+ return;
+
+ VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1, funcName);
}
- void VertexAttrib2fv(GLuint idx, const dom::Float32Array& arr) {
- arr.ComputeLengthAndData();
- VertexAttrib2fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
- }
- void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
- VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
+ void VertexAttrib2fv(GLuint index, const Float32ListU& list) {
+ const char funcName[] = "vertexAttrib2fv";
+ const auto& arr = Float32Arr::From(list);
+ if (!ValidateAttribArraySetter(funcName, 2, arr.elemCount))
+ return;
+
+ VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1, funcName);
}
- void VertexAttrib3fv(GLuint idx, const dom::Float32Array& arr) {
- arr.ComputeLengthAndData();
- VertexAttrib3fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
- }
- void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
- VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
+ void VertexAttrib3fv(GLuint index, const Float32ListU& list) {
+ const char funcName[] = "vertexAttrib3fv";
+ const auto& arr = Float32Arr::From(list);
+ if (!ValidateAttribArraySetter(funcName, 3, arr.elemCount))
+ return;
+
+ VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], 1,
+ funcName);
}
- void VertexAttrib4fv(GLuint idx, const dom::Float32Array& arr) {
- arr.ComputeLengthAndData();
- VertexAttrib4fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
+ void VertexAttrib4fv(GLuint index, const Float32ListU& list) {
+ const char funcName[] = "vertexAttrib4fv";
+ const auto& arr = Float32Arr::From(list);
+ if (!ValidateAttribArraySetter(funcName, 4, arr.elemCount))
+ return;
+
+ VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
+ arr.elemBytes[3], funcName);
}
- void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
- VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
- }
+
+ ////
void VertexAttribPointer(GLuint index, GLint size, GLenum type,
WebGLboolean normalized, GLsizei stride,
WebGLintptr byteOffset);
void VertexAttribDivisor(GLuint index, GLuint divisor);
private:
// Cache the max number of vertices and instances that can be read from
@@ -1356,18 +1377,18 @@ private:
const GLfloat* ptr);
bool ValidateBufferFetching(const char* info);
bool BindArrayAttribToLocation0(WebGLProgram* prog);
// -----------------------------------------------------------------------------
// PROTECTED
protected:
- WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need();
- bool DoFakeVertexAttrib0(GLuint vertexCount);
+ WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
+ bool DoFakeVertexAttrib0(const char* funcName, GLuint vertexCount);
void UndoFakeVertexAttrib0();
inline void InvalidateBufferFetching()
{
mBufferFetchingIsVerified = false;
mBufferFetchingHasPerVertex = false;
mMaxFetchedVertices = 0;
mMaxFetchedInstances = 0;
@@ -1404,17 +1425,17 @@ protected:
GLenum mUnderlyingGLError;
GLenum GetAndFlushUnderlyingGLErrors();
bool mBypassShaderValidation;
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
// some GL constants
- int32_t mGLMaxVertexAttribs;
+ uint32_t mGLMaxVertexAttribs;
int32_t mGLMaxTextureUnits;
int32_t mGLMaxTextureImageUnits;
int32_t mGLMaxVertexTextureImageUnits;
int32_t mGLMaxVaryingVectors;
int32_t mGLMaxFragmentUniformVectors;
int32_t mGLMaxVertexUniformVectors;
uint32_t mGLMaxTransformFeedbackSeparateAttribs;
GLuint mGLMaxUniformBufferBindings;
@@ -1868,26 +1889,27 @@ private:
public:
void OnUBIndexedBindingsChanged() const { mBuffersForUB_Dirty = true; }
const decltype(mBuffersForUB)& BuffersForUB() const;
////////////////////////////////////
protected:
// Generic Vertex Attributes
- UniquePtr<GLenum[]> mVertexAttribType;
- GLfloat mVertexAttrib0Vector[4];
- GLfloat mFakeVertexAttrib0BufferObjectVector[4];
- size_t mFakeVertexAttrib0BufferObjectSize;
+ // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the spec
+ // state tables, this isn't vertex shader /object/ state. This array is merely state
+ // useful to vertex shaders, but is global state.
+ UniquePtr<GLenum[]> mGenericVertexAttribTypes;
+ uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
+
GLuint mFakeVertexAttrib0BufferObject;
- WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus;
+ size_t mFakeVertexAttrib0BufferObjectSize;
+ bool mFakeVertexAttrib0DataDefined;
+ uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
- void GetVertexAttribFloat(GLuint index, GLfloat* out_result);
- void GetVertexAttribInt(GLuint index, GLint* out_result);
- void GetVertexAttribUint(GLuint index, GLuint* out_result);
JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
GLint mStencilRefFront;
GLint mStencilRefBack;
GLuint mStencilValueMaskFront;
GLuint mStencilValueMaskBack;
--- a/dom/canvas/WebGLContextBuffers.cpp
+++ b/dom/canvas/WebGLContextBuffers.cpp
@@ -501,20 +501,18 @@ WebGLContext::DeleteBuffer(WebGLBuffer*
}
}
for (auto& binding : mIndexedUniformBufferBindings) {
fnClearIfBuffer(binding.mBufferBinding);
}
}
- for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
- if (mBoundVertexArray->HasAttrib(i)) {
- fnClearIfBuffer(mBoundVertexArray->mAttribs[i].mBuf);
- }
+ for (auto& cur : mBoundVertexArray->mAttribs) {
+ fnClearIfBuffer(cur.mBuf);
}
////
buffer->RequestDelete();
}
bool
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -341,17 +341,17 @@ public:
}
} else {
mWebGL->ClearBackbufferIfNeeded();
}
////
const size_t requiredVerts = firstVertex + vertCount;
- if (!mWebGL->DoFakeVertexAttrib0(requiredVerts)) {
+ if (!mWebGL->DoFakeVertexAttrib0(funcName, requiredVerts)) {
*out_error = true;
return;
}
mDidFake = true;
////
// Check UBO sizes.
@@ -389,16 +389,43 @@ public:
funcName);
*out_error = true;
return;
}
}
////
+ for (const auto& progAttrib : mWebGL->mActiveProgramLinkInfo->attribs) {
+ const auto& loc = progAttrib.mLoc;
+
+ const auto& attribData = mWebGL->mBoundVertexArray->mAttribs[loc];
+
+ GLenum attribDataBaseType;
+ if (attribData.mEnabled) {
+ attribDataBaseType = attribData.BaseType();
+ } else {
+ attribDataBaseType = mWebGL->mGenericVertexAttribTypes[loc];
+ }
+
+ if (attribDataBaseType != progAttrib.mBaseType) {
+ nsCString progType, dataType;
+ WebGLContext::EnumName(progAttrib.mBaseType, &progType);
+ WebGLContext::EnumName(attribDataBaseType, &dataType);
+ mWebGL->ErrorInvalidOperation("%s: Vertex attrib %u requires data of type"
+ " %s, but is being supplied with type %s.",
+ funcName, loc, progType.BeginReading(),
+ dataType.BeginReading());
+ *out_error = true;
+ return;
+ }
+ }
+
+ ////
+
mWebGL->RunContextLossTimer();
}
~ScopedDrawHelper() {
if (mDidFake) {
mWebGL->UndoFakeVertexAttrib0();
}
}
@@ -681,19 +708,21 @@ WebGLContext::DrawElements_check(const c
ErrorInvalidOperation("%s: bound vertex attribute buffers do not have sufficient "
"size for given indices from the bound element array",
funcName);
return false;
}
// Bug 1008310 - Check if buffer has been used with a different previous type
if (elemArrayBuffer.IsElementArrayUsedWithMultipleTypes()) {
+ nsCString typeName;
+ WebGLContext::EnumName(type, &typeName);
GenerateWarning("%s: bound element array buffer previously used with a type other than "
"%s, this will affect performance.",
- funcName, WebGLContext::EnumName(type));
+ funcName, typeName.BeginReading());
}
return true;
}
static void
HandleDrawElementsErrors(WebGLContext* webgl, const char* funcName,
gl::GLContext::LocalErrorScope& errorScope)
@@ -952,141 +981,159 @@ WebGLContext::ValidateBufferFetching(con
mBufferFetchingHasPerVertex = hasPerVertex;
mMaxFetchedVertices = maxVertices;
mMaxFetchedInstances = maxInstances;
return true;
}
WebGLVertexAttrib0Status
-WebGLContext::WhatDoesVertexAttrib0Need()
+WebGLContext::WhatDoesVertexAttrib0Need() const
{
MOZ_ASSERT(mCurrentProgram);
MOZ_ASSERT(mActiveProgramLinkInfo);
+ const auto& isAttribArray0Enabled = mBoundVertexArray->mAttribs[0].mEnabled;
+
// work around Mac OSX crash, see bug 631420
#ifdef XP_MACOSX
if (gl->WorkAroundDriverBugs() &&
- mBoundVertexArray->IsAttribArrayEnabled(0) &&
+ isAttribArray0Enabled &&
!mBufferFetch_IsAttrib0Active)
{
return WebGLVertexAttrib0Status::EmulatedUninitializedArray;
}
#endif
- if (MOZ_LIKELY(gl->IsGLES() ||
- mBoundVertexArray->IsAttribArrayEnabled(0)))
+ if (MOZ_LIKELY(!gl->IsCompatibilityProfile() ||
+ isAttribArray0Enabled))
{
return WebGLVertexAttrib0Status::Default;
}
return mBufferFetch_IsAttrib0Active
? WebGLVertexAttrib0Status::EmulatedInitializedArray
: WebGLVertexAttrib0Status::EmulatedUninitializedArray;
}
bool
-WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
+WebGLContext::DoFakeVertexAttrib0(const char* funcName, GLuint vertexCount)
{
- WebGLVertexAttrib0Status whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
+ if (!vertexCount) {
+ vertexCount = 1;
+ }
+ const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default))
return true;
if (!mAlreadyWarnedAboutFakeVertexAttrib0) {
GenerateWarning("Drawing without vertex attrib 0 array enabled forces the browser "
"to do expensive emulation work when running on desktop OpenGL "
"platforms, for example on Mac. It is preferable to always draw "
"with vertex attrib 0 array enabled, by using bindAttribLocation "
"to bind some always-used attribute to location 0.");
mAlreadyWarnedAboutFakeVertexAttrib0 = true;
}
- CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(GLfloat);
+ if (!mFakeVertexAttrib0BufferObject) {
+ gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject);
+ mFakeVertexAttrib0BufferObjectSize = 0;
+ }
+ gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
+
+ ////
+
+ switch (mGenericVertexAttribTypes[0]) {
+ case LOCAL_GL_FLOAT:
+ gl->fVertexAttribPointer(0, 4, LOCAL_GL_FLOAT, false, 0, 0);
+ break;
+ case LOCAL_GL_INT:
+ gl->fVertexAttribIPointer(0, 4, LOCAL_GL_INT, 0, 0);
+ break;
+
+ case LOCAL_GL_UNSIGNED_INT:
+ gl->fVertexAttribIPointer(0, 4, LOCAL_GL_UNSIGNED_INT, 0, 0);
+ break;
+
+ default:
+ MOZ_CRASH();
+ }
+
+ ////
+
+ const auto bytesPerVert = sizeof(mFakeVertexAttrib0Data);
+ const auto checked_dataSize = CheckedUint32(vertexCount) * bytesPerVert;
if (!checked_dataSize.isValid()) {
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
"with %d vertices. Try reducing the number of vertices.", vertexCount);
return false;
}
+ const auto dataSize = checked_dataSize.value();
- GLuint dataSize = checked_dataSize.value();
+ if (mFakeVertexAttrib0BufferObjectSize < dataSize) {
+ gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
+ mFakeVertexAttrib0BufferObjectSize = dataSize;
+ mFakeVertexAttrib0DataDefined = false;
+ }
- if (!mFakeVertexAttrib0BufferObject) {
- gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject);
+ if (whatDoesAttrib0Need == WebGLVertexAttrib0Status::EmulatedUninitializedArray)
+ return true;
+
+ ////
+
+ if (mFakeVertexAttrib0DataDefined &&
+ memcmp(mFakeVertexAttrib0Data, mGenericVertexAttrib0Data, bytesPerVert) == 0)
+ {
+ return true;
}
- // if the VBO status is already exactly what we need, or if the only difference is that it's initialized and
- // we don't need it to be, then consider it OK
- bool vertexAttrib0BufferStatusOK =
- mFakeVertexAttrib0BufferStatus == whatDoesAttrib0Need ||
- (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray &&
- whatDoesAttrib0Need == WebGLVertexAttrib0Status::EmulatedUninitializedArray);
-
- if (!vertexAttrib0BufferStatusOK ||
- mFakeVertexAttrib0BufferObjectSize < dataSize ||
- mFakeVertexAttrib0BufferObjectVector[0] != mVertexAttrib0Vector[0] ||
- mFakeVertexAttrib0BufferObjectVector[1] != mVertexAttrib0Vector[1] ||
- mFakeVertexAttrib0BufferObjectVector[2] != mVertexAttrib0Vector[2] ||
- mFakeVertexAttrib0BufferObjectVector[3] != mVertexAttrib0Vector[3])
- {
- mFakeVertexAttrib0BufferStatus = whatDoesAttrib0Need;
- mFakeVertexAttrib0BufferObjectSize = dataSize;
- mFakeVertexAttrib0BufferObjectVector[0] = mVertexAttrib0Vector[0];
- mFakeVertexAttrib0BufferObjectVector[1] = mVertexAttrib0Vector[1];
- mFakeVertexAttrib0BufferObjectVector[2] = mVertexAttrib0Vector[2];
- mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
-
- gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
-
- GetAndFlushUnderlyingGLErrors();
+ ////
- if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
- auto array = MakeUniqueFallible<GLfloat[]>(4 * vertexCount);
- if (!array) {
- ErrorOutOfMemory("Fake attrib0 array.");
- return false;
- }
- for(size_t i = 0; i < vertexCount; ++i) {
- array[4 * i + 0] = mVertexAttrib0Vector[0];
- array[4 * i + 1] = mVertexAttrib0Vector[1];
- array[4 * i + 2] = mVertexAttrib0Vector[2];
- array[4 * i + 3] = mVertexAttrib0Vector[3];
- }
- gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array.get(), LOCAL_GL_DYNAMIC_DRAW);
- } else {
- gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
- }
- GLenum error = GetAndFlushUnderlyingGLErrors();
+ const UniqueBuffer data(malloc(dataSize));
+ if (!data) {
+ ErrorOutOfMemory("%s: Failed to allocate fake vertex attrib 0 array.",
+ funcName);
+ return false;
+ }
+ auto itr = (uint8_t*)data.get();
+ const auto itrEnd = itr + dataSize;
+ while (itr != itrEnd) {
+ memcpy(itr, mGenericVertexAttrib0Data, bytesPerVert);
+ itr += bytesPerVert;
+ }
- gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
+ {
+ gl::GLContext::LocalErrorScope errorScope(*gl);
- // note that we do this error checking and early return AFTER having restored the buffer binding above
- if (error) {
- ErrorOutOfMemory("Ran out of memory trying to construct a fake vertex attrib 0 array for a draw-operation "
- "with %d vertices. Try reducing the number of vertices.", vertexCount);
+ gl->fBufferSubData(LOCAL_GL_ARRAY_BUFFER, 0, dataSize, data.get());
+
+ const auto err = errorScope.GetError();
+ if (err) {
+ ErrorOutOfMemory("%s: Failed to upload fake vertex attrib 0 data.", funcName);
return false;
}
}
- gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
- gl->fVertexAttribPointer(0, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0);
+ ////
+ memcpy(mFakeVertexAttrib0Data, mGenericVertexAttrib0Data, bytesPerVert);
+ mFakeVertexAttrib0DataDefined = true;
return true;
}
void
WebGLContext::UndoFakeVertexAttrib0()
{
- WebGLVertexAttrib0Status whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
-
+ const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default))
return;
- if (mBoundVertexArray->HasAttrib(0) && mBoundVertexArray->mAttribs[0].mBuf) {
+ if (mBoundVertexArray->mAttribs[0].mBuf) {
const WebGLVertexAttribData& attrib0 = mBoundVertexArray->mAttribs[0];
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.mBuf->mGLName);
attrib0.DoVertexAttribPointer(gl, 0);
} else {
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -241,22 +241,23 @@ WebGLContext::ErrorName(GLenum error)
case LOCAL_GL_NO_ERROR:
return "NO_ERROR";
default:
MOZ_ASSERT(false);
return "[unknown WebGL error]";
}
}
-// This version is 'fallible' and will return NULL if glenum is not recognized.
-const char*
-WebGLContext::EnumName(GLenum glenum)
+// This version is fallible and will return nullptr if unrecognized.
+static const char*
+GetEnumName(GLenum val)
{
- switch (glenum) {
+ switch (val) {
#define XX(x) case LOCAL_GL_##x: return #x
+ XX(NONE);
XX(ALPHA);
XX(ATC_RGB);
XX(ATC_RGBA_EXPLICIT_ALPHA);
XX(ATC_RGBA_INTERPOLATED_ALPHA);
XX(COMPRESSED_RGBA_PVRTC_2BPPV1);
XX(COMPRESSED_RGBA_PVRTC_4BPPV1);
XX(COMPRESSED_RGBA_S3TC_DXT1_EXT);
XX(COMPRESSED_RGBA_S3TC_DXT3_EXT);
@@ -268,16 +269,17 @@ WebGLContext::EnumName(GLenum glenum)
XX(DEPTH_COMPONENT);
XX(DEPTH_COMPONENT16);
XX(DEPTH_COMPONENT32);
XX(DEPTH_STENCIL);
XX(DEPTH24_STENCIL8);
XX(DRAW_FRAMEBUFFER);
XX(ETC1_RGB8_OES);
XX(FLOAT);
+ XX(INT);
XX(FRAMEBUFFER);
XX(HALF_FLOAT);
XX(LUMINANCE);
XX(LUMINANCE_ALPHA);
XX(READ_FRAMEBUFFER);
XX(RGB);
XX(RGB16F);
XX(RGB32F);
@@ -569,26 +571,34 @@ WebGLContext::EnumName(GLenum glenum)
XX(NUM_SAMPLE_COUNTS);
XX(TEXTURE_IMMUTABLE_LEVELS);
#undef XX
}
return nullptr;
}
-void
-WebGLContext::EnumName(GLenum glenum, nsACString* out_name)
+/*static*/ void
+WebGLContext::EnumName(GLenum val, nsCString* out_name)
{
- const char* name = EnumName(glenum);
+ const char* name = GetEnumName(val);
if (name) {
- *out_name = nsDependentCString(name);
- } else {
- nsPrintfCString enumAsHex("<enum 0x%04x>", glenum);
- *out_name = enumAsHex;
+ *out_name = name;
+ return;
}
+
+ *out_name = nsPrintfCString("<enum 0x%04x>", val);
+}
+
+void
+WebGLContext::ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val)
+{
+ nsCString enumName;
+ EnumName(val, &enumName);
+ ErrorInvalidEnum("%s: Bad `%s`: %s", funcName, argName, enumName.BeginReading());
}
bool
IsCompressedTextureFormat(GLenum format)
{
switch (format) {
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -538,17 +538,17 @@ WebGLContext::InitAndValidateGL(FailureR
// For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled.
if (gl->IsCompatibilityProfile())
gl->fEnableVertexAttribArray(0);
if (MinCapabilityMode())
mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
else
- gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
+ gl->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
if (mGLMaxVertexAttribs < 8) {
const nsPrintfCString reason("GL_MAX_VERTEX_ATTRIBS: %d is < 8!",
mGLMaxVertexAttribs);
*out_failReason = { "FEATURE_FAILURE_WEBGL_V_ATRB", reason };
return false;
}
@@ -735,23 +735,16 @@ WebGLContext::InitAndValidateGL(FailureR
if (IsWebGL2() &&
!InitWebGL2(out_failReason))
{
// Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
return false;
}
- // Default value for all disabled vertex attributes is [0, 0, 0, 1]
- mVertexAttribType = MakeUnique<GLenum[]>(mGLMaxVertexAttribs);
- for (int32_t index = 0; index < mGLMaxVertexAttribs; ++index) {
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
- VertexAttrib4f(index, 0, 0, 0, 1);
- }
-
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mBoundVertexArray = mDefaultVertexArray;
// OpenGL core profiles remove the default VAO object from version
// 4.0.0. We create a default VAO for all core profiles,
// regardless of version.
//
@@ -778,16 +771,25 @@ WebGLContext::InitAndValidateGL(FailureR
mPixelStore_UnpackAlignment = 4;
mPixelStore_PackRowLength = 0;
mPixelStore_PackSkipRows = 0;
mPixelStore_PackSkipPixels = 0;
mPixelStore_PackAlignment = 4;
mPrimRestartTypeBytes = 0;
+ mGenericVertexAttribTypes.reset(new GLenum[mGLMaxVertexAttribs]);
+ std::fill_n(mGenericVertexAttribTypes.get(), mGLMaxVertexAttribs, LOCAL_GL_FLOAT);
+
+ static const float kDefaultGenericVertexAttribData[4] = { 0, 0, 0, 1 };
+ memcpy(mGenericVertexAttrib0Data, kDefaultGenericVertexAttribData,
+ sizeof(mGenericVertexAttrib0Data));
+
+ mFakeVertexAttrib0BufferObject = 0;
+
return true;
}
bool
WebGLContext::ValidateFramebufferTarget(GLenum target,
const char* const info)
{
bool isValid = true;
@@ -804,14 +806,13 @@ WebGLContext::ValidateFramebufferTarget(
isValid = false;
break;
}
if (MOZ_LIKELY(isValid)) {
return true;
}
- ErrorInvalidEnum("%s: Invalid target: %s (0x%04x).", info, EnumName(target),
- target);
+ ErrorInvalidEnumArg(info, "target", target);
return false;
}
} // namespace mozilla
--- a/dom/canvas/WebGLContextVertices.cpp
+++ b/dom/canvas/WebGLContextVertices.cpp
@@ -15,332 +15,199 @@
#include "WebGLTexture.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
#include "mozilla/Casting.h"
namespace mozilla {
-void
-WebGLContext::GetVertexAttribFloat(GLuint index, GLfloat* out_result)
-{
- if (index) {
- gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
- } else {
- out_result[0] = mVertexAttrib0Vector[0];
- out_result[1] = mVertexAttrib0Vector[1];
- out_result[2] = mVertexAttrib0Vector[2];
- out_result[3] = mVertexAttrib0Vector[3];
- }
-}
-
-void
-WebGLContext::GetVertexAttribInt(GLuint index, GLint* out_result)
-{
- if (index) {
- gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
- } else {
- out_result[0] = BitwiseCast<GLint>(mVertexAttrib0Vector[0]);
- out_result[1] = BitwiseCast<GLint>(mVertexAttrib0Vector[1]);
- out_result[2] = BitwiseCast<GLint>(mVertexAttrib0Vector[2]);
- out_result[3] = BitwiseCast<GLint>(mVertexAttrib0Vector[3]);
- }
-}
-
-void
-WebGLContext::GetVertexAttribUint(GLuint index, GLuint* out_result)
-{
- if (index) {
- gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
- } else {
- out_result[0] = BitwiseCast<GLuint>(mVertexAttrib0Vector[0]);
- out_result[1] = BitwiseCast<GLuint>(mVertexAttrib0Vector[1]);
- out_result[2] = BitwiseCast<GLuint>(mVertexAttrib0Vector[2]);
- out_result[3] = BitwiseCast<GLuint>(mVertexAttrib0Vector[3]);
- }
-}
-
JSObject*
WebGLContext::GetVertexAttribFloat32Array(JSContext* cx, GLuint index)
{
GLfloat attrib[4];
- GetVertexAttribFloat(index, &attrib[0]);
+ if (index) {
+ gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
+ } else {
+ memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
+ }
return dom::Float32Array::Create(cx, this, 4, attrib);
}
JSObject*
WebGLContext::GetVertexAttribInt32Array(JSContext* cx, GLuint index)
{
GLint attrib[4];
- GetVertexAttribInt(index, &attrib[0]);
+ if (index) {
+ gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
+ } else {
+ memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
+ }
return dom::Int32Array::Create(cx, this, 4, attrib);
}
JSObject*
-WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index) {
+WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index)
+{
GLuint attrib[4];
- GetVertexAttribUint(index, &attrib[0]);
+ if (index) {
+ gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
+ } else {
+ memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
+ }
return dom::Uint32Array::Create(cx, this, 4, attrib);
}
-void
-WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
-{
- if (IsContextLost())
- return;
-
- if (!ValidateAttribIndex(index, "vertexAttrib1f"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
-
- if (index) {
- gl->fVertexAttrib1f(index, x0);
- } else {
- mVertexAttrib0Vector[0] = x0;
- mVertexAttrib0Vector[1] = 0;
- mVertexAttrib0Vector[2] = 0;
- mVertexAttrib0Vector[3] = 1;
- if (gl->IsGLES())
- gl->fVertexAttrib1f(index, x0);
- }
-}
+////////////////////////////////////////
void
-WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
+WebGLContext::VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
+ const char* funcName)
{
+ if (!funcName) {
+ funcName = "vertexAttrib4f";
+ }
+
if (IsContextLost())
return;
- if (!ValidateAttribIndex(index, "vertexAttrib2f"))
+ if (!ValidateAttribIndex(index, funcName))
return;
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
+ ////
- if (index) {
- gl->fVertexAttrib2f(index, x0, x1);
- } else {
- mVertexAttrib0Vector[0] = x0;
- mVertexAttrib0Vector[1] = x1;
- mVertexAttrib0Vector[2] = 0;
- mVertexAttrib0Vector[3] = 1;
- if (gl->IsGLES())
- gl->fVertexAttrib2f(index, x0, x1);
+ gl->MakeCurrent();
+ if (index || !gl->IsCompatibilityProfile()) {
+ gl->fVertexAttrib4f(index, x, y, z, w);
}
-}
-void
-WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
-{
- if (IsContextLost())
- return;
+ ////
- if (!ValidateAttribIndex(index, "vertexAttrib3f"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
+ mGenericVertexAttribTypes[index] = LOCAL_GL_FLOAT;
- MakeContextCurrent();
-
- if (index) {
- gl->fVertexAttrib3f(index, x0, x1, x2);
- } else {
- mVertexAttrib0Vector[0] = x0;
- mVertexAttrib0Vector[1] = x1;
- mVertexAttrib0Vector[2] = x2;
- mVertexAttrib0Vector[3] = 1;
- if (gl->IsGLES())
- gl->fVertexAttrib3f(index, x0, x1, x2);
+ if (!index) {
+ const float data[4] = { x, y, z, w };
+ memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
void
-WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
- GLfloat x2, GLfloat x3)
+WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
+ const char* funcName)
{
+ if (!funcName) {
+ funcName = "vertexAttribI4i";
+ }
+
if (IsContextLost())
return;
- if (!ValidateAttribIndex(index, "vertexAttrib4f"))
+ if (!ValidateAttribIndex(index, funcName))
return;
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
+ ////
- if (index) {
- gl->fVertexAttrib4f(index, x0, x1, x2, x3);
- } else {
- mVertexAttrib0Vector[0] = x0;
- mVertexAttrib0Vector[1] = x1;
- mVertexAttrib0Vector[2] = x2;
- mVertexAttrib0Vector[3] = x3;
- if (gl->IsGLES())
- gl->fVertexAttrib4f(index, x0, x1, x2, x3);
+ gl->MakeCurrent();
+ if (index || !gl->IsCompatibilityProfile()) {
+ gl->fVertexAttribI4i(index, x, y, z, w);
}
-}
-
-void
-WebGLContext::VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
- const GLfloat* ptr)
-{
- if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
- return;
+ ////
- if (!ValidateAttribIndex(index, "vertexAttrib1fv"))
- return;
+ mGenericVertexAttribTypes[index] = LOCAL_GL_INT;
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
- if (index) {
- gl->fVertexAttrib1fv(index, ptr);
- } else {
- mVertexAttrib0Vector[0] = ptr[0];
- mVertexAttrib0Vector[1] = GLfloat(0);
- mVertexAttrib0Vector[2] = GLfloat(0);
- mVertexAttrib0Vector[3] = GLfloat(1);
- if (gl->IsGLES())
- gl->fVertexAttrib1fv(index, ptr);
+ if (!index) {
+ const int32_t data[4] = { x, y, z, w };
+ memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
void
-WebGLContext::VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
- const GLfloat* ptr)
+WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
+ const char* funcName)
{
- if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
+ if (!funcName) {
+ funcName = "vertexAttribI4ui";
+ }
+
+ if (IsContextLost())
return;
- if (!ValidateAttribIndex(index, "vertexAttrib2fv"))
+ if (!ValidateAttribIndex(index, funcName))
return;
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
+ ////
+
+ gl->MakeCurrent();
+ if (index || !gl->IsCompatibilityProfile()) {
+ gl->fVertexAttribI4ui(index, x, y, z, w);
+ }
- MakeContextCurrent();
- if (index) {
- gl->fVertexAttrib2fv(index, ptr);
- } else {
- mVertexAttrib0Vector[0] = ptr[0];
- mVertexAttrib0Vector[1] = ptr[1];
- mVertexAttrib0Vector[2] = GLfloat(0);
- mVertexAttrib0Vector[3] = GLfloat(1);
- if (gl->IsGLES())
- gl->fVertexAttrib2fv(index, ptr);
+ ////
+
+ mGenericVertexAttribTypes[index] = LOCAL_GL_UNSIGNED_INT;
+
+ if (!index) {
+ const uint32_t data[4] = { x, y, z, w };
+ memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
-void
-WebGLContext::VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
- const GLfloat* ptr)
-{
- if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
- return;
-
- if (!ValidateAttribIndex(index, "vertexAttrib3fv"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
- if (index) {
- gl->fVertexAttrib3fv(index, ptr);
- } else {
- mVertexAttrib0Vector[0] = ptr[0];
- mVertexAttrib0Vector[1] = ptr[1];
- mVertexAttrib0Vector[2] = ptr[2];
- mVertexAttrib0Vector[3] = GLfloat(1);
- if (gl->IsGLES())
- gl->fVertexAttrib3fv(index, ptr);
- }
-}
-
-void
-WebGLContext::VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
- const GLfloat* ptr)
-{
- if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
- return;
-
- if (!ValidateAttribIndex(index, "vertexAttrib4fv"))
- return;
-
- mVertexAttribType[index] = LOCAL_GL_FLOAT;
-
- MakeContextCurrent();
- if (index) {
- gl->fVertexAttrib4fv(index, ptr);
- } else {
- mVertexAttrib0Vector[0] = ptr[0];
- mVertexAttrib0Vector[1] = ptr[1];
- mVertexAttrib0Vector[2] = ptr[2];
- mVertexAttrib0Vector[3] = ptr[3];
- if (gl->IsGLES())
- gl->fVertexAttrib4fv(index, ptr);
- }
-}
+////////////////////////////////////////
void
WebGLContext::EnableVertexAttribArray(GLuint index)
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
return;
MakeContextCurrent();
InvalidateBufferFetching();
gl->fEnableVertexAttribArray(index);
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
mBoundVertexArray->mAttribs[index].mEnabled = true;
}
void
WebGLContext::DisableVertexAttribArray(GLuint index)
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "disableVertexAttribArray"))
return;
MakeContextCurrent();
InvalidateBufferFetching();
- if (index || gl->IsGLES()) {
+ if (index || !gl->IsCompatibilityProfile()) {
gl->fDisableVertexAttribArray(index);
}
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
mBoundVertexArray->mAttribs[index].mEnabled = false;
}
JS::Value
WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
ErrorResult& rv)
{
+ const char funcName[] = "getVertexAttrib";
if (IsContextLost())
return JS::NullValue();
- if (!ValidateAttribIndex(index, "getVertexAttrib"))
+ if (!ValidateAttribIndex(index, funcName))
return JS::NullValue();
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
MakeContextCurrent();
switch (pname) {
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundVertexArray->mAttribs[index].mBuf.get(), rv);
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
@@ -364,17 +231,17 @@ WebGLContext::GetVertexAttrib(JSContext*
{
return JS::Int32Value(mBoundVertexArray->mAttribs[index].mDivisor);
}
break;
case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
{
JS::RootedObject obj(cx);
- switch (mVertexAttribType[index]) {
+ switch (mGenericVertexAttribTypes[index]) {
case LOCAL_GL_FLOAT:
obj = GetVertexAttribFloat32Array(cx, index);
break;
case LOCAL_GL_INT:
obj = GetVertexAttribInt32Array(cx, index);
break;
@@ -412,17 +279,16 @@ WebGLContext::GetVertexAttribOffset(GLui
return 0;
if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) {
ErrorInvalidEnum("getVertexAttribOffset: bad parameter");
return 0;
}
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
return mBoundVertexArray->mAttribs[index].ByteOffset();
}
void
WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
WebGLboolean normalized, GLsizei stride,
WebGLintptr byteOffset)
{
@@ -431,17 +297,16 @@ WebGLContext::VertexAttribPointer(GLuint
if (!ValidateAttribIndex(index, "vertexAttribPointer"))
return;
if (!ValidateAttribPointer(false, index, size, type, normalized, stride, byteOffset, "vertexAttribPointer"))
return;
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
InvalidateBufferFetching();
/* XXX make work with bufferSubData & heterogeneous types
if (type != mBoundArrayBuffer->GLType())
return ErrorInvalidOperation("vertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
*/
@@ -460,17 +325,16 @@ WebGLContext::VertexAttribDivisor(GLuint
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttribDivisor"))
return;
MOZ_ASSERT(mBoundVertexArray);
- mBoundVertexArray->EnsureAttrib(index);
WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
vd.mDivisor = divisor;
InvalidateBufferFetching();
MakeContextCurrent();
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -418,23 +418,24 @@ WebGLFBAttachPoint::GetParameter(const c
if (webgl->IsWebGL2())
return JS::NullValue();
break;
default:
break;
}
-
+ nsCString attachmentName;
+ WebGLContext::EnumName(attachment, &attachmentName);
if (webgl->IsWebGL2()) {
webgl->ErrorInvalidOperation("%s: No attachment at %s.", funcName,
- webgl->EnumName(attachment));
+ attachmentName.BeginReading());
} else {
webgl->ErrorInvalidEnum("%s: No attachment at %s.", funcName,
- webgl->EnumName(attachment));
+ attachmentName.BeginReading());
}
return JS::NullValue();
}
bool isPNameValid = false;
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::Int32Value(mTexturePtr ? LOCAL_GL_TEXTURE
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -78,17 +78,59 @@ AssembleName(const nsCString& baseName,
*out_name = baseName;
if (isArray) {
out_name->Append('[');
out_name->AppendInt(uint64_t(arrayIndex));
out_name->Append(']');
}
}
-//////////
+////
+
+static GLenum
+AttribBaseType(GLenum attribType)
+{
+ switch (attribType) {
+ case LOCAL_GL_FLOAT:
+ case LOCAL_GL_FLOAT_VEC2:
+ case LOCAL_GL_FLOAT_VEC3:
+ case LOCAL_GL_FLOAT_VEC4:
+
+ case LOCAL_GL_FLOAT_MAT2:
+ case LOCAL_GL_FLOAT_MAT2x3:
+ case LOCAL_GL_FLOAT_MAT2x4:
+
+ case LOCAL_GL_FLOAT_MAT3x2:
+ case LOCAL_GL_FLOAT_MAT3:
+ case LOCAL_GL_FLOAT_MAT3x4:
+
+ case LOCAL_GL_FLOAT_MAT4x2:
+ case LOCAL_GL_FLOAT_MAT4x3:
+ case LOCAL_GL_FLOAT_MAT4:
+ return LOCAL_GL_FLOAT;
+
+ case LOCAL_GL_INT:
+ case LOCAL_GL_INT_VEC2:
+ case LOCAL_GL_INT_VEC3:
+ case LOCAL_GL_INT_VEC4:
+ return LOCAL_GL_INT;
+
+ case LOCAL_GL_UNSIGNED_INT:
+ case LOCAL_GL_UNSIGNED_INT_VEC2:
+ case LOCAL_GL_UNSIGNED_INT_VEC3:
+ case LOCAL_GL_UNSIGNED_INT_VEC4:
+ return LOCAL_GL_UNSIGNED_INT;
+
+ default:
+ MOZ_ASSERT(false, "unexpected attrib elemType");
+ return 0;
+ }
+}
+
+////
/*static*/ const webgl::UniformInfo::TexListT*
webgl::UniformInfo::GetTexList(WebGLActiveInfo* activeInfo)
{
const auto& webgl = activeInfo->mWebGL;
switch (activeInfo->mElemType) {
case LOCAL_GL_SAMPLER_2D:
@@ -220,17 +262,18 @@ QueryProgramInfo(WebGLProgram* prog, gl:
///////
const bool isArray = false;
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
elemType, isArray,
userName,
mappedName);
- const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc)};
+ const GLenum baseType = AttribBaseType(elemType);
+ const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc), baseType};
info->attribs.push_back(attrib);
}
// Uniforms
const bool needsCheckForArrays = gl->WorkAroundDriverBugs();
GLuint numActiveUniforms = 0;
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -33,17 +33,18 @@ class OwningUnsignedLongOrUint32ArrayOrB
template<typename> class Sequence;
} // namespace dom
namespace webgl {
struct AttribInfo final
{
const RefPtr<WebGLActiveInfo> mActiveInfo;
- uint32_t mLoc;
+ const uint32_t mLoc;
+ const GLenum mBaseType;
};
struct UniformInfo final
{
typedef decltype(WebGLContext::mBound2DTextures) TexListT;
const RefPtr<WebGLActiveInfo> mActiveInfo;
const TexListT* const mSamplerTexList;
@@ -117,16 +118,17 @@ struct LinkedProgramInfo final
} // namespace webgl
class WebGLProgram final
: public nsWrapperCache
, public WebGLRefCountedObject<WebGLProgram>
, public LinkedListElement<WebGLProgram>
{
friend class WebGLTransformFeedback;
+ friend struct webgl::LinkedProgramInfo;
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
explicit WebGLProgram(WebGLContext* webgl);
void Delete();
--- a/dom/canvas/WebGLQuery.cpp
+++ b/dom/canvas/WebGLQuery.cpp
@@ -131,18 +131,17 @@ WebGLQuery::GetQueryParameter(GLenum pna
const char funcName[] = "getQueryParameter";
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
break;
default:
- mContext->ErrorInvalidEnum("%s: Invalid pname: %s", funcName,
- mContext->EnumName(pname));
+ mContext->ErrorInvalidEnumArg(funcName, "pname", pname);
return;
}
if (!mTarget) {
mContext->ErrorInvalidOperation("%s: Query has never been active.", funcName);
return;
}
--- a/dom/canvas/WebGLSampler.cpp
+++ b/dom/canvas/WebGLSampler.cpp
@@ -128,22 +128,21 @@ ValidateSamplerParameterParams(WebGLCont
return true;
default:
break;
}
break;
default:
- webgl->ErrorInvalidEnum("%s: invalid pname: %s", funcName,
- webgl->EnumName(pname));
+ webgl->ErrorInvalidEnumArg(funcName, "pname", pname);
return false;
}
- webgl->ErrorInvalidEnum("%s: invalid param: %s", funcName, webgl->EnumName(paramInt));
+ webgl->ErrorInvalidEnumArg(funcName, "param", paramInt);
return false;
}
void
WebGLSampler::SamplerParameter(const char* funcName, GLenum pname,
const FloatOrInt& param)
{
if (!ValidateSamplerParameterParams(mContext, funcName, pname, param))
--- a/dom/canvas/WebGLShader.h
+++ b/dom/canvas/WebGLShader.h
@@ -84,16 +84,17 @@ public:
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLShader)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLShader)
public:
const GLuint mGLName;
const GLenum mType;
+
protected:
nsString mSource;
nsCString mCleanSource;
UniquePtr<webgl::ShaderValidator> mValidator;
nsCString mValidationLog;
bool mTranslationSuccessful;
nsCString mTranslatedSource;
--- a/dom/canvas/WebGLVertexArray.cpp
+++ b/dom/canvas/WebGLVertexArray.cpp
@@ -19,16 +19,17 @@ WebGLVertexArray::WrapObject(JSContext*
{
return dom::WebGLVertexArrayObjectBinding::Wrap(cx, this, givenProto);
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
: WebGLRefCountedObject(webgl)
, mGLName(0)
{
+ mAttribs.SetLength(mContext->mGLMaxVertexAttribs);
mContext->mVertexArrays.insertBack(this);
}
WebGLVertexArray*
WebGLVertexArray::Create(WebGLContext* webgl)
{
WebGLVertexArray* array;
if (webgl->gl->IsSupported(gl::GLFeature::vertex_array_object)) {
@@ -50,26 +51,16 @@ WebGLVertexArray::Delete()
}
bool
WebGLVertexArray::IsVertexArray() const
{
return IsVertexArrayImpl();
}
-void
-WebGLVertexArray::EnsureAttrib(GLuint index)
-{
- MOZ_ASSERT(index < GLuint(mContext->mGLMaxVertexAttribs));
-
- if (index >= mAttribs.Length()) {
- mAttribs.SetLength(index + 1);
- }
-}
-
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
mAttribs,
mElementArrayBuffer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLVertexArray, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLVertexArray, Release)
} // namespace mozilla
--- a/dom/canvas/WebGLVertexArray.h
+++ b/dom/canvas/WebGLVertexArray.h
@@ -28,24 +28,16 @@ public:
static WebGLVertexArray* Create(WebGLContext* webgl);
void BindVertexArray() {
// Bind to dummy value to signal that this vertex array has ever been
// bound.
BindVertexArrayImpl();
};
- void EnsureAttrib(GLuint index);
- bool HasAttrib(GLuint index) const {
- return index < mAttribs.Length();
- }
- bool IsAttribArrayEnabled(GLuint index) const {
- return HasAttrib(index) && mAttribs[index].mEnabled;
- }
-
// Implement parent classes:
void Delete();
bool IsVertexArray() const;
WebGLContext* GetParentObject() const {
return mContext;
}
@@ -67,16 +59,17 @@ protected:
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
virtual bool IsVertexArrayImpl() const = 0;
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
+ friend class ScopedDrawHelper;
friend class WebGLContext;
friend class WebGLVertexArrayFake;
friend class WebGL2Context;
};
} // namespace mozilla
#endif // WEBGL_VERTEX_ARRAY_H_
--- a/dom/canvas/WebGLVertexAttribData.cpp
+++ b/dom/canvas/WebGLVertexAttribData.cpp
@@ -38,24 +38,47 @@ CalcBytesPerVertex(GLenum type, uint8_t
default:
MOZ_CRASH("Bad `type`.");
}
return bytesPerType * size;
}
+static GLenum
+AttribPointerBaseType(bool integerFunc, GLenum type)
+{
+ if (!integerFunc)
+ return LOCAL_GL_FLOAT;
+
+ switch (type) {
+ case LOCAL_GL_BYTE:
+ case LOCAL_GL_SHORT:
+ case LOCAL_GL_INT:
+ return LOCAL_GL_INT;
+
+ case LOCAL_GL_UNSIGNED_BYTE:
+ case LOCAL_GL_UNSIGNED_SHORT:
+ case LOCAL_GL_UNSIGNED_INT:
+ return LOCAL_GL_UNSIGNED_INT;
+
+ default:
+ MOZ_CRASH();
+ }
+}
+
void
WebGLVertexAttribData::VertexAttribPointer(bool integerFunc, WebGLBuffer* buf,
uint8_t size, GLenum type, bool normalized,
uint32_t stride, uint64_t byteOffset)
{
mIntegerFunc = integerFunc;
mBuf = buf;
mType = type;
+ mBaseType = AttribPointerBaseType(integerFunc, type);
mSize = size;
mBytesPerVertex = CalcBytesPerVertex(mType, mSize);
mNormalized = normalized;
mStride = stride;
mExplicitStride = (mStride ? mStride : mBytesPerVertex);
mByteOffset = byteOffset;
}
--- a/dom/canvas/WebGLVertexAttribData.h
+++ b/dom/canvas/WebGLVertexAttribData.h
@@ -20,29 +20,31 @@ public:
bool mEnabled;
private:
bool mIntegerFunc;
public:
WebGLRefPtr<WebGLBuffer> mBuf;
private:
GLenum mType;
+ GLenum mBaseType;
uint8_t mSize; // num of mType vals per vert
uint8_t mBytesPerVertex;
bool mNormalized;
uint32_t mStride; // bytes
uint32_t mExplicitStride;
uint64_t mByteOffset;
public:
#define GETTER(X) const decltype(m##X)& X() const { return m##X; }
GETTER(IntegerFunc)
GETTER(Type)
+ GETTER(BaseType)
GETTER(Size)
GETTER(BytesPerVertex)
GETTER(Normalized)
GETTER(Stride)
GETTER(ExplicitStride)
GETTER(ByteOffset)
#undef GETTER
--- a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html
@@ -35,16 +35,24 @@
<script id='vshader' type='x-shader/x-vertex'>#version 300 es
layout(location=0) in ivec2 p;
layout(location=1) in ivec4 a;
void main()
{
gl_Position = vec4(p.x + a.x + a.y + a.z + a.w, p.y, 0.0, 10.0);
}
</script>
+<script id='vshader_unsigned' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in ivec2 p;
+layout(location=1) in uvec4 a;
+void main()
+{
+ gl_Position = vec4(p.x + int(a.x + a.y + a.z + a.w), p.y, 0.0, 10.0);
+}
+</script>
<script id='fshader' type='x-shader/x-fragment'>#version 300 es
precision mediump float;
layout(location=0) out vec4 oColor;
void main()
{
oColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
@@ -64,30 +72,36 @@ function checkRedPortion(gl, w, low, hig
function runTest() {
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext('testbed', { preserveDrawingBuffer : true }, 2);
if (!gl) {
testFailed('could not create context');
return;
}
- var program = wtu.setupProgram(gl, ['vshader', 'fshader'])
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ var program_unsigned = wtu.setupProgram(gl, ['vshader_unsigned', 'fshader']);
gl.enableVertexAttribArray(0);
var pos = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pos);
gl.bufferData(gl.ARRAY_BUFFER, new Int32Array([-10, -10, 10, -10, -10, 10, 10, 10]), gl.STATIC_DRAW);
gl.vertexAttribIPointer(0, 2, gl.INT, 4 * 2, 0);
debug('Test vertexAttribI4[ui][v] by setting different combinations that add up to 15 and use that when rendering.');
var vals = [[2, -3, 6, 10], [1, 3, 1, 10], [-10, 3, 2, 20], [5, 6, 2, 2]];
var tests = ['vertexAttribI4i', 'vertexAttribI4ui', 'vertexAttribI4iv', 'vertexAttribI4uiv'];
for (var ii = 0; ii < 4; ++ii) {
+ if (ii % 2 == 0) {
+ gl.useProgram(program);
+ } else {
+ gl.useProgram(program_unsigned);
+ }
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (ii < 2) {
gl[tests[ii]](1, vals[ii][0], vals[ii][1], vals[ii][2], vals[ii][3]);
} else {
gl[tests[ii]](1, vals[ii]);
}
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
--- a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html
@@ -46,16 +46,27 @@ layout(location=1) in vec4 aColor;
out vec4 vColor;
void main()
{
gl_Position = vec4(aPosition);
vColor = aColor;
}
</script>
+<script id="vshader_unsigned" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in uvec4 aPosition;
+layout(location=1) in vec4 aColor;
+out vec4 vColor;
+void main()
+{
+ gl_Position = vec4(aPosition);
+ vColor = aColor;
+}
+
+</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
in vec4 vColor;
layout(location=0) out vec4 oColor;
void main()
{
oColor = vColor;
}
@@ -65,16 +76,17 @@ void main()
"use strict";
function init()
{
description("test vertexAttribIPointer offsets work");
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example", undefined, 2);
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+ var program_unsigned = wtu.setupProgram(gl, ["vshader_unsigned", "fshader"], ["vPosition"]);
var tests = [
{ data: new Int32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
type: gl.INT,
componentSize: 4,
},
{ data: new Uint32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
type: gl.UNSIGNED_INT,
@@ -111,16 +123,21 @@ function init()
var test = tests[tt];
for (var oo = 0; oo < 3; ++oo) {
for (var ss = 0; ss < 3; ++ss) {
var offset = (oo + 1) * test.componentSize;
var color = (count % 2) ? [1, 0, 0, 1] : [0, 1, 0, 1];
var stride = test.componentSize * kNumComponents + test.componentSize * ss;
debug("");
debug("check with " + wtu.glEnumToString(gl, test.type) + " at offset: " + offset + " with stride:" + stride);
+ if (test.type == gl.INT || test.type == gl.SHORT || test.type == gl.BYTE) {
+ gl.useProgram(program);
+ } else {
+ gl.useProgram(program_unsigned);
+ }
gl.vertexAttrib4fv(1, color);
var data = new Uint8Array(test.componentSize * kNumVerts * kNumComponents + stride * (kNumVerts - 1));
var view = new Uint8Array(test.data.buffer);
var size = test.componentSize * kNumComponents;
for (var jj = 0; jj < kNumVerts; ++jj) {
var off1 = jj * size;
var off2 = jj * stride;
for (var zz = 0; zz < size; ++zz) {
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -5921,17 +5921,16 @@ skip-if = (os == 'android')
[generated/test_conformance__attribs__gl-bindAttribLocation-matrix.html]
skip-if = (os == 'android')
[generated/test_conformance__attribs__gl-bindAttribLocation-repeated.html]
[generated/test_conformance__attribs__gl-disabled-vertex-attrib.html]
fail-if = (os == 'android')
[generated/test_conformance__attribs__gl-enable-vertex-attrib.html]
[generated/test_conformance__attribs__gl-matrix-attributes.html]
[generated/test_conformance__attribs__gl-vertex-attrib-render.html]
-fail-if = (os == 'linux')
[generated/test_conformance__attribs__gl-vertex-attrib-zero-issues.html]
[generated/test_conformance__attribs__gl-vertex-attrib.html]
[generated/test_conformance__attribs__gl-vertexattribpointer-offsets.html]
[generated/test_conformance__attribs__gl-vertexattribpointer.html]
fail-if = (os == 'mac') || (os == 'win') || (os == 'android') || (os == 'linux')
[generated/test_conformance__buffers__buffer-bind-test.html]
[generated/test_conformance__buffers__buffer-data-and-buffer-sub-data.html]
[generated/test_conformance__buffers__buffer-data-array-buffer-delete.html]
--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini
+++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini
@@ -466,18 +466,16 @@ fail-if = (os == 'b2g')
fail-if = (os == 'b2g')
[generated/test_conformance__programs__get-active-test.html]
fail-if = (os == 'b2g')
########################################################################
########################################################################
# Linux
-[generated/test_conformance__attribs__gl-vertex-attrib-render.html]
-fail-if = (os == 'linux')
[generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
# mozalloc_abort in libglsl.so
skip-if = (os == 'linux')
[generated/test_conformance__glsl__constructors__glsl-construct-vec3.html]
# Crashes
skip-if = (os == 'linux')
[generated/test_conformance__glsl__constructors__glsl-construct-vec4.html]
# Inferred crash from vec3 above.
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -688,27 +688,23 @@ interface WebGLRenderingContextBase {
void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
void useProgram(WebGLProgram? program);
void validateProgram(WebGLProgram program);
void vertexAttrib1f(GLuint indx, GLfloat x);
- void vertexAttrib1fv(GLuint indx, Float32Array values);
- void vertexAttrib1fv(GLuint indx, sequence<GLfloat> values);
+ void vertexAttrib1fv(GLuint indx, Float32List values);
void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
- void vertexAttrib2fv(GLuint indx, Float32Array values);
- void vertexAttrib2fv(GLuint indx, sequence<GLfloat> values);
+ void vertexAttrib2fv(GLuint indx, Float32List values);
void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
- void vertexAttrib3fv(GLuint indx, Float32Array values);
- void vertexAttrib3fv(GLuint indx, sequence<GLfloat> values);
+ void vertexAttrib3fv(GLuint indx, Float32List values);
void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- void vertexAttrib4fv(GLuint indx, Float32Array values);
- void vertexAttrib4fv(GLuint indx, sequence<GLfloat> values);
+ void vertexAttrib4fv(GLuint indx, Float32List values);
void vertexAttribPointer(GLuint indx, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, GLintptr offset);
void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
};
[Exposed=(Window,Worker),
Func="mozilla::dom::OffscreenCanvas::PrefEnabledOnWorkerThread"]