src/spritecache.c
changeset 5500 91a9244b4644
parent 5475 2e6990a8c7c4
child 5501 b4e81fd72b3a
equal deleted inserted replaced
5499:e6bc096fdee2 5500:91a9244b4644
     9 #include "table/sprites.h"
     9 #include "table/sprites.h"
    10 #include "fileio.h"
    10 #include "fileio.h"
    11 
    11 
    12 #define SPRITE_CACHE_SIZE 1024*1024
    12 #define SPRITE_CACHE_SIZE 1024*1024
    13 
    13 
    14 #define WANT_NEW_LRU
       
    15 
       
    16 
    14 
    17 static void* _sprite_ptr[MAX_SPRITES];
    15 static void* _sprite_ptr[MAX_SPRITES];
    18 static uint32 _sprite_file_pos[MAX_SPRITES];
    16 static uint32 _sprite_file_pos[MAX_SPRITES];
    19 
       
    20 #if defined(WANT_NEW_LRU)
       
    21 static int16 _sprite_lru_new[MAX_SPRITES];
    17 static int16 _sprite_lru_new[MAX_SPRITES];
    22 #else
       
    23 static uint16 _sprite_lru[MAX_SPRITES];
       
    24 static uint16 _sprite_lru_cur[MAX_SPRITES];
       
    25 #endif
       
    26 
    18 
    27 typedef struct MemBlock {
    19 typedef struct MemBlock {
    28 	uint32 size;
    20 	uint32 size;
    29 	byte data[VARARRAY_SIZE];
    21 	byte data[VARARRAY_SIZE];
    30 } MemBlock;
    22 } MemBlock;
   157 
   149 
   158 	_sprite_file_pos[load_index] = file_pos;
   150 	_sprite_file_pos[load_index] = file_pos;
   159 
   151 
   160 	_sprite_ptr[load_index] = NULL;
   152 	_sprite_ptr[load_index] = NULL;
   161 
   153 
   162 #if defined(WANT_NEW_LRU)
       
   163 	_sprite_lru_new[load_index] = 0;
   154 	_sprite_lru_new[load_index] = 0;
   164 #else
       
   165 	_sprite_lru[load_index] = 0xFFFF;
       
   166 	_sprite_lru_cur[load_index] = 0;
       
   167 #endif
       
   168 
   155 
   169 	return true;
   156 	return true;
   170 }
   157 }
   171 
   158 
   172 
   159 
   207 void IncreaseSpriteLRU(void)
   194 void IncreaseSpriteLRU(void)
   208 {
   195 {
   209 	int i;
   196 	int i;
   210 
   197 
   211 	// Increase all LRU values
   198 	// Increase all LRU values
   212 #if defined(WANT_NEW_LRU)
       
   213 	if (_sprite_lru_counter > 16384) {
   199 	if (_sprite_lru_counter > 16384) {
   214 		DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage());
   200 		DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage());
   215 
   201 
   216 		for (i = 0; i != MAX_SPRITES; i++)
   202 		for (i = 0; i != MAX_SPRITES; i++)
   217 			if (_sprite_ptr[i] != NULL) {
   203 			if (_sprite_ptr[i] != NULL) {
   221 					_sprite_lru_new[i]--;
   207 					_sprite_lru_new[i]--;
   222 				}
   208 				}
   223 			}
   209 			}
   224 		_sprite_lru_counter = 0;
   210 		_sprite_lru_counter = 0;
   225 	}
   211 	}
   226 #else
       
   227 	for (i = 0; i != MAX_SPRITES; i++)
       
   228 		if (_sprite_ptr[i] != NULL && _sprite_lru[i] != 65535)
       
   229 			_sprite_lru[i]++;
       
   230 	// Reset the lru counter.
       
   231 	_sprite_lru_counter = 0;
       
   232 #endif
       
   233 
   212 
   234 	// Compact sprite cache every now and then.
   213 	// Compact sprite cache every now and then.
   235 	if (++_compact_cache_counter >= 740) {
   214 	if (++_compact_cache_counter >= 740) {
   236 		CompactSpriteCache();
   215 		CompactSpriteCache();
   237 		_compact_cache_counter = 0;
   216 		_compact_cache_counter = 0;
   288 	MemBlock* s;
   267 	MemBlock* s;
   289 	int cur_lru;
   268 	int cur_lru;
   290 
   269 
   291 	DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage());
   270 	DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage());
   292 
   271 
   293 #if defined(WANT_NEW_LRU)
       
   294 	cur_lru = 0xffff;
   272 	cur_lru = 0xffff;
   295 	for (i = 0; i != MAX_SPRITES; i++) {
   273 	for (i = 0; i != MAX_SPRITES; i++) {
   296 		if (_sprite_ptr[i] != NULL && _sprite_lru_new[i] < cur_lru) {
   274 		if (_sprite_ptr[i] != NULL && _sprite_lru_new[i] < cur_lru) {
   297 			cur_lru = _sprite_lru_new[i];
   275 			cur_lru = _sprite_lru_new[i];
   298 			best = i;
   276 			best = i;
   299 		}
   277 		}
   300 	}
   278 	}
   301 #else
       
   302 	{
       
   303 	uint16 cur_lru = 0, cur_lru_cur = 0xffff;
       
   304 	for (i = 0; i != MAX_SPRITES; i++) {
       
   305 		if (_sprite_ptr[i] == NULL || _sprite_lru[i] < cur_lru) continue;
       
   306 
       
   307 		// Found a sprite with a higher LRU value, then remember it.
       
   308 		if (_sprite_lru[i] != cur_lru) {
       
   309 			cur_lru = _sprite_lru[i];
       
   310 			best = i;
       
   311 
       
   312 		// Else if both sprites were very recently referenced, compare by the cur value instead.
       
   313 		} else if (cur_lru == 0 && _sprite_lru_cur[i] <= cur_lru_cur) {
       
   314 			cur_lru_cur = _sprite_lru_cur[i];
       
   315 			cur_lru = _sprite_lru[i];
       
   316 			best = i;
       
   317 		}
       
   318 	}
       
   319 	}
       
   320 #endif
       
   321 
   279 
   322 	// Display an error message and die, in case we found no sprite at all.
   280 	// Display an error message and die, in case we found no sprite at all.
   323 	// This shouldn't really happen, unless all sprites are locked.
   281 	// This shouldn't really happen, unless all sprites are locked.
   324 	if (best == -1)
   282 	if (best == -1)
   325 		error("Out of sprite memory");
   283 		error("Out of sprite memory");
   429 #if defined(NEW_ROTATION)
   387 #if defined(NEW_ROTATION)
   430 	sprite = RotateSprite(sprite);
   388 	sprite = RotateSprite(sprite);
   431 #endif
   389 #endif
   432 
   390 
   433 	// Update LRU
   391 	// Update LRU
   434 #if defined(WANT_NEW_LRU)
       
   435 	_sprite_lru_new[sprite] = ++_sprite_lru_counter;
   392 	_sprite_lru_new[sprite] = ++_sprite_lru_counter;
   436 #else
       
   437 	_sprite_lru_cur[sprite] = ++_sprite_lru_counter;
       
   438 	_sprite_lru[sprite] = 0;
       
   439 #endif
       
   440 
   393 
   441 	p = _sprite_ptr[sprite];
   394 	p = _sprite_ptr[sprite];
   442 	// Load the sprite, if it is not loaded, yet
   395 	// Load the sprite, if it is not loaded, yet
   443 	if (p == NULL) p = ReadSprite(sprite);
   396 	if (p == NULL) p = ReadSprite(sprite);
   444 	return p;
   397 	return p;