diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index aa6f07465b5..dbb4339f465 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -815,10 +815,7 @@ void FMaterial::applyPendingEdits() noexcept { const char* name = mName.c_str(); slog.d << "Applying edits to " << (name ? name : "(untitled)") << io::endl; destroyPrograms(mEngine); // FIXME: this will not destroy the shared variants - - std::unique_ptr pending{ mPendingEdits }; - std::swap(pending, mMaterialParser); - mPendingEdits = nullptr; + latchPendingEdits(); } /** @@ -837,7 +834,7 @@ void FMaterial::onEditCallback(void* userdata, const utils::CString&, const void // and swapping out the MaterialParser until the next getProgram call. std::unique_ptr pending = createParser( engine.getBackend(), engine.getShaderLanguage(), packageData, packageSize); - material->mPendingEdits = pending.release(); + material->setPendingEdits(std::move(pending)); } void FMaterial::onQueryCallback(void* userdata, VariantList* pVariants) { diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index 5a50def58c2..2a2819df6a7 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -219,7 +219,7 @@ class FMaterial : public Material { static void onQueryCallback(void* userdata, VariantList* pActiveVariants); void checkProgramEdits() noexcept { - if (UTILS_UNLIKELY(mPendingEdits.load())) { + if (UTILS_UNLIKELY(hasPendingEdits())) { applyPendingEdits(); } } @@ -302,8 +302,21 @@ class FMaterial : public Material { matdbg::MaterialKey mDebuggerId; mutable utils::Mutex mActiveProgramsLock; mutable VariantList mActivePrograms; - // FIXME: multi-threaded access to mPendingEdits is very broken - std::atomic mPendingEdits = {}; + mutable utils::Mutex mPendingEditsLock; + std::unique_ptr mPendingEdits; + void setPendingEdits(std::unique_ptr pendingEdits) noexcept { + std::lock_guard lock(mPendingEditsLock); + std::swap(pendingEdits, mPendingEdits); + } + bool hasPendingEdits() noexcept { + std::lock_guard lock(mPendingEditsLock); + return (bool)mPendingEdits; + } + void latchPendingEdits() noexcept { + std::lock_guard lock(mPendingEditsLock); + std::swap(mPendingEdits, mMaterialParser); + } + #endif utils::CString mName;