From 0803987df3c52f815015995a263543a3f0a38f87 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Tue, 19 Nov 2024 15:38:28 -0800 Subject: [PATCH 1/7] samples: clean-up automation objects in gltf-viewer (#8285) --- samples/gltf_viewer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp index 77aee4743f5a..47d6055dd3a9 100644 --- a/samples/gltf_viewer.cpp +++ b/samples/gltf_viewer.cpp @@ -1043,6 +1043,8 @@ int main(int argc, char** argv) { delete app.resourceLoader; delete app.stbDecoder; delete app.ktxDecoder; + delete app.automationSpec; + delete app.automationEngine; AssetLoader::destroy(&app.assetLoader); }; From 98585bdc30641383bef64233c534efa35affb224 Mon Sep 17 00:00:00 2001 From: Doris Wu Date: Tue, 19 Nov 2024 18:00:54 +0800 Subject: [PATCH 2/7] Disable transparent picking by default --- filament/src/details/View.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filament/src/details/View.h b/filament/src/details/View.h index e8ffafd0f9be..1f41bab82350 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -534,7 +534,7 @@ class FView : public View { Viewport mViewport; bool mCulling = true; bool mFrontFaceWindingInverted = false; - bool mIsTransparentPickingEnabled = true; + bool mIsTransparentPickingEnabled = false; FRenderTarget* mRenderTarget = nullptr; From 64eb27af8a042fef120c9d3142e3396276d07171 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 19 Nov 2024 22:38:30 -0800 Subject: [PATCH 3/7] fix a HwProgram leak related to depth variant pre-caching (#8276) * fix a HwProgram leak related to depth variant pre-caching Materials that don't use a custom depth can share the same program for all depth variants. We take advantage of that by pre-caching the depths variants when a program is loaded. The depth variants themselves are owned by the default material which is created first. When a material is destroyed it skips deletion of those variants which will be truly destroyed when the default material is destroyed. Unfortunately, the default material doesn't contain all depth variants, in particular, it doesn't have the VSM ones (because it's an unlit material). On top of that, the way it pre-cached depth variant had a bug that made it miss some picking variants. Because of that, these variants were skipped during material destruction but never actually destroyed, since the default material didn't know anything about them. This PR fixes this by making the pre-caching completely lazy. When any material needs such a "precacheable" variant, it first checks if the default material has it. If not, it creates the variant, caches it locally and forwards it to the default material, which implicitly becomes the owner. Just like before newly created material precache everything the default material already has. With this mechanism, it's impossible to have a depth variant without it also existing in the default material. This also simplify the non-public invalidate() method, which doesn't need to populate the pre-cached programs, since this will happen naturally when needed. There was also another issue where post-process materials were handled like regular materials. This didn't cause an problem but was inefficient since these only have a handful of variants. * Update filament/src/details/Material.cpp Co-authored-by: Powei Feng --------- Co-authored-by: Powei Feng --- filament/src/details/Engine.cpp | 25 +- filament/src/details/Material.cpp | 216 +++++++++++------- filament/src/details/Material.h | 7 +- .../include/private/filament/Variant.h | 3 + libs/filabridge/src/Variant.cpp | 44 +++- 5 files changed, 198 insertions(+), 97 deletions(-) diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 6b4e56a1e42e..a9c39de272df 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -529,19 +529,31 @@ void FEngine::shutdown() { mPerViewDescriptorSetLayoutSsrVariant.terminate(mHwDescriptorSetLayoutFactory, driver); mPerRenderableDescriptorSetLayout.terminate(mHwDescriptorSetLayoutFactory, driver); - driver.destroyRenderPrimitive(mFullScreenTriangleRph); + driver.destroyRenderPrimitive(std::move(mFullScreenTriangleRph)); destroy(mFullScreenTriangleIb); + mFullScreenTriangleIb = nullptr; + destroy(mFullScreenTriangleVb); + mFullScreenTriangleVb = nullptr; + destroy(mDummyMorphTargetBuffer); + mDummyMorphTargetBuffer = nullptr; + destroy(mDefaultIblTexture); + mDefaultIblTexture = nullptr; + destroy(mDefaultIbl); + mDefaultIbl = nullptr; destroy(mDefaultColorGrading); + mDefaultColorGrading = nullptr; destroy(mDefaultMaterial); + mDefaultMaterial = nullptr; destroy(mUnprotectedDummySwapchain); + mUnprotectedDummySwapchain = nullptr; /* * clean-up after the user -- we call terminate on each "leaked" object and clear each list. @@ -558,6 +570,7 @@ void FEngine::shutdown() { // this must be done after Skyboxes and before materials destroy(mSkyboxMaterial); + mSkyboxMaterial = nullptr; cleanupResourceList(std::move(mBufferObjects)); cleanupResourceList(std::move(mIndexBuffers)); @@ -574,12 +587,12 @@ void FEngine::shutdown() { cleanupResourceListLocked(mFenceListLock, std::move(mFences)); - driver.destroyTexture(mDummyOneTexture); - driver.destroyTexture(mDummyOneTextureArray); - driver.destroyTexture(mDummyZeroTexture); - driver.destroyTexture(mDummyZeroTextureArray); + driver.destroyTexture(std::move(mDummyOneTexture)); + driver.destroyTexture(std::move(mDummyOneTextureArray)); + driver.destroyTexture(std::move(mDummyZeroTexture)); + driver.destroyTexture(std::move(mDummyZeroTextureArray)); - driver.destroyRenderTarget(mDefaultRenderTarget); + driver.destroyRenderTarget(std::move(mDefaultRenderTarget)); /* * Shutdown the backend... diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index 6f39b217732c..c5d6b83f42ec 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -321,11 +321,7 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder, parser->getSpecularAntiAliasingThreshold(&mSpecularAntiAliasingThreshold); } - processBlendingMode(parser); - processSpecializationConstants(engine, builder, parser); - processPushConstants(engine, parser); - processDepthVariants(engine, parser); - processDescriptorSets(engine, parser); + parser->hasCustomDepthShader(&mHasCustomDepthShader); mPerViewLayoutIndex = ColorPassDescriptorSet::getIndex( mIsVariantLit, @@ -333,6 +329,12 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder, mRefractionMode == RefractionMode::SCREEN_SPACE, !(mVariantFilterMask & +UserVariantFilterBit::FOG)); + processBlendingMode(parser); + processSpecializationConstants(engine, builder, parser); + processPushConstants(engine, parser); + processDescriptorSets(engine, parser); + precacheDepthVariants(engine); + #if FILAMENT_ENABLE_MATDBG // Register the material with matdbg. matdbg::DebugServer* server = downcast(engine).debug.server; @@ -346,47 +348,21 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder, FMaterial::~FMaterial() noexcept = default; void FMaterial::invalidate(Variant::type_t variantMask, Variant::type_t variantValue) noexcept { - DriverApi& driverApi = mEngine.getDriverApi(); - if (mMaterialDomain == MaterialDomain::SURFACE) { - auto& cachedPrograms = mCachedPrograms; - for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) { - Variant const variant(k); - if ((k & variantMask) == variantValue) { - if (UTILS_LIKELY(!mIsDefaultMaterial)) { - // The depth variants may be shared with the default material, in which case - // we should not free it now. - bool const isSharedVariant = - Variant::isValidDepthVariant(variant) && !mHasCustomDepthShader; - if (isSharedVariant) { - // we don't own this variant, skip. - continue; - } - } - driverApi.destroyProgram(cachedPrograms[k]); - cachedPrograms[k].clear(); - } - } - - if (UTILS_UNLIKELY(!mIsDefaultMaterial && !mHasCustomDepthShader)) { - FMaterial const* const pDefaultMaterial = mEngine.getDefaultMaterial(); - for (Variant const variant: pDefaultMaterial->mDepthVariants) { - pDefaultMaterial->prepareProgram(variant); - if (!cachedPrograms[variant.key]) { - cachedPrograms[variant.key] = pDefaultMaterial->getProgram(variant); - } - } - } - } else if (mMaterialDomain == MaterialDomain::POST_PROCESS) { - auto& cachedPrograms = mCachedPrograms; - for (size_t k = 0, n = POST_PROCESS_VARIANT_COUNT; k < n; ++k) { - if ((k & variantMask) == variantValue) { - driverApi.destroyProgram(cachedPrograms[k]); - cachedPrograms[k].clear(); - } + // Note: This API is not public at the moment, so it's okay to have some debugging logs + // and extra checks. + if (mMaterialDomain == MaterialDomain::SURFACE && + !mIsDefaultMaterial && + !mHasCustomDepthShader) { + // it would be unsafe to invalidate any of the cached depth variant + if (UTILS_UNLIKELY(!((variantMask & Variant::DEP) && !(variantValue & Variant::DEP)))) { + slog.w << io::hex << "FMaterial::invalidate(" + << +variantMask << ", " << +variantValue + << ") would corrupt the depth variant cache" << io::endl; } - } else if (mMaterialDomain == MaterialDomain::COMPUTE) { - // TODO: handle compute variants if any + variantMask |= Variant::DEP; + variantValue &= ~Variant::DEP; } + destroyPrograms(mEngine, variantMask, variantValue); } void FMaterial::terminate(FEngine& engine) { @@ -626,10 +602,41 @@ Program FMaterial::getProgramWithVariants( } void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexcept { - auto program = mEngine.getDriverApi().createProgram(std::move(p)); - mEngine.getDriverApi().setDebugTag(program.getId(), mName); + FEngine const& engine = mEngine; + DriverApi& driverApi = mEngine.getDriverApi(); + + // Check if the default material has this program cached + if (mMaterialDomain == MaterialDomain::SURFACE && + !mIsDefaultMaterial && !mHasCustomDepthShader && + Variant::isValidDepthVariant(variant)) { + FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); + if (pDefaultMaterial) { + auto program = pDefaultMaterial->mCachedPrograms[variant.key]; + if (program) { + mCachedPrograms[variant.key] = program; + return; + } + } + } + + auto program = driverApi.createProgram(std::move(p)); + driverApi.setDebugTag(program.getId(), mName); assert_invariant(program); mCachedPrograms[variant.key] = program; + + // 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 (mMaterialDomain == MaterialDomain::SURFACE && + !mIsDefaultMaterial && !mHasCustomDepthShader && + Variant::isValidDepthVariant(variant)) { + FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); + if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) { + // set the tag to the default material name + driverApi.setDebugTag(program.getId(), mName); + pDefaultMaterial->mCachedPrograms[variant.key] = program; + } + } } size_t FMaterial::getParameters(ParameterInfo* parameters, size_t count) const noexcept { @@ -734,22 +741,76 @@ void FMaterial::onQueryCallback(void* userdata, VariantList* pVariants) { #endif // FILAMENT_ENABLE_MATDBG -void FMaterial::destroyPrograms(FEngine& engine) { +void FMaterial::destroyPrograms(FEngine& engine, + Variant::type_t const variantMask, Variant::type_t const variantValue) { + DriverApi& driverApi = engine.getDriverApi(); auto& cachedPrograms = mCachedPrograms; - for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) { - const Variant variant(k); - if (!mIsDefaultMaterial) { - // The depth variants may be shared with the default material, in which case - // we should not free it now. - bool const isSharedVariant = Variant::isValidDepthVariant(variant) && !mHasCustomDepthShader; - if (isSharedVariant) { - // we don't own this variant, skip. - continue; + + switch (mMaterialDomain) { + case MaterialDomain::SURFACE: { + if (mIsDefaultMaterial || mHasCustomDepthShader) { + // default material or we have custom depth shaders, we destroy all variants + for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) { + if ((k & variantMask) == variantValue) { + // Only destroy if the handle is valid. Not strictly needed, but we have a lot + // of variants, and this generates traffic in the command queue. + if (cachedPrograms[k]) { + driverApi.destroyProgram(std::move(cachedPrograms[k])); + } + } + } + } else { + // The depth variants may be shared with the default material, in which case + // we should not free them now. + + // During Engine::shutdown(), auto-cleanup destroys the default material first, + // so this can be null, but this is only used for debugging. + UTILS_UNUSED_IN_RELEASE + auto UTILS_NULLABLE pDefaultMaterial = engine.getDefaultMaterial(); + + for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) { + if ((k & variantMask) == variantValue) { + // Only destroy if the handle is valid. Not strictly needed, but we have a lot + // of variant, and this generates traffic in the command queue. + if (cachedPrograms[k]) { + if (Variant::isValidDepthVariant(Variant(k))) { + // By construction this should always be true, because this + // field is populated only when a material creates the program + // for this variant. + // During Engine::shutdown, auto-cleanup destroys the + // default material first + assert_invariant(!pDefaultMaterial || + pDefaultMaterial->mCachedPrograms[k]); + // we don't own this variant, skip, but clear the entry. + cachedPrograms[k].clear(); + continue; + } + + driverApi.destroyProgram(std::move(cachedPrograms[k])); + } + } + } } + break; + } + case MaterialDomain::POST_PROCESS: { + for (size_t k = 0, n = POST_PROCESS_VARIANT_COUNT; k < n; ++k) { + if ((k & variantMask) == variantValue) { + // Only destroy if the handle is valid. Not strictly needed, but we have a lot + // of variant, and this generates traffic in the command queue. + if (cachedPrograms[k]) { + driverApi.destroyProgram(std::move(cachedPrograms[k])); + } + } + } + break; + } + case MaterialDomain::COMPUTE: { + // Compute programs don't have variants + driverApi.destroyProgram(std::move(cachedPrograms[0])); + break; } - driverApi.destroyProgram(cachedPrograms[k]); - cachedPrograms[k].clear(); } } @@ -1014,34 +1075,17 @@ void FMaterial::processPushConstants(FEngine& engine, MaterialParser const* pars }); } -void FMaterial::processDepthVariants(FEngine& engine, MaterialParser const* const parser) { - parser->hasCustomDepthShader(&mHasCustomDepthShader); - - if (UTILS_UNLIKELY(mIsDefaultMaterial)) { - assert_invariant(mMaterialDomain == MaterialDomain::SURFACE); - filaflat::MaterialChunk const& materialChunk{ parser->getMaterialChunk() }; - auto variants = FixedCapacityVector::with_capacity(materialChunk.getShaderCount()); - materialChunk.visitShaders([&variants]( - ShaderModel, Variant variant, ShaderStage) { - if (Variant::isValidDepthVariant(variant)) { - variants.push_back(variant); - } - }); - std::sort(variants.begin(), variants.end(), - [](Variant lhs, Variant rhs) { return lhs.key < rhs.key; }); - auto pos = std::unique(variants.begin(), variants.end()); - variants.resize(std::distance(variants.begin(), pos)); - std::swap(mDepthVariants, variants); - } - - if (mMaterialDomain == MaterialDomain::SURFACE) { - if (UTILS_UNLIKELY(!mIsDefaultMaterial && !mHasCustomDepthShader)) { - FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); - auto& cachedPrograms = mCachedPrograms; - for (Variant const variant: pDefaultMaterial->mDepthVariants) { - pDefaultMaterial->prepareProgram(variant); - cachedPrograms[variant.key] = pDefaultMaterial->getProgram(variant); - } +void FMaterial::precacheDepthVariants(FEngine& engine) { + // if possible pre-cache all depth variants from the default material + if (mMaterialDomain == MaterialDomain::SURFACE && + !mIsDefaultMaterial && + !mHasCustomDepthShader) { + FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); + assert_invariant(pDefaultMaterial); + auto const allDepthVariants = VariantUtils::getDepthVariants(); + for (auto const variant: allDepthVariants) { + assert_invariant(Variant::isValidDepthVariant(variant)); + mCachedPrograms[variant.key] = pDefaultMaterial->mCachedPrograms[variant.key]; } } } diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index ba19427f1cc4..eb578be3a3a7 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -218,7 +218,9 @@ class FMaterial : public Material { uint32_t generateMaterialInstanceId() const noexcept { return mMaterialInstanceId++; } - void destroyPrograms(FEngine& engine); + void destroyPrograms(FEngine& engine, + Variant::type_t variantMask = 0, + Variant::type_t variantValue = 0); // return the id of a specialization constant specified by name for this material std::optional getSpecializationConstantId(std::string_view name) const noexcept ; @@ -282,7 +284,7 @@ class FMaterial : public Material { void processPushConstants(FEngine& engine, MaterialParser const* parser); - void processDepthVariants(FEngine& engine, MaterialParser const* parser); + void precacheDepthVariants(FEngine& engine); void processDescriptorSets(FEngine& engine, MaterialParser const* parser); @@ -331,7 +333,6 @@ class FMaterial : public Material { SamplerInterfaceBlock mSamplerInterfaceBlock; BufferInterfaceBlock mUniformInterfaceBlock; SubpassInfo mSubpassInfo; - utils::FixedCapacityVector mDepthVariants; // only populated with default material using BindingUniformInfoContainer = utils::FixedCapacityVector>; diff --git a/libs/filabridge/include/private/filament/Variant.h b/libs/filabridge/include/private/filament/Variant.h index fc94dec7f6af..153ea33f69ef 100644 --- a/libs/filabridge/include/private/filament/Variant.h +++ b/libs/filabridge/include/private/filament/Variant.h @@ -19,6 +19,7 @@ #include +#include #include #include @@ -271,6 +272,8 @@ namespace VariantUtils { utils::Slice getLitVariants() noexcept UTILS_PURE; // list of unlit variants utils::Slice getUnlitVariants() noexcept UTILS_PURE; +// list of depth variants +utils::Slice getDepthVariants() noexcept UTILS_PURE; } } // namespace filament diff --git a/libs/filabridge/src/Variant.cpp b/libs/filabridge/src/Variant.cpp index ce0bcb6ee9a8..a515e83f370e 100644 --- a/libs/filabridge/src/Variant.cpp +++ b/libs/filabridge/src/Variant.cpp @@ -16,8 +16,15 @@ #include +#include + +#include + #include +#include +#include + namespace filament { Variant Variant::filterUserVariant( @@ -65,6 +72,8 @@ Variant Variant::filterUserVariant( namespace details { +namespace { + // Compile-time variant count for lit and unlit constexpr inline size_t variant_count(bool lit) noexcept { size_t count = 0; @@ -81,6 +90,17 @@ constexpr inline size_t variant_count(bool lit) noexcept { return count; } +constexpr inline size_t depth_variant_count() noexcept { + size_t count = 0; + for (size_t i = 0; i < VARIANT_COUNT; i++) { + Variant const variant(i); + if (Variant::isValidDepthVariant(variant)) { + count++; + } + } + return count; +} + // Compile-time variant list for lit and unlit template constexpr auto get_variants() noexcept { @@ -98,9 +118,18 @@ constexpr auto get_variants() noexcept { } return variants; } -static auto const gLitVariants{ details::get_variants() }; -static auto const gUnlitVariants{ details::get_variants() }; +constexpr auto get_depth_variants() noexcept { + std::array variants; + size_t count = 0; + for (size_t i = 0; i < VARIANT_COUNT; i++) { + Variant const variant(i); + if (Variant::isValidDepthVariant(variant)) { + variants[count++] = variant; + } + } + return variants; +} // Below are compile time sanity-check tests constexpr inline bool reserved_is_not_valid() noexcept { @@ -163,6 +192,13 @@ constexpr inline size_t fragment_variant_count() noexcept { return count; } +} // anonymous namespace + + +static auto const gLitVariants{ details::get_variants() }; +static auto const gUnlitVariants{ details::get_variants() }; +static auto const gDepthVariants{ details::get_depth_variants() }; + static_assert(reserved_is_not_valid()); static_assert(reserved_variant_count() == 160); static_assert(valid_variant_count() == 96); @@ -182,6 +218,10 @@ utils::Slice getUnlitVariants() noexcept { return { details::gUnlitVariants.data(), details::gUnlitVariants.size() }; } +utils::Slice getDepthVariants() noexcept { + return { details::gDepthVariants.data(), details::gDepthVariants.size() }; +} + }; // VariantUtils } // namespace filament From 16bab2479a1fa9c35364bdd37eee6d8f57110a2b Mon Sep 17 00:00:00 2001 From: Evan Mezeske Date: Mon, 25 Nov 2024 10:47:28 -0700 Subject: [PATCH 4/7] When applying animations, allow the time to be exactly equal to the duration before taking the fmod(), so that it is possible to animate to the exact last keyframe. Without this change, trying to animate to the last keyframe wraps back to the first, which only works for animations that loop. (#8287) --- libs/gltfio/src/Animator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gltfio/src/Animator.cpp b/libs/gltfio/src/Animator.cpp index 6e53b705c606..0d8b667644b1 100644 --- a/libs/gltfio/src/Animator.cpp +++ b/libs/gltfio/src/Animator.cpp @@ -264,7 +264,7 @@ size_t Animator::getAnimationCount() const { void Animator::applyAnimation(size_t animationIndex, float time) const { const Animation& anim = mImpl->animations[animationIndex]; - time = fmod(time, anim.duration); + time = time == anim.duration ? time : fmod(time, anim.duration); TransformManager& transformManager = *mImpl->transformManager; transformManager.openLocalTransformTransaction(); for (const auto& channel : anim.channels) { From 2381551ab904a21830b2464f80be53182bdcc048 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Mon, 25 Nov 2024 15:45:52 -0800 Subject: [PATCH 5/7] Release Filament 1.56.2 --- README.md | 4 ++-- RELEASE_NOTES.md | 3 +++ android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cbfa132634b9..0907d9794c27 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.56.1' + implementation 'com.google.android.filament:filament-android:1.56.2' } ``` @@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`: iOS projects can use CocoaPods to install the latest release: ```shell -pod 'Filament', '~> 1.56.1' +pod 'Filament', '~> 1.56.2' ``` ## Documentation diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 9f82faac507b..56727aa38e87 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,6 +7,9 @@ A new header is inserted each time a *tag* is created. Instead, if you are authoring a PR for the main branch, add your release note to [NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md). +## v1.56.3 + + ## v1.56.2 - vk: fix stage pool gc logic diff --git a/android/gradle.properties b/android/gradle.properties index c657979b6c3f..a478149a0ea0 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.56.1 +VERSION_NAME=1.56.2 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index 44fe59269553..0d57d4405a5f 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.56.1" + spec.version = "1.56.2" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.56.1/filament-v1.56.1-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.56.2/filament-v1.56.2-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index bbca1748ed75..8022284f92ca 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.56.1", + "version": "1.56.2", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From e2492dfde871edc6b5067b6b22f60321131dc9e0 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Mon, 25 Nov 2024 15:46:04 -0800 Subject: [PATCH 6/7] Bump version to 1.56.3 --- README.md | 4 ++-- android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0907d9794c27..5c04ba0bba93 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.56.2' + implementation 'com.google.android.filament:filament-android:1.56.3' } ``` @@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`: iOS projects can use CocoaPods to install the latest release: ```shell -pod 'Filament', '~> 1.56.2' +pod 'Filament', '~> 1.56.3' ``` ## Documentation diff --git a/android/gradle.properties b/android/gradle.properties index a478149a0ea0..ad8a89ce2cb7 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.56.2 +VERSION_NAME=1.56.3 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index 0d57d4405a5f..33fe0bf83649 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.56.2" + spec.version = "1.56.3" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.56.2/filament-v1.56.2-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.56.3/filament-v1.56.3-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index 8022284f92ca..dd5c85b6d95e 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.56.2", + "version": "1.56.3", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From 592c91f20effde3b906a58310951d6e74c322884 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 5 Dec 2024 13:18:20 -0800 Subject: [PATCH 7/7] pre-populate the default material's depth variants This restores the old behavior with depth variant caching. We pay the price at engine init time, instead of when the variant is needed the first time. We can revisit this later. Note that the default material doesn't have all possible depth variants (e.g. VSM), but that pre-caches the most popular ones. BUGS=[381946222] --- filament/src/details/Material.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index c5d6b83f42ec..5f641eb167f2 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -605,10 +605,13 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce FEngine const& engine = mEngine; DriverApi& driverApi = mEngine.getDriverApi(); - // Check if the default material has this program cached - if (mMaterialDomain == MaterialDomain::SURFACE && + bool const isSharedVariant = + (mMaterialDomain == MaterialDomain::SURFACE) && !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant)) { + Variant::isValidDepthVariant(variant); + + // Check if the default material has this program cached + if (isSharedVariant) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial) { auto program = pDefaultMaterial->mCachedPrograms[variant.key]; @@ -627,9 +630,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 (mMaterialDomain == MaterialDomain::SURFACE && - !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant)) { + if (isSharedVariant) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) { // set the tag to the default material name @@ -1076,6 +1077,21 @@ void FMaterial::processPushConstants(FEngine& engine, MaterialParser const* pars } void FMaterial::precacheDepthVariants(FEngine& engine) { + // pre-cache all depth variants inside the default material. Note that this should be + // entirely optional; if we remove this pre-caching, these variants will be populated + // later, when/if needed by createAndCacheProgram(). Doing it now potentially uses more + // memory and increases init time, but reduces hiccups during the first frame. + if (UTILS_UNLIKELY(mIsDefaultMaterial)) { + auto const allDepthVariants = VariantUtils::getDepthVariants(); + for (auto const variant: allDepthVariants) { + assert_invariant(Variant::isValidDepthVariant(variant)); + if (hasVariant(variant)) { + prepareProgram(variant); + } + } + return; + } + // if possible pre-cache all depth variants from the default material if (mMaterialDomain == MaterialDomain::SURFACE && !mIsDefaultMaterial &&