#pragma once #include #include #include #include #include #include namespace mln { namespace gfx { class Context; class Texture2D; class UploadPass; using Texture2DPtr = std::shared_ptr; class TextureHandle { public: TextureHandle(const mapbox::Bin& bin) : id(bin.id), rectangle(bin.x, bin.y, bin.w, bin.h), needsUpload(bin.refcount() == 1) {}; ~TextureHandle() = default; int32_t getId() const { return id; } const Rect& getRectangle() const { return rectangle; } bool isUploadNeeded() const { return needsUpload; } bool operator==(const TextureHandle& other) const { return (id == other.id); } struct Hasher { size_t operator()(const TextureHandle& texHandle) const { return texHandle.id; } }; private: int32_t id = 0; Rect rectangle; bool needsUpload = false; friend class DynamicTexture; }; class DynamicTexture { public: DynamicTexture(Context& context, Size size, TexturePixelType pixelType); virtual ~DynamicTexture() = default; const Texture2DPtr& getTexture() const; TexturePixelType getPixelFormat() const; bool isEmpty() const; std::optional reserveSize(const Size& size, int32_t uniqueId); template std::optional addImage(const Image& image, int32_t uniqueId = -1) { return addImage(image.data ? image.data.get() : nullptr, image.size, uniqueId); } std::optional addImage(const uint8_t* pixelData, const Size& imageSize, int32_t uniqueId = -1); virtual void uploadImage(const uint8_t* pixelData, TextureHandle& texHandle); virtual void uploadDeferredImages(UploadPass&) {}; virtual bool removeTexture(const TextureHandle& texHandle); protected: DynamicTexture(Size size, TexturePixelType pixelType); mapbox::ShelfPack shelfPack; Texture2DPtr texture; TexturePixelType pixelFormat; int numTextures = 0; std::mutex mutex; }; } // namespace gfx } // namespace mln