From 225dbd7ba2dde73bb28e54e03ae960e88e708f57 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 28 Dec 2021 16:09:59 +0200 Subject: [PATCH] Move Texture2D::AsyncLoader back to the common part The backend-specific parts are now handled by AsyncTransfer. --- source/backends/opengl/texture2d_backend.cpp | 99 -------------------- source/backends/opengl/texture2d_backend.h | 3 - source/backends/vulkan/texture2d_backend.cpp | 5 - source/backends/vulkan/texture2d_backend.h | 1 - source/core/texture2d.cpp | 99 ++++++++++++++++++++ source/core/texture2d.h | 5 + 6 files changed, 104 insertions(+), 108 deletions(-) diff --git a/source/backends/opengl/texture2d_backend.cpp b/source/backends/opengl/texture2d_backend.cpp index 187d1693..a4e3cad6 100644 --- a/source/backends/opengl/texture2d_backend.cpp +++ b/source/backends/opengl/texture2d_backend.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include #include "buffer.h" #include "gl.h" #include "texture2d.h" @@ -13,27 +11,6 @@ using namespace std; namespace Msp { namespace GL { -class OpenGLTexture2D::AsyncLoader: public Resource::AsyncLoader -{ -private: - Texture2D &texture; - IO::Seekable &io; - Texture2D::AsyncTransfer transfer; - Graphics::Image image; - Graphics::ImageLoader *img_loader = 0; - DataFile::RawData *raw_data = 0; - unsigned n_bytes = 0; - int phase = 0; - -public: - AsyncLoader(Texture2D &, IO::Seekable &); - ~AsyncLoader(); - - virtual bool needs_sync() const; - virtual bool process(); -}; - - OpenGLTexture2D::OpenGLTexture2D(): Texture(GL_TEXTURE_2D) { } @@ -85,11 +62,6 @@ void OpenGLTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsig } } -Resource::AsyncLoader *OpenGLTexture2D::load(IO::Seekable &io, const Resources *) -{ - return new AsyncLoader(static_cast(*this), io); -} - uint64_t OpenGLTexture2D::get_data_size() const { if(!id) @@ -151,76 +123,5 @@ void OpenGLTexture2D::AsyncTransfer::finalize() glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } - -OpenGLTexture2D::AsyncLoader::AsyncLoader(Texture2D &t, IO::Seekable &i): - texture(t), - io(i) -{ - char magic[4] = { }; - io.read(magic, 4); - io.seek(0, IO::S_BEG); - - if(DataFile::RawData::detect_signature(string(magic, 4))) - { - raw_data = new DataFile::RawData; - raw_data->open_io(io, "async"); - } - else - img_loader = Graphics::ImageLoader::open_io(io); -} - -OpenGLTexture2D::AsyncLoader::~AsyncLoader() -{ - delete img_loader; - delete raw_data; -} - -bool OpenGLTexture2D::AsyncLoader::needs_sync() const -{ - return phase%2; -} - -bool OpenGLTexture2D::AsyncLoader::process() -{ - if(phase==0) - { - if(raw_data) - n_bytes = raw_data->get_size(); - else - { - image.load_headers(*img_loader); - n_bytes = image.get_stride()*image.get_height(); - } - } - else if(phase==1) - { - if(img_loader) - { - unsigned w = image.get_width(); - unsigned h = image.get_height(); - texture.storage(pixelformat_from_image(image, texture.use_srgb_format), w, h); - } - - transfer = texture.sub_image_async(0, 0, 0, texture.width, texture.height); - } - else if(phase==2) - { - if(raw_data) - raw_data->load_into(transfer.get_address()); - else - image.load_into(*img_loader, transfer.get_address()); - } - else if(phase==3) - { - transfer = Texture2D::AsyncTransfer(); - - if(texture.auto_gen_mipmap) - texture.generate_mipmap(); - } - - ++phase; - return phase>3; -} - } // namespace GL } // namespace Msp diff --git a/source/backends/opengl/texture2d_backend.h b/source/backends/opengl/texture2d_backend.h index f9b5abfe..9d469f2b 100644 --- a/source/backends/opengl/texture2d_backend.h +++ b/source/backends/opengl/texture2d_backend.h @@ -25,15 +25,12 @@ protected: void finalize(); }; - class AsyncLoader; - OpenGLTexture2D(); void allocate(); void sub_image(unsigned, int, int, unsigned, unsigned, const void *); public: - virtual Resource::AsyncLoader *load(IO::Seekable &, const Resources * = 0); virtual std::size_t get_data_size() const; virtual void unload(); }; diff --git a/source/backends/vulkan/texture2d_backend.cpp b/source/backends/vulkan/texture2d_backend.cpp index 7c6b55f1..1ab49b88 100644 --- a/source/backends/vulkan/texture2d_backend.cpp +++ b/source/backends/vulkan/texture2d_backend.cpp @@ -40,11 +40,6 @@ void VulkanTexture2D::fill_mipmap_blit(unsigned level, void *b) blit.dstOffsets[1] = { static_cast(dst_size.x), static_cast(dst_size.y), 1 }; } -Resource::AsyncLoader *VulkanTexture2D::load(IO::Seekable &, const Resources *) -{ - throw logic_error("Texture2D::load is unimplemented"); -} - uint64_t VulkanTexture2D::get_data_size() const { return 0; diff --git a/source/backends/vulkan/texture2d_backend.h b/source/backends/vulkan/texture2d_backend.h index 7686a9e0..139f8bef 100644 --- a/source/backends/vulkan/texture2d_backend.h +++ b/source/backends/vulkan/texture2d_backend.h @@ -27,7 +27,6 @@ protected: virtual void fill_mipmap_blit(unsigned, void *); public: - virtual Resource::AsyncLoader *load(IO::Seekable &, const Resources * = 0); virtual std::size_t get_data_size() const; virtual void unload(); }; diff --git a/source/core/texture2d.cpp b/source/core/texture2d.cpp index 74071535..a0ba9515 100644 --- a/source/core/texture2d.cpp +++ b/source/core/texture2d.cpp @@ -1,3 +1,5 @@ +#include +#include #include "error.h" #include "texture2d.h" @@ -6,6 +8,27 @@ using namespace std; namespace Msp { namespace GL { +class Texture2D::AsyncLoader: public Resource::AsyncLoader +{ +private: + Texture2D &texture; + IO::Seekable &io; + Texture2D::AsyncTransfer transfer; + Graphics::Image image; + Graphics::ImageLoader *img_loader = 0; + DataFile::RawData *raw_data = 0; + unsigned n_bytes = 0; + int phase = 0; + +public: + AsyncLoader(Texture2D &, IO::Seekable &); + ~AsyncLoader(); + + virtual bool needs_sync() const; + virtual bool process(); +}; + + Texture2D::~Texture2D() { set_manager(0); @@ -72,6 +95,11 @@ LinAl::Vector Texture2D::get_level_size(unsigned level) const return LinAl::Vector(w, h); } +Resource::AsyncLoader *Texture2D::load(IO::Seekable &io, const Resources *) +{ + return new AsyncLoader(static_cast(*this), io); +} + Texture2D::Loader::Loader(Texture2D &t): DataFile::DerivedObjectLoader(t) @@ -156,5 +184,76 @@ Texture2D::AsyncTransfer::~AsyncTransfer() finalize(); } + +Texture2D::AsyncLoader::AsyncLoader(Texture2D &t, IO::Seekable &i): + texture(t), + io(i) +{ + char magic[4] = { }; + io.read(magic, 4); + io.seek(0, IO::S_BEG); + + if(DataFile::RawData::detect_signature(string(magic, 4))) + { + raw_data = new DataFile::RawData; + raw_data->open_io(io, "async"); + } + else + img_loader = Graphics::ImageLoader::open_io(io); +} + +Texture2D::AsyncLoader::~AsyncLoader() +{ + delete img_loader; + delete raw_data; +} + +bool Texture2D::AsyncLoader::needs_sync() const +{ + return phase%2; +} + +bool Texture2D::AsyncLoader::process() +{ + if(phase==0) + { + if(raw_data) + n_bytes = raw_data->get_size(); + else + { + image.load_headers(*img_loader); + n_bytes = image.get_stride()*image.get_height(); + } + } + else if(phase==1) + { + if(img_loader) + { + unsigned w = image.get_width(); + unsigned h = image.get_height(); + texture.storage(pixelformat_from_image(image, texture.use_srgb_format), w, h); + } + + transfer = texture.sub_image_async(0, 0, 0, texture.width, texture.height); + } + else if(phase==2) + { + if(raw_data) + raw_data->load_into(transfer.get_address()); + else + image.load_into(*img_loader, transfer.get_address()); + } + else if(phase==3) + { + transfer = Texture2D::AsyncTransfer(); + + if(texture.auto_gen_mipmap) + texture.generate_mipmap(); + } + + ++phase; + return phase>3; +} + } // namespace GL } // namespace Msp diff --git a/source/core/texture2d.h b/source/core/texture2d.h index 02cdade5..b13b8b3c 100644 --- a/source/core/texture2d.h +++ b/source/core/texture2d.h @@ -61,6 +61,8 @@ public: }; private: + class AsyncLoader; + unsigned width = 0; unsigned height = 0; @@ -91,6 +93,9 @@ public: private: unsigned get_n_levels() const; LinAl::Vector get_level_size(unsigned) const; + +public: + virtual Resource::AsyncLoader *load(IO::Seekable &, const Resources * = 0); }; } // namespace GL -- 2.45.2