diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index b191a2f133a1..77b9270941b1 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -315,11 +315,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { std::unique_ptr mIncompleteTexOverride; - // Reuse, to avoid reallocing data for this, as this is showing up in - // profiles. - std::unordered_map - mReuseable_ScopedResolveTexturesForDraw_samplerByTexUnit; - public: class FuncScope; diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp index e2bed5cbe59d..3113da76d1be 100644 --- a/dom/canvas/WebGLContextDraw.cpp +++ b/dom/canvas/WebGLContextDraw.cpp @@ -79,11 +79,11 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( : mWebGL(webgl) { const auto& fb = mWebGL->mBoundDrawFramebuffer; - auto& samplerByTexUnit = - mWebGL->mReuseable_ScopedResolveTexturesForDraw_samplerByTexUnit; - if (!samplerByTexUnit.empty()) { - samplerByTexUnit.clear(); - } + struct SamplerByTexUnit { + uint8_t texUnit; + const webgl::SamplerUniformInfo* sampler; + }; + AutoTArray samplerByTexUnit; MOZ_ASSERT(mWebGL->mActiveProgramLinkInfo); const auto& samplerUniforms = mWebGL->mActiveProgramLinkInfo->samplerUniforms; @@ -96,11 +96,19 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( MOZ_ASSERT(texUnit < texList.Length()); { - auto& prevSamplerForTexUnit = samplerByTexUnit[texUnit]; + decltype(SamplerByTexUnit::sampler) prevSamplerForTexUnit = nullptr; + for (const auto& cur : samplerByTexUnit) { + if (cur.texUnit == texUnit) { + prevSamplerForTexUnit = cur.sampler; + } + } if (!prevSamplerForTexUnit) { + samplerByTexUnit.AppendElement(SamplerByTexUnit{texUnit, &uniform}); prevSamplerForTexUnit = &uniform; } - if (&uniform.texListForType != &prevSamplerForTexUnit->texListForType) { + + if (MOZ_UNLIKELY(&uniform.texListForType != + &prevSamplerForTexUnit->texListForType)) { // Pointing to different tex lists means different types! const auto linkInfo = mWebGL->mActiveProgramLinkInfo; const auto LocInfoBySampler = [&](const webgl::SamplerUniformInfo* p) @@ -132,11 +140,11 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( const auto& sampler = mWebGL->mBoundSamplers[texUnit]; const auto& samplingInfo = tex->GetSampleableInfo(sampler.get()); - if (!samplingInfo) { // There was an error. + if (MOZ_UNLIKELY(!samplingInfo)) { // There was an error. *out_error = true; return; } - if (!samplingInfo->IsComplete()) { + if (MOZ_UNLIKELY(!samplingInfo->IsComplete())) { if (samplingInfo->incompleteReason) { const auto& targetName = GetEnumName(tex->Target().get()); mWebGL->GenerateWarning("%s at unit %u is incomplete: %s", targetName, @@ -148,7 +156,7 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( // We have more validation to do if we're otherwise complete: const auto& texBaseType = samplingInfo->usage->format->baseType; - if (texBaseType != uniformBaseType) { + if (MOZ_UNLIKELY(texBaseType != uniformBaseType)) { const auto& targetName = GetEnumName(tex->Target().get()); const auto& srcType = ToString(texBaseType); const auto& dstType = ToString(uniformBaseType); @@ -160,7 +168,8 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( return; } - if (uniform.isShadowSampler != samplingInfo->isDepthTexCompare) { + if (MOZ_UNLIKELY(uniform.isShadowSampler != + samplingInfo->isDepthTexCompare)) { const auto& targetName = GetEnumName(tex->Target().get()); mWebGL->ErrorInvalidOperation( "%s at unit %u is%s a depth texture" @@ -173,8 +182,8 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw( return; } - if (!ValidateNoSamplingFeedback(*tex, samplingInfo->levels, fb.get(), - texUnit)) { + if (MOZ_UNLIKELY(!ValidateNoSamplingFeedback(*tex, samplingInfo->levels, + fb.get(), texUnit))) { *out_error = true; return; } diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index 10b1f576ad68..28cc1368649a 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -1355,8 +1355,8 @@ void WebGLContext::UniformData( const auto srcBegin = reinterpret_cast(data.begin().get()); auto destIndex = locInfo->indexIntoUniform; for (const auto& val : Range(srcBegin, elemCount)) { - if (destIndex >= texUnits.size()) break; - texUnits[destIndex] = val; + if (destIndex >= texUnits.Length()) break; + texUnits[destIndex] = AssertedCast(val); destIndex += 1; } } diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index 1a2e673d0b22..f01ed06a3616 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -202,6 +202,8 @@ static webgl::Limits MakeLimits(const WebGLContext& webgl) { // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value. gl.GetUIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &limits.maxTexUnits); + limits.maxTexUnits = std::min( + limits.maxTexUnits, uint32_t{UINT8_MAX}); // We want to use uint8_t. gl.GetUIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &limits.maxTex2dSize); gl.GetUIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &limits.maxTexCubeSize); diff --git a/dom/canvas/WebGLProgram.cpp b/dom/canvas/WebGLProgram.cpp index 586019603d8a..3dfa3a7de8b1 100644 --- a/dom/canvas/WebGLProgram.cpp +++ b/dom/canvas/WebGLProgram.cpp @@ -490,7 +490,7 @@ RefPtr QueryProgramInfo(WebGLProgram* prog, auto curInfo = std::unique_ptr( new webgl::SamplerUniformInfo{*texList, *baseType, isShadowSampler}); - curInfo->texUnits.resize(uniform.elemCount); + curInfo->texUnits.SetLength(uniform.elemCount); samplerInfo = curInfo.get(); info->samplerUniforms.push_back(std::move(curInfo)); } diff --git a/dom/canvas/WebGLProgram.h b/dom/canvas/WebGLProgram.h index fc7d97987abc..5d6349764db1 100644 --- a/dom/canvas/WebGLProgram.h +++ b/dom/canvas/WebGLProgram.h @@ -78,7 +78,7 @@ struct SamplerUniformInfo final { const decltype(WebGLContext::mBound2DTextures)& texListForType; const webgl::TextureBaseType texBaseType; const bool isShadowSampler; - std::vector texUnits; + AutoTArray texUnits; }; struct LocationInfo final {