changeset 18471:ca0bc1c7f5ce draft

(svn r23315) -Codechange: Only encode sprites for zoom levels that will be used.
author peter1138 <peter1138@openttd.org>
date Thu, 24 Nov 2011 12:26:44 +0000
parents 64ea4c57dcb9
children 11637619aa76
files src/blitter/32bpp_optimized.cpp src/blitter/8bpp_optimized.cpp src/fontcache.cpp src/settings.cpp src/spritecache.cpp src/spritecache.h src/spriteloader/spriteloader.hpp
diffstat 7 files changed, 59 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/blitter/32bpp_optimized.cpp
+++ b/src/blitter/32bpp_optimized.cpp
@@ -11,6 +11,7 @@
 
 #include "../stdafx.h"
 #include "../zoom_func.h"
+#include "../settings_type.h"
 #include "../core/math_func.hpp"
 #include "32bpp_optimized.hpp"
 
@@ -274,7 +275,19 @@
 	/* lengths of streams */
 	uint32 lengths[ZOOM_LVL_COUNT][2];
 
-	for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) {
+	ZoomLevel zoom_min;
+	ZoomLevel zoom_max;
+
+	if (sprite->type == ST_FONT) {
+		zoom_min = ZOOM_LVL_NORMAL;
+		zoom_max = ZOOM_LVL_NORMAL;
+	} else {
+		zoom_min = _settings_client.gui.zoom_min;
+		zoom_max = _settings_client.gui.zoom_max;
+		if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
+	}
+
+	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
 		const SpriteLoader::Sprite *src_orig = ResizeSprite(sprite, z);
 
 		uint size = src_orig->height * src_orig->width;
@@ -358,7 +371,7 @@
 	}
 
 	uint len = 0; // total length of data
-	for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) {
+	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
 		len += lengths[z][0] + lengths[z][1];
 	}
 
@@ -371,8 +384,8 @@
 
 	SpriteData *dst = (SpriteData *)dest_sprite->data;
 
-	for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) {
-		dst->offset[z][0] = z == ZOOM_LVL_BEGIN ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1];
+	for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
+		dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1];
 		dst->offset[z][1] = lengths[z][0] + dst->offset[z][0];
 
 		memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]);
--- a/src/blitter/8bpp_optimized.cpp
+++ b/src/blitter/8bpp_optimized.cpp
@@ -11,6 +11,7 @@
 
 #include "../stdafx.h"
 #include "../zoom_func.h"
+#include "../settings_type.h"
 #include "../core/math_func.hpp"
 #include "8bpp_optimized.hpp"
 
@@ -116,7 +117,19 @@
 	/* Make memory for all zoom-levels */
 	uint memory = sizeof(SpriteData);
 
-	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
+	ZoomLevel zoom_min;
+	ZoomLevel zoom_max;
+
+	if (sprite->type == ST_FONT) {
+		zoom_min = ZOOM_LVL_NORMAL;
+		zoom_max = ZOOM_LVL_NORMAL;
+	} else {
+		zoom_min = _settings_client.gui.zoom_min;
+		zoom_max = _settings_client.gui.zoom_max;
+		if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
+	}
+
+	for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
 		memory += UnScaleByZoom(sprite->height, i) * UnScaleByZoom(sprite->width, i);
 	}
 
@@ -131,7 +144,7 @@
 	byte *dst = temp_dst->data;
 
 	/* Make the sprites per zoom-level */
-	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
+	for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
 		/* Store the index table */
 		uint offset = dst - temp_dst->data;
 		temp_dst->offset[i] = offset;
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -1113,6 +1113,7 @@
 
 	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
 	sprite.AllocateData(width * height);
+	sprite.type = ST_FONT;
 	sprite.width = width;
 	sprite.height = height;
 	sprite.x_offs = slot->bitmap_left;
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -898,6 +898,7 @@
 {
 	extern void ConstrainAllViewportsZoom();
 	ConstrainAllViewportsZoom();
+	GfxClearSpriteCache();
 	return true;
 }
 
--- a/src/spritecache.cpp
+++ b/src/spritecache.cpp
@@ -199,6 +199,7 @@
 		/* Try loading 32bpp graphics in case we are 32bpp output */
 		SpriteLoaderPNG sprite_loader;
 		SpriteLoader::Sprite sprite;
+		sprite.type = sprite_type;
 
 		if (sprite_loader.LoadSprite(&sprite, file_slot, sc->id, sprite_type)) {
 			return BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, allocator);
@@ -290,6 +291,7 @@
 
 	SpriteLoaderGrf sprite_loader;
 	SpriteLoader::Sprite sprite;
+	sprite.type = sprite_type;
 
 	if (!sprite_loader.LoadSprite(&sprite, file_slot, file_pos, sprite_type)) {
 		if (id == SPR_IMG_QUERY) usererror("Okay... something went horribly wrong. I couldn't load the fallback sprite. What should I do?");
@@ -608,7 +610,7 @@
 }
 
 
-void GfxInitSpriteMem()
+static void GfxInitSpriteCache()
 {
 	/* initialize sprite cache heap */
 	if (_spritecache_ptr == NULL) _spritecache_ptr = (MemBlock*)MallocT<byte>(_sprite_cache_size * 1024 * 1024);
@@ -617,6 +619,11 @@
 	_spritecache_ptr->size = ((_sprite_cache_size * 1024 * 1024) - sizeof(MemBlock)) | S_FREE_MASK;
 	/* Sentinel block (identified by size == 0) */
 	NextBlock(_spritecache_ptr)->size = 0;
+}
+
+void GfxInitSpriteMem()
+{
+	GfxInitSpriteCache();
 
 	/* Reset the spritecache 'pool' */
 	free(_spritecache);
@@ -626,4 +633,19 @@
 	_compact_cache_counter = 0;
 }
 
+/**
+ * Remove all encoded sprites from the sprite cache without
+ * discarding sprite location information.
+ */
+void GfxClearSpriteCache()
+{
+	/* Clear sprite ptr for all cached items */
+	for (uint i = 0; i != _spritecache_items; i++) {
+		SpriteCache *sc = GetSpriteCache(i);
+		sc->ptr = NULL;
+	}
+
+	GfxInitSpriteCache();
+}
+
 /* static */ ReusableBuffer<SpriteLoader::CommonPixel> SpriteLoader::Sprite::buffer;
--- a/src/spritecache.h
+++ b/src/spritecache.h
@@ -48,6 +48,7 @@
 }
 
 void GfxInitSpriteMem();
+void GfxClearSpriteCache();
 void IncreaseSpriteLRU();
 
 bool LoadNextSprite(int load_index, byte file_index, uint file_sprite_id);
--- a/src/spriteloader/spriteloader.hpp
+++ b/src/spriteloader/spriteloader.hpp
@@ -38,6 +38,7 @@
 		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
+		SpriteType type;                 ///< The sprite type
 		SpriteLoader::CommonPixel *data; ///< The sprite itself
 
 		/**