diff --git a/Source/Core/VideoCommon/Resources/CustomResourceManager.cpp b/Source/Core/VideoCommon/Resources/CustomResourceManager.cpp index 8148ccd899d..56556285d8f 100644 --- a/Source/Core/VideoCommon/Resources/CustomResourceManager.cpp +++ b/Source/Core/VideoCommon/Resources/CustomResourceManager.cpp @@ -3,8 +3,6 @@ #include "VideoCommon/Resources/CustomResourceManager.h" -#include "Common/Logging/Log.h" - #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/PipelineUtils.h" #include "VideoCommon/Resources/InvalidTextures.h" @@ -97,7 +95,7 @@ TextureDataResource* CustomResourceManager::GetTextureDataFromAsset( resource = std::make_unique(CreateResourceContext(asset_id, std::move(library))); } - ProcessResource(resource.get()); + resource->Process(); return resource.get(); } @@ -111,7 +109,7 @@ MaterialResource* CustomResourceManager::GetMaterialFromAsset( resource = std::make_unique( CreateResourceContext(asset_id, std::move(library)), pipeline_uid); } - ProcessResource(resource.get()); + resource->Process(); return resource.get(); } @@ -127,7 +125,7 @@ CustomResourceManager::GetShaderFromAsset(const CustomAssetLibrary::AssetID& ass resource = std::make_unique(CreateResourceContext(asset_id, std::move(library)), pipeline_uid, preprocessor_settings, m_host_config); } - ProcessResource(resource.get()); + resource->Process(); return resource.get(); } @@ -141,7 +139,7 @@ TextureAndSamplerResource* CustomResourceManager::GetTextureAndSamplerFromAsset( resource = std::make_unique( CreateResourceContext(asset_id, std::move(library))); } - ProcessResource(resource.get()); + resource->Process(); return resource.get(); } @@ -161,73 +159,4 @@ Resource::ResourceContext CustomResourceManager::CreateResourceContext( m_invalid_cubemap_texture.get(), m_invalid_transparent_texture.get()}; } - -void CustomResourceManager::ProcessResource(Resource* resource) -{ - resource->MarkAsActive(); - - const auto data_processed = resource->IsDataProcessed(); - if (data_processed == Resource::TaskComplete::Yes || - data_processed == Resource::TaskComplete::Error) - { - resource->MarkAsActive(); - if (data_processed == Resource::TaskComplete::Error) - return; - } - - ProcessResourceState(resource); -} - -void CustomResourceManager::ProcessResourceState(Resource* resource) -{ - const auto current_state = resource->GetState(); - Resource::State next_state = current_state; - Resource::TaskComplete task_complete = Resource::TaskComplete::No; - switch (current_state) - { - case Resource::State::ReloadData: - resource->ResetData(); - task_complete = Resource::TaskComplete::Yes; - next_state = Resource::State::CollectingPrimaryData; - break; - case Resource::State::CollectingPrimaryData: - task_complete = resource->CollectPrimaryData(); - next_state = Resource::State::CollectingDependencyData; - if (task_complete == Resource::TaskComplete::No) - resource->MarkAsPending(); - break; - case Resource::State::CollectingDependencyData: - task_complete = resource->CollectDependencyData(); - next_state = Resource::State::ProcessingData; - break; - case Resource::State::ProcessingData: - task_complete = resource->ProcessData(); - next_state = Resource::State::DataAvailable; - break; - case Resource::State::DataAvailable: - // Early out, we're already at our end state - return; - default: - ERROR_LOG_FMT(VIDEO, "Unknown resource state '{}' for resource '{}'", - static_cast(current_state), resource->m_resource_context.primary_asset_id); - return; - }; - - if (task_complete == Resource::TaskComplete::Yes) - { - resource->m_state = next_state; - if (next_state == Resource::State::DataAvailable) - { - resource->m_data_processed = task_complete; - } - else - { - ProcessResourceState(resource); - } - } - else if (task_complete == Resource::TaskComplete::Error) - { - resource->m_data_processed = task_complete; - } -} } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Resources/CustomResourceManager.h b/Source/Core/VideoCommon/Resources/CustomResourceManager.h index 538bec13f1c..04eaa469425 100644 --- a/Source/Core/VideoCommon/Resources/CustomResourceManager.h +++ b/Source/Core/VideoCommon/Resources/CustomResourceManager.h @@ -53,8 +53,6 @@ private: Resource::ResourceContext CreateResourceContext(const CustomAssetLibrary::AssetID& asset_id, std::shared_ptr library); - void ProcessResource(Resource* resource); - void ProcessResourceState(Resource* resource); CustomAssetCache m_asset_cache; TexturePool m_texture_pool; Common::AsyncWorkThreadSP m_worker_thread; diff --git a/Source/Core/VideoCommon/Resources/Resource.cpp b/Source/Core/VideoCommon/Resources/Resource.cpp index 52d1d8b01cb..b4376314db6 100644 --- a/Source/Core/VideoCommon/Resources/Resource.cpp +++ b/Source/Core/VideoCommon/Resources/Resource.cpp @@ -3,6 +3,8 @@ #include "VideoCommon/Resources/Resource.h" +#include "Common/Logging/Log.h" + namespace VideoCommon { Resource::Resource(ResourceContext resource_context) @@ -10,10 +12,78 @@ Resource::Resource(ResourceContext resource_context) { } +void Resource::Process() +{ + MarkAsActive(); + + if (m_data_processed == TaskComplete::Error) + return; + + ProcessCurrentTask(); +} + +void Resource::ProcessCurrentTask() +{ + Task next_task = m_current_task; + TaskComplete task_complete = TaskComplete::No; + switch (m_current_task) + { + case Task::ReloadData: + ResetData(); + task_complete = TaskComplete::Yes; + next_task = Task::CollectPrimaryData; + break; + case Task::CollectPrimaryData: + task_complete = CollectPrimaryData(); + next_task = Task::CollectDependencyData; + if (task_complete == TaskComplete::No) + MarkAsPending(); + break; + case Task::CollectDependencyData: + task_complete = CollectDependencyData(); + next_task = Task::ProcessData; + break; + case Task::ProcessData: + task_complete = ProcessData(); + next_task = Task::DataAvailable; + break; + case Task::DataAvailable: + // Early out, we're already at our end state + return; + default: + ERROR_LOG_FMT(VIDEO, "Unknown task '{}' for resource '{}'", static_cast(m_current_task), + m_resource_context.primary_asset_id); + return; + }; + + if (task_complete == Resource::TaskComplete::Yes) + { + m_current_task = next_task; + if (next_task == Resource::Task::DataAvailable) + { + m_data_processed = task_complete; + } + else + { + // No need to wait for the next resource request + // process the new task immediately + ProcessCurrentTask(); + } + } + else if (task_complete == Resource::TaskComplete::Error) + { + // If we failed our task due to an error, + // we can't service this resource request, + // wait for a reload and mark the whole + // data processing as an error + m_data_processed = task_complete; + } +} + void Resource::NotifyAssetChanged(bool has_error) { m_data_processed = has_error ? TaskComplete::Error : TaskComplete::No; - m_state = State::ReloadData; + m_current_task = Task::ReloadData; for (Resource* reference : m_references) { diff --git a/Source/Core/VideoCommon/Resources/Resource.h b/Source/Core/VideoCommon/Resources/Resource.h index 4bcec910c78..d53460004f0 100644 --- a/Source/Core/VideoCommon/Resources/Resource.h +++ b/Source/Core/VideoCommon/Resources/Resource.h @@ -49,17 +49,8 @@ public: Error, }; - enum class State - { - ReloadData, - CollectingPrimaryData, - CollectingDependencyData, - ProcessingData, - DataAvailable, - }; - + void Process(); TaskComplete IsDataProcessed() const { return m_data_processed; } - State GetState() const { return m_state; } void AddReference(Resource* reference); void RemoveReference(Resource* reference); @@ -71,6 +62,7 @@ protected: ResourceContext m_resource_context; private: + void ProcessCurrentTask(); void NotifyAssetChanged(bool has_error); void NotifyAssetUnloaded(); @@ -86,7 +78,16 @@ private: virtual TaskComplete ProcessData(); TaskComplete m_data_processed = TaskComplete::No; - State m_state = State::ReloadData; + + enum class Task + { + ReloadData, + CollectPrimaryData, + CollectDependencyData, + ProcessData, + DataAvailable, + }; + Task m_current_task = Task::ReloadData; std::unordered_set m_references; };