From 0c1b8ea602de72a96573b7e3301589e8e3249ca1 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 23 Feb 2009 10:50:25 +0000 Subject: [PATCH] (svn r15555) -Codechange: remove the mallocs + frees for temporary data from loading sprites. --- src/fontcache.cpp | 3 +-- src/spritecache.cpp | 17 +++++++++++++++-- src/spriteloader/grf.cpp | 2 +- src/spriteloader/png.cpp | 10 ++-------- src/spriteloader/spriteloader.hpp | 20 ++++++++++++++++++++ 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/fontcache.cpp b/src/fontcache.cpp index fe74e08790..f59d5eff97 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -710,7 +710,7 @@ const Sprite *GetGlyph(FontSize size, WChar key) height = max(1, slot->bitmap.rows + (size == FS_NORMAL)); /* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */ - sprite.data = CallocT(width * height); + sprite.AllocateData(width * height); sprite.width = width; sprite.height = height; sprite.x_offs = slot->bitmap_left; @@ -740,7 +740,6 @@ const Sprite *GetGlyph(FontSize size, WChar key) } new_glyph.sprite = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, AllocateFont); - free(sprite.data); new_glyph.width = (slot->advance.x >> 6) + (size != FS_NORMAL); SetGlyphPtr(size, key, &new_glyph); diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 36ae252922..c5fa7f0370 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -154,7 +154,6 @@ static void *ReadSprite(SpriteCache *sc, SpriteID id, SpriteType sprite_type) if (sprite_loader.LoadSprite(&sprite, file_slot, sc->id, sprite_type)) { sc->ptr = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, &AllocSprite); - free(sprite.data); return sc->ptr; } @@ -256,7 +255,6 @@ static void *ReadSprite(SpriteCache *sc, SpriteID id, SpriteType sprite_type) return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL); } sc->ptr = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, &AllocSprite); - free(sprite.data); return sc->ptr; } @@ -561,3 +559,18 @@ void GfxInitSpriteMem() _compact_cache_counter = 0; } + +void SpriteLoader::Sprite::AllocateData(size_t size) +{ + if (Sprite::size < size) { + Sprite::size = size; + Sprite::mem = ReallocT(Sprite::mem, Sprite::size); + } + + memset(Sprite::mem, 0, sizeof(SpriteLoader::CommonPixel) * size); + + this->data = Sprite::mem; + +} +/* static */ SpriteLoader::CommonPixel *SpriteLoader::Sprite::mem = NULL; +/* static */ size_t SpriteLoader::Sprite::size = 0; diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index b4f51eda93..cd034ee735 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -86,7 +86,7 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, if (num != 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__); - sprite->data = CallocT(sprite->width * sprite->height); + sprite->AllocateData(sprite->width * sprite->height); /* When there are transparency pixels, this format has an other trick.. decode it */ if (type & 0x08) { diff --git a/src/spriteloader/png.cpp b/src/spriteloader/png.cpp index d6648b6bed..f99237d920 100644 --- a/src/spriteloader/png.cpp +++ b/src/spriteloader/png.cpp @@ -51,7 +51,6 @@ static bool LoadPNG(SpriteLoader::Sprite *sprite, const char *filename, uint32 i png_infop info_ptr, end_info; uint bit_depth, colour_type; uint i, pixelsize; - png_bytep row_pointer; SpriteLoader::CommonPixel *dst; if (!OpenPNGFile(filename, id, mask)) return mask; // If mask is true, and file not found, continue true anyway, as it isn't a show-stopper @@ -102,7 +101,7 @@ static bool LoadPNG(SpriteLoader::Sprite *sprite, const char *filename, uint32 i sprite->height = info_ptr->height; sprite->width = info_ptr->width; - sprite->data = CallocT(sprite->width * sprite->height); + sprite->AllocateData(sprite->width * sprite->height); } bit_depth = png_get_bit_depth(png_ptr, info_ptr); @@ -134,11 +133,7 @@ static bool LoadPNG(SpriteLoader::Sprite *sprite, const char *filename, uint32 i pixelsize = sizeof(uint8); } - row_pointer = (png_byte *)MallocT(info_ptr->width * pixelsize); - if (row_pointer == NULL) { - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - return false; - } + png_bytep row_pointer = AllocaM(png_byte, info_ptr->width * pixelsize); for (i = 0; i < info_ptr->height; i++) { png_read_row(png_ptr, row_pointer, NULL); @@ -164,7 +159,6 @@ static bool LoadPNG(SpriteLoader::Sprite *sprite, const char *filename, uint32 i } } - free(row_pointer); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return true; diff --git a/src/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index 34e668e22a..9b431fb4fe 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.hpp @@ -15,12 +15,32 @@ public: uint8 m; ///< Remap-channel }; + /** + * Structure for passing information from the sprite loader to the blitter. + * You can only use this struct once at a time when using AllocateData to + * allocate the memory as that will always return the same memory address. + * This to prevent thousands of malloc + frees just to load a sprite. + */ struct Sprite { + Sprite() : data(NULL) {} + ~Sprite() { assert(this->data == NULL || this->data == Sprite::mem); } + uint16 height; ///< Height of the sprite uint16 width; ///< Width of the sprite int16 x_offs; ///< The x-offset of where the sprite will be drawn int16 y_offs; ///< The y-offset of where the sprite will be drawn SpriteLoader::CommonPixel *data; ///< The sprite itself + + /** + * Allocate the sprite data of this sprite. + * @param size the minimum size of the data field. + */ + void AllocateData(size_t size); + private: + /** Allocated memory to pass sprite data around */ + static SpriteLoader::CommonPixel *mem; + /** Size (in items) of the above memory. */ + static size_t size; }; /**