author | Jeff Gilbert <jgilbert@mozilla.com> |
Wed, 21 Dec 2016 19:42:07 -0800 | |
changeset 327539 | c0eb5a38f7168f4731c3e796d5f25d9788e9d87a |
parent 327538 | c22ce760279e78eb670f23118d8c320893a09502 |
child 327540 | c274a7c25dc7e3a9228b3b9a5c1917e985ff4192 |
push id | 35517 |
push user | kwierso@gmail.com |
push date | Thu, 29 Dec 2016 20:22:54 +0000 |
treeherder | autoland@3f2f8d77ad27 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz, daoshengmu |
bugs | 1325301 |
milestone | 53.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- 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 @@ -5923,17 +5923,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 @@ -470,18 +470,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"]