mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
125 lines
3.4 KiB
C++
125 lines
3.4 KiB
C++
// Copyright 2025 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "VideoCommon/Resources/CustomResourceManager.h"
|
|
|
|
#include "VideoCommon/VideoEvents.h"
|
|
|
|
namespace VideoCommon
|
|
{
|
|
void CustomResourceManager::Initialize()
|
|
{
|
|
m_asset_cache.Initialize();
|
|
|
|
m_xfb_event =
|
|
AfterFrameEvent::Register([this](Core::System&) { XFBTriggered(); }, "CustomResourceManager");
|
|
}
|
|
|
|
void CustomResourceManager::Shutdown()
|
|
{
|
|
m_asset_cache.Shutdown();
|
|
Reset();
|
|
}
|
|
|
|
void CustomResourceManager::Reset()
|
|
{
|
|
m_texture_data_resources.clear();
|
|
|
|
m_asset_cache.Reset();
|
|
}
|
|
|
|
void CustomResourceManager::MarkAssetDirty(const CustomAssetLibrary::AssetID& asset_id)
|
|
{
|
|
m_asset_cache.MarkAssetDirty(asset_id);
|
|
}
|
|
|
|
void CustomResourceManager::XFBTriggered()
|
|
{
|
|
m_asset_cache.Update();
|
|
}
|
|
|
|
TextureDataResource* CustomResourceManager::GetTextureDataFromAsset(
|
|
const CustomAssetLibrary::AssetID& asset_id,
|
|
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
|
{
|
|
const auto [it, added] = m_texture_data_resources.try_emplace(asset_id, nullptr);
|
|
if (added)
|
|
{
|
|
it->second = std::make_unique<TextureDataResource>(CreateResourceContext(asset_id, library));
|
|
}
|
|
ProcessResource(it->second.get());
|
|
return it->second.get();
|
|
}
|
|
|
|
Resource::ResourceContext CustomResourceManager::CreateResourceContext(
|
|
const CustomAssetLibrary::AssetID& asset_id,
|
|
const std::shared_ptr<VideoCommon::CustomAssetLibrary>& library)
|
|
{
|
|
return Resource::ResourceContext{asset_id, library, &m_asset_cache, this};
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// Early out if we're already at our end state
|
|
if (resource->GetState() == Resource::State::DataAvailable)
|
|
return;
|
|
|
|
ProcessResourceState(resource);
|
|
}
|
|
|
|
void CustomResourceManager::ProcessResourceState(Resource* resource)
|
|
{
|
|
Resource::State next_state = resource->GetState();
|
|
Resource::TaskComplete task_complete = Resource::TaskComplete::No;
|
|
switch (resource->GetState())
|
|
{
|
|
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;
|
|
};
|
|
|
|
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
|