Skip to content

Commit

Permalink
gh-59: setup texture manager for basic management of texture assets
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorOrachyov committed Aug 3, 2024
1 parent 5d857d4 commit 4362a0c
Show file tree
Hide file tree
Showing 26 changed files with 700 additions and 189 deletions.
4 changes: 2 additions & 2 deletions engine/plugins/freetype/freetype_asset_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

#include "freetype_asset_loader.hpp"

#include "freetype_font.hpp"
#include "freetype_import_data.hpp"
#include "grc/font.hpp"
#include "profiler/profiler.hpp"
Expand Down Expand Up @@ -57,7 +56,8 @@ namespace wmoge {
asset->set_name(name);
asset->set_import_data(meta.import_data);

return FreetypeFont::load(font, import_data->source_files[0].file, import_data->height, import_data->glyphs_in_row);
FreetypeFont loader;
return loader.load(font, import_data->source_files[0].file, import_data->height, import_data->glyphs_in_row);
}

}// namespace wmoge
1 change: 1 addition & 0 deletions engine/plugins/freetype/freetype_asset_loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#pragma once

#include "asset/asset_loader.hpp"
#include "freetype_font.hpp"

namespace wmoge {

Expand Down
27 changes: 18 additions & 9 deletions engine/plugins/freetype/freetype_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,26 @@
#include "grc/texture.hpp"
#include "platform/file_system.hpp"
#include "profiler/profiler.hpp"
#include "system/engine.hpp"
#include "system/ioc_container.hpp"

#include <freetype/freetype.h>

namespace wmoge {

FreetypeFont::FreetypeFont() {
m_gfx_driver = IocContainer::iresolve_v<GfxDriver>();
m_file_system = IocContainer::iresolve_v<FileSystem>();
m_texture_manager = IocContainer::iresolve_v<TextureManager>();
}

Status FreetypeFont::load(const Ref<Font>& font, const std::string& path, int height, int glyphs_in_row) {
WG_AUTO_PROFILE_ASSET("FreetypeFont::load");

static const int GLYPHS_SIZE_SHIFT = 6;
static const int GLYPHS_BITMAP_OFFSET = 2;

std::vector<std::uint8_t> ttf_data;
if (!Engine::instance()->file_system()->read_file(path, ttf_data)) {
if (!m_file_system->read_file(path, ttf_data)) {
WG_LOG_ERROR("failed to load font data from asset pak " << path);
return StatusCode::FailedRead;
}
Expand Down Expand Up @@ -153,15 +159,21 @@ namespace wmoge {
sampler_desc.brd_clr = GfxSampBrdClr::Black;
sampler_desc.mag_flt = GfxSampFlt::Linear;
sampler_desc.min_flt = GfxSampFlt::LinearMipmapLinear;
sampler_desc.max_anisotropy = Engine::instance()->gfx_driver()->device_caps().max_anisotropy;
sampler_desc.max_anisotropy = m_gfx_driver->device_caps().max_anisotropy;
sampler_desc.u = GfxSampAddress::ClampToBorder;
sampler_desc.v = GfxSampAddress::ClampToBorder;

TexCompressionParams compression_params{};
compression_params.format = TexCompressionFormat::BC4;

font_desc.texture = make_ref<Texture2d>(GfxFormat::R8, bitmap_width, bitmap_height, GfxTexSwizz::RRRRtoRGBA);
font_desc.texture->set_name(SID(font->get_name().str() + "_texture"));
TextureFlags flags;
flags.set(TextureFlag::Pooled);
flags.set(TextureFlag::FromDisk);
flags.set(TextureFlag::Font);
flags.set(TextureFlag::Compressed);

font_desc.texture = m_texture_manager->create_2d(flags, GfxFormat::R8, bitmap_width, bitmap_height, GfxTexSwizz::RRRRtoRGBA);
font_desc.texture->set_name(SID(font->get_name().str() + "_bitmap"));
font_desc.texture->set_sampler_from_desc(sampler_desc);
font_desc.texture->set_compression(compression_params);
font_desc.texture->set_source_images({bitmap});
Expand All @@ -174,10 +186,7 @@ namespace wmoge {
WG_LOG_ERROR("failed to compress font texture " << font->get_name());
return StatusCode::Error;
}
if (!font_desc.texture->generate_gfx_resource()) {
WG_LOG_ERROR("failed to create gfx font texture " << font->get_name());
return StatusCode::Error;
}
m_texture_manager->init(font_desc.texture.get());

return font->init(font_desc);
}
Expand Down
12 changes: 11 additions & 1 deletion engine/plugins/freetype/freetype_font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

#include "core/status.hpp"
#include "core/string_utils.hpp"
#include "gfx/gfx_driver.hpp"
#include "grc/font.hpp"
#include "grc/texture_manager.hpp"
#include "platform/file_system.hpp"

namespace wmoge {

Expand All @@ -39,6 +42,8 @@ namespace wmoge {
*/
class FreetypeFont {
public:
FreetypeFont();

/**
* @brief Loads font from a .ttf file from file system using specified height in pixels
*
Expand All @@ -51,7 +56,12 @@ namespace wmoge {
*
* @return True if font loaded
*/
static Status load(const Ref<Font>& font, const std::string& path, int height = 40, int glyphs_in_row = 16);
Status load(const Ref<Font>& font, const std::string& path, int height = 40, int glyphs_in_row = 16);

private:
GfxDriver* m_gfx_driver;
FileSystem* m_file_system;
TextureManager* m_texture_manager;
};

}// namespace wmoge
48 changes: 30 additions & 18 deletions engine/plugins/runtime/asset/texture_asset_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
#include "gfx/gfx_driver.hpp"
#include "grc/image.hpp"
#include "grc/texture.hpp"
#include "grc/texture_manager.hpp"
#include "grc/texture_resize.hpp"
#include "profiler/profiler.hpp"
#include "system/engine.hpp"
#include "system/ioc_container.hpp"

namespace wmoge {

Expand Down Expand Up @@ -63,13 +65,21 @@ namespace wmoge {
return StatusCode::FailedResize;
}

Ref<Texture2d> texture = make_ref<Texture2d>(
import_data->format,
source_image->get_width(),
source_image->get_height());
auto texture_manager = IocContainer::iresolve_v<TextureManager>();

TextureFlags flags;
flags.set(TextureFlag::Pooled);
flags.set(TextureFlag::FromDisk);
flags.set(TextureFlag::Compressed, import_data->compression.format != TexCompressionFormat::Unknown);

Ref<Texture2d> texture =
texture_manager->create_2d(flags,
import_data->format,
source_image->get_width(),
source_image->get_height());

if (!texture) {
WG_LOG_ERROR("Failed to instantiate texture " << name);
WG_LOG_ERROR("failed to instantiate texture " << name);
return StatusCode::FailedInstantiate;
}

Expand All @@ -93,10 +103,7 @@ namespace wmoge {
return StatusCode::Error;
}
}
if (!texture->generate_gfx_resource()) {
WG_LOG_ERROR("failed create gfx asset for " << name);
return StatusCode::Error;
}
texture_manager->init(texture.get());

return WG_OK;
}
Expand Down Expand Up @@ -144,13 +151,21 @@ namespace wmoge {
}
}

Ref<TextureCube> texture = make_ref<TextureCube>(
import_data->format,
source_images.front()->get_width(),
source_images.front()->get_height());
auto texture_manager = IocContainer::iresolve_v<TextureManager>();

TextureFlags flags;
flags.set(TextureFlag::Pooled);
flags.set(TextureFlag::FromDisk);
flags.set(TextureFlag::Compressed, import_data->compression.format != TexCompressionFormat::Unknown);

Ref<TextureCube> texture =
texture_manager->create_cube(flags,
import_data->format,
source_images.front()->get_width(),
source_images.front()->get_height());

if (!texture) {
WG_LOG_ERROR("Failed to instantiate texture " << name);
WG_LOG_ERROR("failed to instantiate texture " << name);
return StatusCode::Error;
}

Expand All @@ -174,10 +189,7 @@ namespace wmoge {
return StatusCode::Error;
}
}
if (!texture->generate_gfx_resource()) {
WG_LOG_ERROR("failed create gfx asset for " << name);
return StatusCode::Error;
}
texture_manager->init(texture.get());

return WG_OK;
}
Expand Down
1 change: 1 addition & 0 deletions engine/runtime/asset/_rtti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace wmoge {
rtti_type<AssetMetaFile>();
rtti_type<AssetMeta>();
rtti_type<AssetLoader>();
rtti_type<AssetUnloader>();
rtti_type<Asset>();
}

Expand Down
2 changes: 1 addition & 1 deletion engine/runtime/asset/asset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace wmoge {
* @class Asset
* @brief Base class for any engine asset
*/
class Asset : public WeakRefCnt<RttiObject> {
class Asset : public WeakRefCnt<Asset, RttiObject> {
public:
WG_RTTI_CLASS(Asset, RttiObject);

Expand Down
21 changes: 20 additions & 1 deletion engine/runtime/asset/asset_loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,26 @@ namespace wmoge {

WG_RTTI_CLASS_BEGIN(AssetLoader) {
WG_RTTI_META_DATA(RttiUiHint("Interface for an asset loader to implement custom loading"));
// WG_RTTI_METHOD(load, {"name", "meta", "asset"}, {RttiUiHint("Instantiates and loads a particular asset type from meta info")});
}
WG_RTTI_END;

/**
* @class AssetUnloader
* @brief Class responsible for unloading assets(s) of a specific type
*/
class AssetUnloader : public RttiObject {
public:
WG_RTTI_CLASS(AssetUnloader, RttiObject);

AssetUnloader() = default;
virtual ~AssetUnloader() = default;

virtual Status unload(Asset* asset) { return StatusCode::NotImplemented; }
virtual RttiClass* get_asset_type() { return nullptr; }
};

WG_RTTI_CLASS_BEGIN(AssetUnloader) {
WG_RTTI_META_DATA(RttiUiHint("Interface for an asset unloader to implement custom unloading"));
}
WG_RTTI_END;

Expand Down
50 changes: 36 additions & 14 deletions engine/runtime/asset/asset_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ namespace wmoge {
m_file_system = IocContainer::iresolve_v<FileSystem>();
m_type_storage = IocContainer::iresolve_v<RttiTypeStorage>();
m_event_manager = IocContainer::iresolve_v<EventManager>();

m_callback = std::make_shared<typename Asset::ReleaseCallback>([this](Asset* asset) {
std::lock_guard guard(m_mutex);

auto* rtti = asset->get_class();
auto unloader = find_unloader(rtti);
auto& id = asset->get_id();

if (unloader) {
(*unloader)->unload(asset);
}

m_assets.erase(id);
});
}

AsyncResult<Ref<Asset>> AssetManager::load_async(const AssetId& name, AssetCallback callback) {
Expand Down Expand Up @@ -113,6 +127,7 @@ namespace wmoge {
m_event_manager->dispatch(event);

std::lock_guard guard(m_mutex);
asset->set_release_callback(m_callback);
m_assets[name] = WeakRef<Asset>(asset);
async_op->set_result(std::move(asset));
return 0;
Expand Down Expand Up @@ -180,6 +195,11 @@ namespace wmoge {
m_loaders[loader->get_class_name()] = std::move(loader);
}

void AssetManager::add_unloader(Ref<AssetUnloader> unloader) {
std::lock_guard guard(m_mutex);
m_unloaders[unloader->get_asset_type()] = std::move(unloader);
}

void AssetManager::add_pak(std::shared_ptr<AssetPak> pak) {
std::lock_guard guard(m_mutex);
m_paks.push_back(std::move(pak));
Expand All @@ -191,6 +211,12 @@ namespace wmoge {
return query != m_loaders.end() ? std::make_optional(query->second.get()) : std::nullopt;
}

std::optional<AssetUnloader*> AssetManager::find_unloader(RttiClass* rtti) {
std::lock_guard guard(m_mutex);
auto query = m_unloaders.find(rtti);
return query != m_unloaders.end() ? std::make_optional(query->second.get()) : std::nullopt;
}

std::optional<AssetMeta> AssetManager::find_meta(const AssetId& asset) {
std::lock_guard guard(m_mutex);

Expand All @@ -215,20 +241,6 @@ namespace wmoge {
return std::nullopt;
}

void AssetManager::gc() {
WG_AUTO_PROFILE_ASSET("AssetManager::gc");

std::lock_guard guard(m_mutex);
int evicted = 0;
for (auto iter = m_assets.begin(); iter != m_assets.end(); ++iter) {
if (iter->second.acquire()->refs_count() == 1) {
iter = m_assets.erase(iter);
evicted += 1;
}
}
WG_LOG_INFO("gc " << evicted << " unreferenced assets");
}

void AssetManager::clear() {
WG_AUTO_PROFILE_ASSET("AssetManager::clear");

Expand All @@ -249,6 +261,16 @@ namespace wmoge {
add_loader(loader->instantiate().cast<AssetLoader>());
}

std::vector<RttiClass*> unloaders = m_type_storage->find_classes([](const Ref<RttiClass>& type) {
return type->is_subtype_of(AssetUnloader::get_class_static()) && type->can_instantiate();
});

for (auto& unloader : unloaders) {
assert(unloader);
assert(unloader->can_instantiate());
add_unloader(unloader->instantiate().cast<AssetUnloader>());
}

add_pak(std::make_shared<AssetPakFileSystem>());
}

Expand Down
Loading

0 comments on commit 4362a0c

Please sign in to comment.