diff --git a/filament/include/filament/MaterialInstance.h b/filament/include/filament/MaterialInstance.h index c50e15352d..82944e72aa 100644 --- a/filament/include/filament/MaterialInstance.h +++ b/filament/include/filament/MaterialInstance.h @@ -330,6 +330,43 @@ public: return getConstant(name, strlen(name)); } + using CompilerPriorityQueue = backend::CompilerPriorityQueue; + + /** + * Asynchronously ensures that a subset of this MaterialInstance's variants are compiled. + * + * This function behaves identically to Material::compile(), but takes into account the + * specific constants overridden by setConstant(). + * + * @param priority Which priority queue to use, LOW or HIGH. + * @param variants Variants to include to the compile command. + * @param handler Handler to dispatch the callback or nullptr for the default handler + * @param callback callback called on the main thread when the compilation is done on + * by backend. + * + * @see Material::compile + * @see setConstant + */ + void compile(CompilerPriorityQueue priority, + UserVariantFilterMask variants, + backend::CallbackHandler* UTILS_NULLABLE handler = nullptr, + utils::Invocable&& callback = {}) noexcept; + + inline void compile(CompilerPriorityQueue priority, + UserVariantFilterBit variants, + backend::CallbackHandler* UTILS_NULLABLE handler = nullptr, + utils::Invocable&& callback = {}) noexcept { + compile(priority, UserVariantFilterMask(variants), handler, + std::forward>(callback)); + } + + inline void compile(CompilerPriorityQueue priority, + backend::CallbackHandler* UTILS_NULLABLE handler = nullptr, + utils::Invocable&& callback = {}) noexcept { + compile(priority, UserVariantFilterBit::ALL, handler, + std::forward>(callback)); + } + /** * Set-up a custom scissor rectangle; by default it is disabled. * diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index a487a88cea..5bb4f2cb6d 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -235,11 +235,17 @@ filament::DescriptorSetLayout const& FMaterial::getPerViewDescriptorSetLayout( return mDefinition.perViewDescriptorSetLayoutPcf; } -void FMaterial::compile(CompilerPriorityQueue const priority, - UserVariantFilterMask variantSpec, - CallbackHandler* handler, - Invocable&& callback) noexcept { - getDefaultInstance()->compile(mEngine, priority, variantSpec, handler, std::move(callback)); +void FMaterial::compile(CompilerPriorityQueue const priority, UserVariantFilterMask variantSpec, + CallbackHandler* handler, Invocable&& callback) noexcept { + FMaterialInstance* mi = getDefaultInstance(); + if (callback) { + mi->compile(mEngine, priority, variantSpec, handler, + [this, callback = std::move(callback)](MaterialInstance*) { + callback(this); + }); + } else { + mi->compile(mEngine, priority, variantSpec, handler, {}); + } } FMaterialInstance* FMaterial::createInstance(const char* name) const noexcept { diff --git a/filament/src/details/MaterialInstance.cpp b/filament/src/details/MaterialInstance.cpp index a2af631fe1..7eb1dc68b2 100644 --- a/filament/src/details/MaterialInstance.cpp +++ b/filament/src/details/MaterialInstance.cpp @@ -448,8 +448,7 @@ const char* FMaterialInstance::getName() const noexcept { void FMaterialInstance::compile(FEngine& engine, CompilerPriorityQueue const priority, UserVariantFilterMask variantSpec, CallbackHandler* handler, - Invocable&& callback) noexcept { - + Invocable&& callback) noexcept { DriverApi& driver = engine.getDriverApi(); MaterialDefinition const& definition = mMaterial->getDefinition(); @@ -476,17 +475,15 @@ void FMaterialInstance::compile(FEngine& engine, CompilerPriorityQueue const pri if (callback) { struct Callback { - Invocable f; - Material* m; + Invocable f; + MaterialInstance* m; static void func(void* user) { auto* const c = static_cast(user); c->f(c->m); delete c; } }; - // TODO(exv): fix this const cast - auto* const user = new (std::nothrow) Callback{ std::move(callback), - const_cast(static_cast(mMaterial)) }; + auto* const user = new (std::nothrow) Callback{ std::move(callback), this }; driver.compilePrograms(priority, handler, &Callback::func, user); } else { driver.compilePrograms(priority, nullptr, nullptr, nullptr); diff --git a/filament/src/details/MaterialInstance.h b/filament/src/details/MaterialInstance.h index a47613f9fe..5a12ac0e07 100644 --- a/filament/src/details/MaterialInstance.h +++ b/filament/src/details/MaterialInstance.h @@ -86,7 +86,7 @@ public: void compile(FEngine& engine, backend::CompilerPriorityQueue priority, UserVariantFilterMask variantSpec, backend::CallbackHandler* handler, - utils::Invocable&& callback) noexcept; + utils::Invocable&& callback) noexcept; // prepareProgram creates the program for the material's given variant at the backend level. // Must be called outside of backend render pass.