diff --git a/src/blitter/32bpp_anim_sse4.hpp b/src/blitter/32bpp_anim_sse4.hpp index b787c14e06..8217e7d805 100644 --- a/src/blitter/32bpp_anim_sse4.hpp +++ b/src/blitter/32bpp_anim_sse4.hpp @@ -39,7 +39,7 @@ public: template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override { + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override { return Blitter_32bppSSE_Base::Encode(sprite, allocator); } std::string_view GetName() override { return "32bpp-sse4-anim"; } diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index 943e9a0297..848bb7e9c7 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -285,7 +285,7 @@ void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, this->Draw(bp, mode, zoom); } -template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { /* streams of pixels (a, r, g, b channels) * @@ -414,7 +414,7 @@ template Sprite *Blitter_32bppOptimized::EncodeInternal(const len += lengths[z][0] + lengths[z][1]; } - Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len); + Sprite *dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + sizeof(SpriteData) + len); dest_sprite->height = sprite[ZOOM_LVL_MIN].height; dest_sprite->width = sprite[ZOOM_LVL_MIN].width; @@ -438,10 +438,10 @@ template Sprite *Blitter_32bppOptimized::EncodeInternal(const return dest_sprite; } -template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator); -template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator); +template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator); +template Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator); -Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { return this->EncodeInternal(sprite, allocator); } diff --git a/src/blitter/32bpp_optimized.hpp b/src/blitter/32bpp_optimized.hpp index b1e076faa4..862c1d9e7e 100644 --- a/src/blitter/32bpp_optimized.hpp +++ b/src/blitter/32bpp_optimized.hpp @@ -22,7 +22,7 @@ public: }; void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; std::string_view GetName() override { return "32bpp-optimized"; } @@ -30,7 +30,7 @@ public: protected: template void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - template Sprite *EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator); + template Sprite *EncodeInternal(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator); }; /** Factory for the optimised 32 bpp blitter (without palette animation). */ diff --git a/src/blitter/32bpp_simple.cpp b/src/blitter/32bpp_simple.cpp index 9fcb224b08..ae660e372f 100644 --- a/src/blitter/32bpp_simple.cpp +++ b/src/blitter/32bpp_simple.cpp @@ -115,10 +115,10 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal); } -Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { Blitter_32bppSimple::Pixel *dst; - Sprite *dest_sprite = static_cast(allocator(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width) * sizeof(*dst))); + Sprite *dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width) * sizeof(*dst)); dest_sprite->height = sprite[ZOOM_LVL_MIN].height; dest_sprite->width = sprite[ZOOM_LVL_MIN].width; diff --git a/src/blitter/32bpp_simple.hpp b/src/blitter/32bpp_simple.hpp index 8c2dc3a346..902af2905a 100644 --- a/src/blitter/32bpp_simple.hpp +++ b/src/blitter/32bpp_simple.hpp @@ -26,7 +26,7 @@ class Blitter_32bppSimple : public Blitter_32bppBase { public: void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; std::string_view GetName() override { return "32bpp-simple"; } }; diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 72919b9bc4..2b4505253b 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -20,7 +20,7 @@ /** Instantiation of the SSE2 32bpp blitter factory. */ static FBlitter_32bppSSE2 iFBlitter_32bppSSE2; -Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { /* First uint32_t of a line = the number of transparent pixels from the left. * Second uint32_t of a line = the number of transparent pixels from the right. @@ -51,7 +51,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri all_sprites_size += rgba_size + mv_size; } - Sprite *dst_sprite = (Sprite *) allocator(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size); + Sprite *dst_sprite = allocator.Allocate(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size); dst_sprite->height = sprite[ZOOM_LVL_MIN].height; dst_sprite->width = sprite[ZOOM_LVL_MIN].width; dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp index 402c732546..ebbb31e059 100644 --- a/src/blitter/32bpp_sse2.hpp +++ b/src/blitter/32bpp_sse2.hpp @@ -76,7 +76,7 @@ public: uint8_t data[]; ///< Data, all zoomlevels. }; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator); + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator); }; DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags); @@ -88,7 +88,7 @@ public: template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override { + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override { return Blitter_32bppSSE_Base::Encode(sprite, allocator); } diff --git a/src/blitter/40bpp_anim.cpp b/src/blitter/40bpp_anim.cpp index cf2ee68897..3a9b89e4bd 100644 --- a/src/blitter/40bpp_anim.cpp +++ b/src/blitter/40bpp_anim.cpp @@ -397,7 +397,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height, } } -Sprite *Blitter_40bppAnim::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_40bppAnim::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { return this->EncodeInternal(sprite, allocator); } diff --git a/src/blitter/40bpp_anim.hpp b/src/blitter/40bpp_anim.hpp index 928af303c2..0174735c3a 100644 --- a/src/blitter/40bpp_anim.hpp +++ b/src/blitter/40bpp_anim.hpp @@ -27,7 +27,7 @@ public: void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override; void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; size_t BufferSize(uint width, uint height) override; Blitter::PaletteAnimation UsePaletteAnimation() override; bool NeedsAnimationBuffer() override; diff --git a/src/blitter/8bpp_optimized.cpp b/src/blitter/8bpp_optimized.cpp index 3d050744cb..c4bef59b53 100644 --- a/src/blitter/8bpp_optimized.cpp +++ b/src/blitter/8bpp_optimized.cpp @@ -120,7 +120,7 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z } } -Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { /* Make memory for all zoom-levels */ uint memory = sizeof(SpriteData); @@ -219,7 +219,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri assert(size < memory); /* Allocate the exact amount of memory we need */ - Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size); + Sprite *dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + size); dest_sprite->height = sprite[ZOOM_LVL_MIN].height; dest_sprite->width = sprite[ZOOM_LVL_MIN].width; diff --git a/src/blitter/8bpp_optimized.hpp b/src/blitter/8bpp_optimized.hpp index b999676648..c3c8e381d0 100644 --- a/src/blitter/8bpp_optimized.hpp +++ b/src/blitter/8bpp_optimized.hpp @@ -23,7 +23,7 @@ public: }; void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; std::string_view GetName() override { return "8bpp-optimized"; } }; diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp index 8dfa599a61..6686ec0e2a 100644 --- a/src/blitter/8bpp_simple.cpp +++ b/src/blitter/8bpp_simple.cpp @@ -61,10 +61,10 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom } } -Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { Sprite *dest_sprite; - dest_sprite = static_cast(allocator(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width))); + dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width)); dest_sprite->height = sprite[ZOOM_LVL_MIN].height; dest_sprite->width = sprite[ZOOM_LVL_MIN].width; diff --git a/src/blitter/8bpp_simple.hpp b/src/blitter/8bpp_simple.hpp index eebccac158..12e7f0fd8e 100644 --- a/src/blitter/8bpp_simple.hpp +++ b/src/blitter/8bpp_simple.hpp @@ -17,7 +17,7 @@ class Blitter_8bppSimple final : public Blitter_8bppBase { public: void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; std::string_view GetName() override { return "8bpp-simple"; } }; diff --git a/src/blitter/null.cpp b/src/blitter/null.cpp index 865c225917..dc8b1c0ea2 100644 --- a/src/blitter/null.cpp +++ b/src/blitter/null.cpp @@ -15,10 +15,10 @@ /** Instantiation of the null blitter factory. */ static FBlitter_Null iFBlitter_Null; -Sprite *Blitter_Null::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +Sprite *Blitter_Null::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { Sprite *dest_sprite; - dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite)); + dest_sprite = allocator.Allocate(sizeof(*dest_sprite)); dest_sprite->height = sprite[ZOOM_LVL_MIN].height; dest_sprite->width = sprite[ZOOM_LVL_MIN].width; diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 5f5ed81646..a0ecfbe8db 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -18,7 +18,7 @@ public: uint8_t GetScreenDepth() override { return 0; } void Draw(Blitter::BlitterParams *, BlitterMode, ZoomLevel) override {}; void DrawColourMappingRect(void *, int, int, PaletteID) override {}; - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; void *MoveTo(void *, int, int) override { return nullptr; }; void SetPixel(void *, int, int, uint8_t) override {}; void DrawRect(void *, int, int, uint8_t) override {}; diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index 7e83bbf48d..51187047c7 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -274,7 +274,8 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa) } GlyphEntry new_glyph; - new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, SimpleSpriteAlloc); + SimpleSpriteAllocator allocator; + new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, allocator); new_glyph.width = slot->advance.x >> 6; this->SetGlyphPtr(key, &new_glyph); diff --git a/src/fontcache/truetypefontcache.cpp b/src/fontcache/truetypefontcache.cpp index c897221d10..df07f802e0 100644 --- a/src/fontcache/truetypefontcache.cpp +++ b/src/fontcache/truetypefontcache.cpp @@ -10,7 +10,6 @@ #include "../stdafx.h" #include "../debug.h" #include "../fontcache.h" -#include "../blitter/factory.hpp" #include "../core/bitmath_func.hpp" #include "../gfx_layout.h" #include "truetypefontcache.h" diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index c73a799a69..ab54485929 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -277,7 +277,8 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) } GlyphEntry new_glyph; - new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, SimpleSpriteAlloc); + SimpleSpriteAllocator allocator; + new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, allocator); new_glyph.width = (uint8_t)std::round(CTFontGetAdvancesForGlyphs(this->font.get(), kCTFontOrientationDefault, &glyph, nullptr, 1)); this->SetGlyphPtr(key, &new_glyph); diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index 1f4aa775bb..dbab716f1a 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -253,7 +253,8 @@ void Win32FontCache::ClearFontCache() } GlyphEntry new_glyph; - new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, SimpleSpriteAlloc); + SimpleSpriteAllocator allocator; + new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(spritecollection, allocator); new_glyph.width = gm.gmCellIncX; this->SetGlyphPtr(key, &new_glyph); diff --git a/src/spritecache.cpp b/src/spritecache.cpp index ca7fbba6c9..1c688c2c38 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -423,14 +423,14 @@ static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite * @param num Size of the sprite in the GRF. * @return Sprite data. */ -static void *ReadRecolourSprite(SpriteFile &file, uint num) +static void *ReadRecolourSprite(SpriteFile &file, uint num, SpriteAllocator &allocator) { /* "Normal" recolour sprites are ALWAYS 257 bytes. Then there is a small * number of recolour sprites that are 17 bytes that only exist in DOS * GRFs which are the same as 257 byte recolour sprites, but with the last * 240 bytes zeroed. */ static const uint RECOLOUR_SPRITE_SIZE = 257; - uint8_t *dest = (uint8_t *)AllocSprite(std::max(RECOLOUR_SPRITE_SIZE, num)); + uint8_t *dest = allocator.Allocate(std::max(RECOLOUR_SPRITE_SIZE, num)); if (file.NeedsPaletteRemap()) { uint8_t *dest_tmp = new uint8_t[std::max(RECOLOUR_SPRITE_SIZE, num)]; @@ -460,7 +460,7 @@ static void *ReadRecolourSprite(SpriteFile &file, uint num) * @param encoder Sprite encoder to use. * @return Read sprite data. */ -static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_type, AllocatorProc *allocator, SpriteEncoder *encoder) +static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_type, SpriteAllocator &allocator, SpriteEncoder *encoder) { /* Use current blitter if no other sprite encoder is given. */ if (encoder == nullptr) encoder = BlitterFactory::GetCurrentBlitter(); @@ -490,7 +490,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty if (sprite_avail == 0) { if (sprite_type == SpriteType::MapGen) return nullptr; if (id == SPR_IMG_QUERY) UserError("Okay... something went horribly wrong. I couldn't load the fallback sprite. What should I do?"); - return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder); + return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, &allocator, encoder); } if (sprite_type == SpriteType::MapGen) { @@ -505,7 +505,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty * (so type = 0xFF basically). */ uint num = sprite[ZOOM_LVL_MIN].width * sprite[ZOOM_LVL_MIN].height; - Sprite *s = (Sprite *)allocator(sizeof(*s) + num); + Sprite *s = allocator.Allocate(sizeof(*s) + num); s->width = sprite[ZOOM_LVL_MIN].width; s->height = sprite[ZOOM_LVL_MIN].height; s->x_offs = sprite[ZOOM_LVL_MIN].x_offs; @@ -523,7 +523,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty if (!ResizeSprites(sprite, sprite_avail, encoder)) { if (id == SPR_IMG_QUERY) UserError("Okay... something went horribly wrong. I couldn't resize the fallback sprite. What should I do?"); - return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder); + return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, &allocator, encoder); } if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font && _font_zoom != ZOOM_LVL_MIN) { @@ -637,7 +637,8 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) return false; } type = SpriteType::Recolour; - data = ReadRecolourSprite(file, num); + CacheSpriteAllocator allocator; + data = ReadRecolourSprite(file, num, allocator); } else if (file.GetContainerVersion() >= 2 && grf_type == 0xFD) { if (num != 4) { /* Invalid sprite section include, ignore. */ @@ -848,7 +849,7 @@ static void DeleteEntryFromSpriteCache() DeleteEntryFromSpriteCache(best); } -void *AllocSprite(size_t mem_req) +void *CacheSpriteAllocator::AllocatePtr(size_t mem_req) { mem_req += sizeof(MemBlock); @@ -888,7 +889,7 @@ void *AllocSprite(size_t mem_req) /** * Sprite allocator simply using malloc. */ -void *SimpleSpriteAlloc(size_t size) +void *SimpleSpriteAllocator::AllocatePtr(size_t size) { return MallocT(size); } @@ -902,7 +903,7 @@ void *SimpleSpriteAlloc(size_t size) * @return fallback sprite * @note this function will do UserError() in the case the fallback sprite isn't available */ -static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, SpriteCache *sc, AllocatorProc *allocator) +static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, SpriteCache *sc, SpriteAllocator *allocator) { static const char * const sprite_types[] = { "normal", // SpriteType::Normal @@ -947,7 +948,7 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S * @param encoder Sprite encoder to use. Set to nullptr to use the currently active blitter. * @return Sprite raw data */ -void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator, SpriteEncoder *encoder) +void *GetRawSprite(SpriteID sprite, SpriteType type, SpriteAllocator *allocator, SpriteEncoder *encoder) { assert(type != SpriteType::MapGen || IsMapgenSpriteID(sprite)); assert(type < SpriteType::Invalid); @@ -965,17 +966,18 @@ void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator, S if (allocator == nullptr && encoder == nullptr) { /* Load sprite into/from spritecache */ + CacheSpriteAllocator cache_allocator; /* Update LRU */ sc->lru = ++_sprite_lru_counter; /* Load the sprite, if it is not loaded, yet */ - if (sc->ptr == nullptr) sc->ptr = ReadSprite(sc, sprite, type, AllocSprite, nullptr); + if (sc->ptr == nullptr) sc->ptr = ReadSprite(sc, sprite, type, cache_allocator, nullptr); return sc->ptr; } else { /* Do not use the spritecache, but a different allocator. */ - return ReadSprite(sc, sprite, type, allocator, encoder); + return ReadSprite(sc, sprite, type, *allocator, encoder); } } diff --git a/src/spritecache.h b/src/spritecache.h index 78447d700d..c2be62bdec 100644 --- a/src/spritecache.h +++ b/src/spritecache.h @@ -31,10 +31,13 @@ enum SpriteCacheCtrlFlags { extern uint _sprite_cache_size; -typedef void *AllocatorProc(size_t size); +/** SpriteAllocate that uses malloc to allocate memory. */ +class SimpleSpriteAllocator : public SpriteAllocator { +protected: + void *AllocatePtr(size_t size) override; +}; -void *SimpleSpriteAlloc(size_t size); -void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator = nullptr, SpriteEncoder *encoder = nullptr); +void *GetRawSprite(SpriteID sprite, SpriteType type, SpriteAllocator *allocator = nullptr, SpriteEncoder *encoder = nullptr); bool SpriteExists(SpriteID sprite); SpriteType GetSpriteType(SpriteID sprite); diff --git a/src/spritecache_internal.h b/src/spritecache_internal.h index 5c49c54aed..f4f328eb4d 100644 --- a/src/spritecache_internal.h +++ b/src/spritecache_internal.h @@ -31,12 +31,17 @@ struct SpriteCache { uint8_t control_flags; ///< Control flags, see SpriteCacheCtrlFlags }; +/** SpriteAllocator that allocates memory from the sprite cache. */ +class CacheSpriteAllocator : public SpriteAllocator { +protected: + void *AllocatePtr(size_t size) override; +}; + inline bool IsMapgenSpriteID(SpriteID sprite) { return IsInsideMM(sprite, SPR_MAPGEN_BEGIN, SPR_MAPGEN_END); } -void *AllocSprite(size_t mem_req); SpriteCache *AllocateSpriteCache(uint index); #endif /* SPRITECACHE_INTERNAL_H */ diff --git a/src/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index afb7baa48c..88db68671f 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.hpp @@ -16,7 +16,6 @@ #include "sprite_file_type.hpp" struct Sprite; -typedef void *AllocatorProc(size_t size); /** The different colour components a sprite can have. */ enum SpriteColourComponent { @@ -85,6 +84,32 @@ public: virtual ~SpriteLoader() = default; }; +/** Interface for something that can allocate memory for a sprite. */ +class SpriteAllocator { +public: + virtual ~SpriteAllocator() = default; + + /** + * Allocate memory for a sprite. + * @tparam T Type to return memory as. + * @param size Size of memory to allocate in bytes. + * @return Pointer to allocated memory. + */ + template + T *Allocate(size_t size) + { + return static_cast(this->AllocatePtr(size)); + } + +protected: + /** + * Allocate memory for a sprite. + * @param size Size of memory to allocate. + * @return Pointer to allocated memory. + */ + virtual void *AllocatePtr(size_t size) = 0; +}; + /** Interface for something that can encode a sprite. */ class SpriteEncoder { public: @@ -99,7 +124,7 @@ public: /** * Convert a sprite from the loader to our own format. */ - virtual Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) = 0; + virtual Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) = 0; /** * Get the value which the height and width on a sprite have to be aligned by. diff --git a/src/tests/mock_spritecache.cpp b/src/tests/mock_spritecache.cpp index 5a5910cfdd..38bb6804cd 100644 --- a/src/tests/mock_spritecache.cpp +++ b/src/tests/mock_spritecache.cpp @@ -17,7 +17,8 @@ static bool MockLoadNextSprite(int load_index) { - static Sprite *sprite = (Sprite *)AllocSprite(sizeof(*sprite)); + SimpleSpriteAllocator allocator; + static Sprite *sprite = allocator.Allocate(sizeof(*sprite)); bool is_mapgen = IsMapgenSpriteID(load_index); diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 13920cb543..a7b43da317 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -1105,7 +1105,8 @@ void OpenGLBackend::PopulateCursorCache() this->cursor_sprites.emplace_back(sc); if (!this->cursor_cache.Contains(sc.image.sprite)) { - Sprite *old = this->cursor_cache.Insert(sc.image.sprite, (Sprite *)GetRawSprite(sc.image.sprite, SpriteType::Normal, &SimpleSpriteAlloc, this)); + SimpleSpriteAllocator allocator; + Sprite *old = this->cursor_cache.Insert(sc.image.sprite, static_cast(GetRawSprite(sc.image.sprite, SpriteType::Normal, &allocator, this))); if (old != nullptr) { OpenGLSprite *gl_sprite = (OpenGLSprite *)old->data; gl_sprite->~OpenGLSprite(); @@ -1257,10 +1258,10 @@ void OpenGLBackend::ReleaseAnimBuffer(const Rect &update_rect) } } -/* virtual */ Sprite *OpenGLBackend::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) +/* virtual */ Sprite *OpenGLBackend::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) { /* Allocate and construct sprite data. */ - Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(OpenGLSprite)); + Sprite *dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + sizeof(OpenGLSprite)); OpenGLSprite *gl_sprite = (OpenGLSprite *)dest_sprite->data; new (gl_sprite) OpenGLSprite(sprite[ZOOM_LVL_MIN].width, sprite[ZOOM_LVL_MIN].height, sprite[ZOOM_LVL_MIN].type == SpriteType::Font ? 1 : ZOOM_LVL_END, sprite[ZOOM_LVL_MIN].colours); diff --git a/src/video/opengl.h b/src/video/opengl.h index 0fd706ffb2..14633c44cd 100644 --- a/src/video/opengl.h +++ b/src/video/opengl.h @@ -107,7 +107,7 @@ public: bool Is32BppSupported() override { return true; } uint GetSpriteAlignment() override { return 1u << (ZOOM_LVL_END - 1); } - Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; + Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; };