Changeset - r11203:4e233b1fc54b
[Not reviewed]
master
0 4 0
rubidium - 16 years ago 2009-02-23 17:54:02
rubidium@openttd.org
(svn r15556) -Change: don't temporary malloc+free when encoding sprites, just reuse the same piece of allocated memory for each encoding.
4 files changed with 66 insertions and 23 deletions:
0 comments (0 inline, 0 general)
src/blitter/8bpp_optimized.cpp
Show inline comments
 
@@ -113,7 +113,12 @@ Sprite *Blitter_8bppOptimized::Encode(Sp
 

	
 
	/* We have no idea how much memory we really need, so just guess something */
 
	memory *= 5;
 
	SpriteData *temp_dst = (SpriteData *)MallocT<byte>(memory);
 

	
 
	/* Don't allocate memory each time, but just keep some
 
	 * memory around as this function is called quite often
 
	 * and the memory usage is quite low. */
 
	static ReusableBuffer<byte> temp_buffer;
 
	SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
 
	byte *dst = temp_dst->data;
 

	
 
	/* Make the sprites per zoom-level */
 
@@ -195,7 +200,6 @@ Sprite *Blitter_8bppOptimized::Encode(Sp
 
	dest_sprite->x_offs = sprite->x_offs;
 
	dest_sprite->y_offs = sprite->y_offs;
 
	memcpy(dest_sprite->data, temp_dst, size);
 
	free(temp_dst);
 

	
 
	return dest_sprite;
 
}
src/core/alloc_type.hpp
Show inline comments
 
@@ -71,6 +71,61 @@ struct SmallStackSafeStackAlloc {
 
};
 

	
 
/**
 
 * A reusable buffer that can be used for places that temporary allocate
 
 * a bit of memory and do that very often, or for places where static
 
 * memory is allocated that might need to be reallocated sometimes.
 
 *
 
 * Every time Allocate or ZeroAllocate is called previous results of both
 
 * functions will become invalid.
 
 */
 
template <typename T>
 
class ReusableBuffer {
 
private:
 
	T *buffer;    ///< The real data buffer
 
	size_t count; ///< Number of T elements in the buffer
 

	
 
public:
 
	/** Create a new buffer */
 
	ReusableBuffer() : buffer(NULL), count(0) {}
 
	/** Clear the buffer */
 
	~ReusableBuffer() { free(this->buffer); }
 

	
 
	/**
 
	 * Get buffer of at least count times T.
 
	 * @note the buffer might be bigger
 
	 * @note calling this function invalidates any previous buffers given
 
	 * @param count the minimum buffer size
 
	 * @return the buffer
 
	 */
 
	T *Allocate(size_t count)
 
	{
 
		if (this->count < count) {
 
			free(this->buffer);
 
			this->buffer = MallocT<T>(count);
 
		}
 
		return this->buffer;
 
	}
 

	
 
	/**
 
	 * Get buffer of at least count times T with zeroed memory.
 
	 * @note the buffer might be bigger
 
	 * @note calling this function invalidates any previous buffers given
 
	 * @param count the minimum buffer size
 
	 * @return the buffer
 
	 */
 
	T *ZeroAllocate(size_t count)
 
	{
 
		if (this->count < count) {
 
			free(this->buffer);
 
			this->buffer = CallocT<T>(count);
 
		} else {
 
			memset(this->buffer, 0, sizeof(T) * count);
 
		}
 
		return this->buffer;
 
	}
 
};
 

	
 
/**
 
 * Base class that provides memory initialization on dynamically created objects.
 
 * All allocated memory will be zeroed.
 
 */
src/spritecache.cpp
Show inline comments
 
@@ -560,17 +560,4 @@ void GfxInitSpriteMem()
 
	_compact_cache_counter = 0;
 
}
 

	
 
void SpriteLoader::Sprite::AllocateData(size_t size)
 
{
 
	if (Sprite::size < size) {
 
		Sprite::size = size;
 
		Sprite::mem = ReallocT<SpriteLoader::CommonPixel>(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;
 
/* static */ ReusableBuffer<SpriteLoader::CommonPixel> SpriteLoader::Sprite::buffer;
src/spriteloader/spriteloader.hpp
Show inline comments
 
@@ -5,6 +5,8 @@
 
#ifndef SPRITELOADER_HPP
 
#define SPRITELOADER_HPP
 

	
 
#include "../core/alloc_type.hpp"
 

	
 
class SpriteLoader {
 
public:
 
	struct CommonPixel {
 
@@ -22,9 +24,6 @@ public:
 
	 * 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
 
@@ -35,12 +34,10 @@ public:
 
		 * Allocate the sprite data of this sprite.
 
		 * @param size the minimum size of the data field.
 
		 */
 
		void AllocateData(size_t size);
 
		void AllocateData(size_t size) { this->data = Sprite::buffer.ZeroAllocate(size); }
 
	private:
 
		/** Allocated memory to pass sprite data around */
 
		static SpriteLoader::CommonPixel *mem;
 
		/** Size (in items) of the above memory. */
 
		static size_t size;
 
		static ReusableBuffer<SpriteLoader::CommonPixel> buffer;
 
	};
 

	
 
	/**
0 comments (0 inline, 0 general)