#include "Rendering/Internal/RenderPipelineFactory.h" #include #include #include "Rendering/Execution/DirectionalShadowExecutionState.h" #include "Rendering/Pipelines/BuiltinForwardPipeline.h" #include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h" #include "Rendering/Pipelines/ScriptableRenderPipelineHost.h" #include "Rendering/Passes/BuiltinDepthOnlyPass.h" #include "Rendering/Passes/BuiltinObjectIdPass.h" #include "Rendering/Passes/BuiltinShadowCasterPass.h" #include #include #include namespace XCEngine { namespace Rendering { namespace Internal { namespace { std::shared_ptr CreateBuiltinForwardPipelineRendererAsset() { static const std::shared_ptr s_builtinForwardPipelineAsset = std::make_shared(); return s_builtinForwardPipelineAsset; } std::unique_ptr CreateBuiltinDepthOnlyStandalonePass() { return std::make_unique(); } std::unique_ptr CreateBuiltinObjectIdStandalonePass() { return std::make_unique(); } std::unique_ptr CreateBuiltinShadowCasterStandalonePass() { return std::make_unique(); } using PipelineRendererAssetRegistry = std::unordered_map; using CameraFrameStandalonePassRegistry = std::unordered_map; using CameraFramePlanPolicyRegistry = std::unordered_map; using DirectionalShadowExecutionPolicyRegistry = std::unordered_map; PipelineRendererAssetRegistry& GetPipelineRendererAssetRegistry() { static PipelineRendererAssetRegistry registry = {}; return registry; } CameraFrameStandalonePassRegistry& GetCameraFrameStandalonePassRegistry() { static CameraFrameStandalonePassRegistry registry = {}; return registry; } CameraFramePlanPolicyRegistry& GetCameraFramePlanPolicyRegistry() { static CameraFramePlanPolicyRegistry registry = {}; return registry; } DirectionalShadowExecutionPolicyRegistry& GetDirectionalShadowExecutionPolicyRegistry() { static DirectionalShadowExecutionPolicyRegistry registry = {}; return registry; } std::unordered_set& GetBuiltinPipelineRendererAssetKeys() { static std::unordered_set builtinKeys = {}; return builtinKeys; } std::unordered_set& GetBuiltinCameraFrameStandalonePassKeys() { static std::unordered_set builtinKeys = {}; return builtinKeys; } std::unordered_set& GetBuiltinCameraFramePlanPolicyKeys() { static std::unordered_set builtinKeys = {}; return builtinKeys; } std::unordered_set& GetBuiltinDirectionalShadowExecutionPolicyKeys() { static std::unordered_set builtinKeys = {}; return builtinKeys; } std::mutex& GetPipelineRendererAssetRegistryMutex() { static std::mutex mutex; return mutex; } std::mutex& GetCameraFrameStandalonePassRegistryMutex() { static std::mutex mutex; return mutex; } std::mutex& GetCameraFramePlanPolicyRegistryMutex() { static std::mutex mutex; return mutex; } std::mutex& GetDirectionalShadowExecutionPolicyRegistryMutex() { static std::mutex mutex; return mutex; } void EnsureBuiltinPipelineRendererAssetRegistryInitialized() { static const bool initialized = []() { PipelineRendererAssetRegistry& registry = GetPipelineRendererAssetRegistry(); registry.emplace( "BuiltinForward", &CreateBuiltinForwardPipelineRendererAsset); GetBuiltinPipelineRendererAssetKeys().insert("BuiltinForward"); return true; }(); (void)initialized; } void EnsureBuiltinCameraFrameStandalonePassRegistryInitialized() { static const bool initialized = []() { CameraFrameStandalonePassRegistry& registry = GetCameraFrameStandalonePassRegistry(); registry.emplace( "BuiltinDepthOnly", &CreateBuiltinDepthOnlyStandalonePass); registry.emplace( "BuiltinObjectId", &CreateBuiltinObjectIdStandalonePass); registry.emplace( "BuiltinShadowCaster", &CreateBuiltinShadowCasterStandalonePass); std::unordered_set& builtinKeys = GetBuiltinCameraFrameStandalonePassKeys(); builtinKeys.insert("BuiltinDepthOnly"); builtinKeys.insert("BuiltinObjectId"); builtinKeys.insert("BuiltinShadowCaster"); return true; }(); (void)initialized; } void EnsureBuiltinCameraFramePlanPolicyRegistryInitialized() { static const bool initialized = []() { CameraFramePlanPolicyRegistry& registry = GetCameraFramePlanPolicyRegistry(); registry.emplace( "BuiltinDefaultCameraFramePlan", [](CameraFramePlan& plan, const FinalColorSettings& defaultFinalColorSettings) { ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy( plan, defaultFinalColorSettings); }); GetBuiltinCameraFramePlanPolicyKeys().insert( "BuiltinDefaultCameraFramePlan"); return true; }(); (void)initialized; } void EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized() { static const bool initialized = []() { DirectionalShadowExecutionPolicyRegistry& registry = GetDirectionalShadowExecutionPolicyRegistry(); registry.emplace( "BuiltinDirectionalShadow", [](const CameraFramePlan& plan, const DirectionalShadowSurfaceAllocation& shadowAllocation, DirectionalShadowExecutionState& shadowState) { ApplyDefaultRenderPipelineDirectionalShadowExecutionPolicy( plan, shadowAllocation, shadowState); return shadowState.shadowCasterRequest.IsValid() && shadowState.shadowData.IsValid(); }); GetBuiltinDirectionalShadowExecutionPolicyKeys().insert( "BuiltinDirectionalShadow"); return true; }(); (void)initialized; } std::unique_ptr TryCreateNativeSceneRendererFromAsset( const std::shared_ptr& asset) { if (asset == nullptr) { return nullptr; } std::unique_ptr pipeline = asset->CreatePipeline(); if (pipeline == nullptr) { return nullptr; } NativeSceneRenderer* const sceneRenderer = dynamic_cast(pipeline.get()); if (sceneRenderer == nullptr) { return nullptr; } (void)pipeline.release(); return std::unique_ptr(sceneRenderer); } } // namespace std::shared_ptr CreateConfiguredRenderPipelineAsset() { return Pipelines::CreateConfiguredManagedRenderPipelineAsset(); } std::shared_ptr CreateFallbackRenderPipelineAsset() { return std::make_shared(); } bool RegisterPipelineRendererAssetFactory( const std::string& key, PipelineRendererAssetFactory factory) { if (key.empty() || !factory) { return false; } EnsureBuiltinPipelineRendererAssetRegistryInitialized(); std::lock_guard lock( GetPipelineRendererAssetRegistryMutex()); PipelineRendererAssetRegistry& registry = GetPipelineRendererAssetRegistry(); if (registry.find(key) != registry.end()) { return false; } registry.emplace(key, std::move(factory)); return true; } bool UnregisterPipelineRendererAssetFactory(const std::string& key) { if (key.empty()) { return false; } EnsureBuiltinPipelineRendererAssetRegistryInitialized(); std::lock_guard lock( GetPipelineRendererAssetRegistryMutex()); if (GetBuiltinPipelineRendererAssetKeys().find(key) != GetBuiltinPipelineRendererAssetKeys().end()) { return false; } PipelineRendererAssetRegistry& registry = GetPipelineRendererAssetRegistry(); return registry.erase(key) != 0u; } std::shared_ptr CreatePipelineRendererAssetByKey( const std::string& key) { if (key.empty()) { return nullptr; } EnsureBuiltinPipelineRendererAssetRegistryInitialized(); std::lock_guard lock( GetPipelineRendererAssetRegistryMutex()); const PipelineRendererAssetRegistry& registry = GetPipelineRendererAssetRegistry(); const auto it = registry.find(key); if (it == registry.end() || !it->second) { return nullptr; } return it->second(); } bool RegisterCameraFrameStandalonePassFactory( const std::string& key, CameraFrameStandalonePassFactory factory) { if (key.empty() || !factory) { return false; } EnsureBuiltinCameraFrameStandalonePassRegistryInitialized(); std::lock_guard lock( GetCameraFrameStandalonePassRegistryMutex()); CameraFrameStandalonePassRegistry& registry = GetCameraFrameStandalonePassRegistry(); if (registry.find(key) != registry.end()) { return false; } registry.emplace(key, std::move(factory)); return true; } bool UnregisterCameraFrameStandalonePassFactory( const std::string& key) { if (key.empty()) { return false; } EnsureBuiltinCameraFrameStandalonePassRegistryInitialized(); std::lock_guard lock( GetCameraFrameStandalonePassRegistryMutex()); if (GetBuiltinCameraFrameStandalonePassKeys().find(key) != GetBuiltinCameraFrameStandalonePassKeys().end()) { return false; } CameraFrameStandalonePassRegistry& registry = GetCameraFrameStandalonePassRegistry(); return registry.erase(key) != 0u; } std::unique_ptr CreateCameraFrameStandalonePassByKey( const std::string& key) { if (key.empty()) { return nullptr; } EnsureBuiltinCameraFrameStandalonePassRegistryInitialized(); std::lock_guard lock( GetCameraFrameStandalonePassRegistryMutex()); const CameraFrameStandalonePassRegistry& registry = GetCameraFrameStandalonePassRegistry(); const auto it = registry.find(key); if (it == registry.end() || !it->second) { return nullptr; } return it->second(); } bool RegisterCameraFramePlanPolicy( const std::string& key, CameraFramePlanPolicy policy) { if (key.empty() || !policy) { return false; } EnsureBuiltinCameraFramePlanPolicyRegistryInitialized(); std::lock_guard lock( GetCameraFramePlanPolicyRegistryMutex()); CameraFramePlanPolicyRegistry& registry = GetCameraFramePlanPolicyRegistry(); if (registry.find(key) != registry.end()) { return false; } registry.emplace(key, std::move(policy)); return true; } bool UnregisterCameraFramePlanPolicy( const std::string& key) { if (key.empty()) { return false; } EnsureBuiltinCameraFramePlanPolicyRegistryInitialized(); std::lock_guard lock( GetCameraFramePlanPolicyRegistryMutex()); if (GetBuiltinCameraFramePlanPolicyKeys().find(key) != GetBuiltinCameraFramePlanPolicyKeys().end()) { return false; } CameraFramePlanPolicyRegistry& registry = GetCameraFramePlanPolicyRegistry(); return registry.erase(key) != 0u; } bool ApplyCameraFramePlanPolicyByKey( const std::string& key, CameraFramePlan& plan, const FinalColorSettings& defaultFinalColorSettings) { if (key.empty()) { return false; } EnsureBuiltinCameraFramePlanPolicyRegistryInitialized(); std::lock_guard lock( GetCameraFramePlanPolicyRegistryMutex()); const CameraFramePlanPolicyRegistry& registry = GetCameraFramePlanPolicyRegistry(); const auto it = registry.find(key); if (it == registry.end() || !it->second) { return false; } it->second( plan, defaultFinalColorSettings); return true; } bool RegisterDirectionalShadowExecutionPolicy( const std::string& key, DirectionalShadowExecutionPolicy policy) { if (key.empty() || !policy) { return false; } EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized(); std::lock_guard lock( GetDirectionalShadowExecutionPolicyRegistryMutex()); DirectionalShadowExecutionPolicyRegistry& registry = GetDirectionalShadowExecutionPolicyRegistry(); if (registry.find(key) != registry.end()) { return false; } registry.emplace(key, std::move(policy)); return true; } bool UnregisterDirectionalShadowExecutionPolicy( const std::string& key) { if (key.empty()) { return false; } EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized(); std::lock_guard lock( GetDirectionalShadowExecutionPolicyRegistryMutex()); if (GetBuiltinDirectionalShadowExecutionPolicyKeys().find(key) != GetBuiltinDirectionalShadowExecutionPolicyKeys().end()) { return false; } DirectionalShadowExecutionPolicyRegistry& registry = GetDirectionalShadowExecutionPolicyRegistry(); return registry.erase(key) != 0u; } bool ConfigureDirectionalShadowExecutionStateByKey( const std::string& key, const CameraFramePlan& plan, const DirectionalShadowSurfaceAllocation& shadowAllocation, DirectionalShadowExecutionState& shadowState) { if (key.empty()) { return false; } EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized(); std::lock_guard lock( GetDirectionalShadowExecutionPolicyRegistryMutex()); const DirectionalShadowExecutionPolicyRegistry& registry = GetDirectionalShadowExecutionPolicyRegistry(); const auto it = registry.find(key); if (it == registry.end() || !it->second) { return false; } return it->second( plan, shadowAllocation, shadowState); } std::shared_ptr ResolveRenderPipelineAssetOrDefault( std::shared_ptr preferredAsset) { if (preferredAsset != nullptr) { return std::move(preferredAsset); } if (std::shared_ptr configuredAsset = CreateConfiguredRenderPipelineAsset(); configuredAsset != nullptr) { return configuredAsset; } return CreateFallbackRenderPipelineAsset(); } std::unique_ptr CreateRenderPipelineOrDefault( const std::shared_ptr& preferredAsset, std::shared_ptr* outResolvedAsset) { const std::shared_ptr resolvedAsset = ResolveRenderPipelineAssetOrDefault(preferredAsset); if (resolvedAsset != nullptr) { if (std::unique_ptr pipeline = resolvedAsset->CreatePipeline()) { if (outResolvedAsset != nullptr) { *outResolvedAsset = resolvedAsset; } return pipeline; } } const std::shared_ptr defaultAsset = ResolveRenderPipelineAssetOrDefault(nullptr); if (defaultAsset != nullptr && defaultAsset != resolvedAsset) { if (std::unique_ptr pipeline = defaultAsset->CreatePipeline()) { if (outResolvedAsset != nullptr) { *outResolvedAsset = defaultAsset; } return pipeline; } } const std::shared_ptr fallbackAsset = CreateFallbackRenderPipelineAsset(); if (fallbackAsset != nullptr && fallbackAsset != resolvedAsset && fallbackAsset != defaultAsset) { if (std::unique_ptr pipeline = fallbackAsset->CreatePipeline()) { if (outResolvedAsset != nullptr) { *outResolvedAsset = fallbackAsset; } return pipeline; } } if (outResolvedAsset != nullptr) { *outResolvedAsset = fallbackAsset != nullptr ? fallbackAsset : (defaultAsset != nullptr ? defaultAsset : resolvedAsset); } return std::make_unique(); } std::unique_ptr CreateNativeSceneRendererFromAsset( const std::shared_ptr& preferredAsset, std::shared_ptr* outResolvedAsset) { if (std::unique_ptr sceneRenderer = TryCreateNativeSceneRendererFromAsset(preferredAsset)) { if (outResolvedAsset != nullptr) { *outResolvedAsset = preferredAsset; } return sceneRenderer; } if (outResolvedAsset != nullptr) { outResolvedAsset->reset(); } return CreateDefaultNativeSceneRenderer(); } std::unique_ptr CreateDefaultNativeSceneRenderer() { return std::make_unique(); } } // namespace Internal } // namespace Rendering } // namespace XCEngine