mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
VideoCommon: separate the concept of a 'resource' from an 'asset'. A resource is potentially multiple assets that are chained together but represent one type of data to the rest of the system. An example is a 'material'. A 'material' is a collection of textures, a custom shader, and some metadata that all comes together to form what the concept of the material is. There will be a 'material' resource. For now, start small by introducing the interface and change our texture loading which used assets from the old resource manager, to an actual resource.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
// 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
|
||||
Reference in New Issue
Block a user