diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index 651b88cf0213..be8ca04be2ec 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -611,13 +611,10 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce FEngine const& engine = mEngine; DriverApi& driverApi = mEngine.getDriverApi(); - bool const isSharedVariant = - (mMaterialDomain == MaterialDomain::SURFACE) && - !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant); + bool const isShared = isSharedVariant(variant); // Check if the default material has this program cached - if (isSharedVariant) { + if (isShared) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial) { auto program = pDefaultMaterial->mCachedPrograms[variant.key]; @@ -636,7 +633,7 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce // If the default material doesn't already have this program cached, and all caching conditions // are met (Surface Domain and no custom depth shader), cache it now. // New Materials will inherit these program automatically. - if (isSharedVariant) { + if (isShared) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) { // set the tag to the default material name diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index eb578be3a3a7..5dd55e733ec8 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -156,6 +156,13 @@ class FMaterial : public Material { std::unique_lock lock(mActiveProgramsLock); mActivePrograms.set(variant.key); lock.unlock(); + + if (isSharedVariant(variant)) { + FMaterial const* const pDefaultMaterial = mEngine.getDefaultMaterial(); + if (pDefaultMaterial && pDefaultMaterial->mCachedPrograms[variant.key]) { + return pDefaultMaterial->getProgram(variant); + } + } #endif assert_invariant(mCachedPrograms[variant.key]); return mCachedPrograms[variant.key]; @@ -290,6 +297,11 @@ class FMaterial : public Material { void createAndCacheProgram(backend::Program&& p, Variant variant) const noexcept; + inline bool isSharedVariant(Variant variant) const { + return (mMaterialDomain == MaterialDomain::SURFACE) && !mIsDefaultMaterial && + !mHasCustomDepthShader && Variant::isValidDepthVariant(variant); + } + // try to order by frequency of use mutable std::array, VARIANT_COUNT> mCachedPrograms; DescriptorSetLayout mPerViewDescriptorSetLayout; diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index 96c9538620e7..803cf00fba9f 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -193,8 +193,12 @@ DebugServer::addMaterial(const CString& name, const void* data, size_t size, voi return {}; } - const uint32_t seed = 42; - const MaterialKey key = utils::hash::murmurSlow((const uint8_t*) data, size, seed); + // Note that it's possible to have two materials with the exact same content (however wasteful), + // but they refer to different instantiation of FMaterial. Hence we hash on userdata and the + // material data. + constexpr uint32_t seed = 42; + uint64_t dataSpace[2] = {(uint64_t) data, (uint64_t) userdata}; + uint32_t const key = utils::hash::murmur3((const uint32_t*) dataSpace, sizeof(dataSpace), seed); // Retain a copy of the package to permit queries after the client application has // freed up the original material package. diff --git a/libs/matdbg/web/app.js b/libs/matdbg/web/app.js index 4a7c7df4e444..cccec2b1b67b 100644 --- a/libs/matdbg/web/app.js +++ b/libs/matdbg/web/app.js @@ -662,8 +662,8 @@ class MaterialSidePanel extends LitElement { let name = material.name || kUntitledPlaceholder; if (name in duplicatedLabels) { const index = duplicatedLabels[name]; - name = `${name} (${index})`; duplicatedLabels[name] = index + 1; + name = `${name} (${index})`; } return { matid: matid,