texture cache refactor to later allow async loading
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
This commit is contained in:
parent
f2027befc8
commit
11ae259f67
2
external/solanaceae_util
vendored
2
external/solanaceae_util
vendored
@ -1 +1 @@
|
||||
Subproject commit 717748e8fc6ecd2170aa98ca442727fb1fe32834
|
||||
Subproject commit 85bbbb0e5a572b61067f3db188f3cfbda0948e7e
|
@ -71,27 +71,27 @@ std::optional<TextureEntry> BitsetImageLoader::haveToTexture(TextureUploaderI& t
|
||||
BitsetImageLoader::BitsetImageLoader(void) {
|
||||
}
|
||||
|
||||
std::optional<TextureEntry> BitsetImageLoader::load(TextureUploaderI& tu, ObjectHandle o) {
|
||||
TextureLoaderResult BitsetImageLoader::load(TextureUploaderI& tu, ObjectHandle o) {
|
||||
if (!static_cast<bool>(o)) {
|
||||
std::cerr << "BIL error: trying to load invalid object\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (!o.any_of<ObjComp::F::LocalHaveBitset, ObjComp::F::RemoteHaveBitset>()) {
|
||||
// after completion, this is called until the texture times out
|
||||
//std::cout << "BIL: no local have bitset\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (o.all_of<ObjComp::F::LocalHaveBitset>()) {
|
||||
auto& have = o.get<ObjComp::F::LocalHaveBitset>().have;
|
||||
assert(have.size_bits() > 0);
|
||||
return haveToTexture(tu, have, o);
|
||||
return {haveToTexture(tu, have, o)};
|
||||
} else if (o.all_of<ObjComp::F::RemoteHaveBitset>()) {
|
||||
auto& list = o.get<ObjComp::F::RemoteHaveBitset>().others;
|
||||
if (list.empty()) {
|
||||
std::cout << "BIL: remote set list empty\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
const auto& first_entry = list.begin()->second;
|
||||
|
||||
@ -115,10 +115,10 @@ std::optional<TextureEntry> BitsetImageLoader::load(TextureUploaderI& tu, Object
|
||||
}
|
||||
}
|
||||
|
||||
return haveToTexture(tu, _tmp_bitset, o);
|
||||
return {haveToTexture(tu, _tmp_bitset, o)};
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
std::optional<TextureEntry> BitsetImageLoader::load(TextureUploaderI& tu, ObjectContactSub ocs) {
|
||||
|
@ -30,7 +30,7 @@ class BitsetImageLoader {
|
||||
|
||||
public:
|
||||
BitsetImageLoader(void);
|
||||
std::optional<TextureEntry> load(TextureUploaderI& tu, ObjectHandle o);
|
||||
TextureLoaderResult load(TextureUploaderI& tu, ObjectHandle o);
|
||||
std::optional<TextureEntry> load(TextureUploaderI& tu, ObjectContactSub ocs);
|
||||
};
|
||||
|
||||
|
@ -30,29 +30,29 @@ MessageImageLoader::MessageImageLoader(void) {
|
||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
||||
}
|
||||
|
||||
std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
|
||||
TextureLoaderResult MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
|
||||
if (!static_cast<bool>(m)) {
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (m.all_of<Message::Components::TagNotImage>()) {
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (!m.all_of<Message::Components::MessageFileObject>()) {
|
||||
// not a file message
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
const auto& o = m.get<Message::Components::MessageFileObject>().o;
|
||||
|
||||
if (!static_cast<bool>(o)) {
|
||||
std::cerr << "MIL error: invalid object in file message\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (!o.all_of<ObjComp::Ephemeral::Backend, ObjComp::F::SingleInfo>()) {
|
||||
std::cerr << "MIL error: object missing backend (?)\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
// TODO: handle collections
|
||||
@ -60,40 +60,40 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
|
||||
|
||||
if (file_size > 50*1024*1024) {
|
||||
std::cerr << "MIL error: image file too large\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (file_size == 0) {
|
||||
std::cerr << "MIL warning: empty file\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (!o.all_of<ObjComp::F::TagLocalHaveAll>()) {
|
||||
// not ready yet
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
auto* file_backend = o.get<ObjComp::Ephemeral::Backend>().ptr;
|
||||
if (file_backend == nullptr) {
|
||||
std::cerr << "MIL error: object backend nullptr\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
auto file2 = file_backend->file2(o, StorageBackendI::FILE2_READ);
|
||||
if (!file2 || !file2->isGood() || !file2->can_read) {
|
||||
std::cerr << "MIL error: creating file2 from object via backendI\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
auto read_data = file2->read(file_size, 0);
|
||||
if (read_data.ptr == nullptr) {
|
||||
std::cerr << "MMIL error: reading from file2 returned nullptr\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (read_data.size != file_size) {
|
||||
std::cerr << "MIL error: reading from file2 size missmatch, should be " << file_size << ", is " << read_data.size << "\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
// try all loaders after another
|
||||
@ -107,7 +107,7 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
|
||||
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||
new_entry.current_texture = 0;
|
||||
for (const auto& [ms, data] : res.frames) {
|
||||
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
||||
const auto n_t = tu.upload(data.data(), res.width, res.height);
|
||||
new_entry.textures.push_back(n_t);
|
||||
new_entry.frame_duration.push_back(ms);
|
||||
}
|
||||
@ -117,10 +117,10 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
|
||||
|
||||
std::cout << "MIL: loaded image file o:" << /*file_path*/ entt::to_integral(o.entity()) << "\n";
|
||||
|
||||
return new_entry;
|
||||
return {new_entry};
|
||||
}
|
||||
|
||||
std::cerr << "MIL error: failed to load message (unhandled format)\n";
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,6 @@ class MessageImageLoader {
|
||||
|
||||
public:
|
||||
MessageImageLoader(void);
|
||||
std::optional<TextureEntry> load(TextureUploaderI& tu, Message3Handle m);
|
||||
TextureLoaderResult load(TextureUploaderI& tu, Message3Handle m);
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@ TextureEntry generateTestAnim(TextureUploaderI& tu) {
|
||||
}
|
||||
}
|
||||
|
||||
const auto n_t = tu.uploadRGBA(pixels.data(), width, height);
|
||||
const auto n_t = tu.upload(pixels.data(), width, height);
|
||||
|
||||
// this is so ugly
|
||||
new_entry.textures.emplace_back(n_t);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <entt/container/dense_set.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
struct TextureEntry {
|
||||
uint32_t width {0};
|
||||
@ -70,6 +71,11 @@ struct TextureEntry {
|
||||
}
|
||||
};
|
||||
|
||||
struct TextureLoaderResult {
|
||||
std::optional<TextureEntry> texture;
|
||||
bool keep_trying{false}; // if set, cant be cleared, as some async might be going on
|
||||
};
|
||||
|
||||
TextureEntry generateTestAnim(TextureUploaderI& tu);
|
||||
|
||||
// fwd
|
||||
@ -188,12 +194,12 @@ struct TextureCache {
|
||||
for (; it != _to_load.end(); it++) {
|
||||
if (_cache.count(*it)) {
|
||||
auto new_entry_opt = _l.load(_tu, *it);
|
||||
if (new_entry_opt.has_value()) {
|
||||
if (new_entry_opt.texture.has_value()) {
|
||||
auto old_entry = _cache.at(*it);
|
||||
for (const auto& tex_id : old_entry.textures) {
|
||||
_tu.destroy(tex_id);
|
||||
}
|
||||
auto [new_it, _] = _cache.insert_or_assign(*it, new_entry_opt.value());
|
||||
auto [new_it, _] = _cache.insert_or_assign(*it, new_entry_opt.texture.value());
|
||||
//new_it->second.current_texture = old_entry.current_texture; // ??
|
||||
new_it->second.rendered_this_frame = old_entry.rendered_this_frame;
|
||||
new_it->second.timestamp_last_rendered = old_entry.timestamp_last_rendered;
|
||||
@ -202,15 +208,21 @@ struct TextureCache {
|
||||
|
||||
// TODO: not a good idea?
|
||||
break; // end load from queue/onlyload 1 per update
|
||||
} else if (!new_entry_opt.keep_trying) {
|
||||
// failed to load and the loader is done
|
||||
it = _to_load.erase(it);
|
||||
}
|
||||
} else {
|
||||
auto new_entry_opt = _l.load(_tu, *it);
|
||||
if (new_entry_opt.has_value()) {
|
||||
_cache.emplace(*it, new_entry_opt.value());
|
||||
if (new_entry_opt.texture.has_value()) {
|
||||
_cache.emplace(*it, new_entry_opt.texture.value());
|
||||
it = _to_load.erase(it);
|
||||
|
||||
// TODO: not a good idea?
|
||||
break; // end load from queue/onlyload 1 per update
|
||||
} else if (!new_entry_opt.keep_trying) {
|
||||
// failed to load and the loader is done
|
||||
it = _to_load.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "./image_loader_qoi.hpp"
|
||||
#include "./image_loader_webp.hpp"
|
||||
#include "./image_loader_sdl_image.hpp"
|
||||
#include "texture_uploader.hpp"
|
||||
|
||||
#include <solanaceae/contact/components.hpp>
|
||||
#include <solanaceae/tox_contacts/components.hpp>
|
||||
@ -119,9 +120,9 @@ static std::vector<uint8_t> generateToxIdenticon(const ToxKey& key) {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
|
||||
TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
|
||||
if (!_cr.valid(c)) {
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
if (_cr.all_of<Contact::Components::AvatarMemory>(c)) {
|
||||
@ -134,13 +135,13 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
new_entry.width = a_m.width;
|
||||
new_entry.height = a_m.height;
|
||||
|
||||
const auto n_t = tu.uploadRGBA(a_m.data.data(), a_m.width, a_m.height);
|
||||
const auto n_t = tu.upload(a_m.data.data(), a_m.width, a_m.height);
|
||||
new_entry.textures.push_back(n_t);
|
||||
new_entry.frame_duration.push_back(250);
|
||||
|
||||
std::cout << "TAL: loaded memory buffer\n";
|
||||
|
||||
return new_entry;
|
||||
return {new_entry};
|
||||
}
|
||||
|
||||
if (_cr.all_of<Contact::Components::AvatarFile>(c)) {
|
||||
@ -169,7 +170,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||
new_entry.current_texture = 0;
|
||||
for (const auto& [ms, data] : res.frames) {
|
||||
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
||||
const auto n_t = tu.upload(data.data(), res.width, res.height);
|
||||
new_entry.textures.push_back(n_t);
|
||||
new_entry.frame_duration.push_back(ms);
|
||||
}
|
||||
@ -179,7 +180,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
|
||||
std::cout << "TAL: loaded image file " << a_f.file_path << "\n";
|
||||
|
||||
return new_entry;
|
||||
return {new_entry};
|
||||
}
|
||||
}
|
||||
} // continues if loading img fails
|
||||
@ -190,7 +191,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
Contact::Components::ToxGroupPeerPersistent,
|
||||
Contact::Components::ID
|
||||
>(c)) {
|
||||
return std::nullopt;
|
||||
return {std::nullopt};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> pixels;
|
||||
@ -212,7 +213,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||
new_entry.current_texture = 0;
|
||||
|
||||
const auto n_t = tu.uploadRGBA(pixels.data(), 5, 5, TextureUploaderI::NEAREST);
|
||||
const auto n_t = tu.upload(pixels.data(), 5, 5, TextureUploaderI::RGBA, TextureUploaderI::NEAREST);
|
||||
new_entry.textures.push_back(n_t);
|
||||
new_entry.frame_duration.push_back(250);
|
||||
|
||||
@ -221,6 +222,6 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
||||
|
||||
std::cout << "TAL: generated ToxIdenticon\n";
|
||||
|
||||
return new_entry;
|
||||
return {new_entry};
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,6 @@ class ToxAvatarLoader {
|
||||
|
||||
public:
|
||||
ToxAvatarLoader(Contact3Registry& cr);
|
||||
std::optional<TextureEntry> load(TextureUploaderI& tu, Contact3 c);
|
||||
TextureLoaderResult load(TextureUploaderI& tu, Contact3 c);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user