The backend-specific parts are now handled by AsyncTransfer.
-#include <msp/datafile/rawdata.h>
#include <msp/gl/extensions/arb_direct_state_access.h>
#include <msp/gl/extensions/arb_texture_storage.h>
#include <msp/gl/extensions/arb_vertex_buffer_object.h>
-#include <msp/graphics/imageloader.h>
#include "buffer.h"
#include "gl.h"
#include "texture2d.h"
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)
{ }
}
}
-Resource::AsyncLoader *OpenGLTexture2D::load(IO::Seekable &io, const Resources *)
-{
- return new AsyncLoader(static_cast<Texture2D &>(*this), io);
-}
-
uint64_t OpenGLTexture2D::get_data_size() const
{
if(!id)
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
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();
};
blit.dstOffsets[1] = { static_cast<int>(dst_size.x), static_cast<int>(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;
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();
};
+#include <msp/datafile/rawdata.h>
+#include <msp/graphics/imageloader.h>
#include "error.h"
#include "texture2d.h"
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);
return LinAl::Vector<unsigned, 2>(w, h);
}
+Resource::AsyncLoader *Texture2D::load(IO::Seekable &io, const Resources *)
+{
+ return new AsyncLoader(static_cast<Texture2D &>(*this), io);
+}
+
Texture2D::Loader::Loader(Texture2D &t):
DataFile::DerivedObjectLoader<Texture2D, Texture::Loader>(t)
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
};
private:
+ class AsyncLoader;
+
unsigned width = 0;
unsigned height = 0;
private:
unsigned get_n_levels() const;
LinAl::Vector<unsigned, 2> get_level_size(unsigned) const;
+
+public:
+ virtual Resource::AsyncLoader *load(IO::Seekable &, const Resources * = 0);
};
} // namespace GL