--- sourceforge.net/trunk/rdesktop/cache.c 2004/06/25 15:46:26 724 +++ sourceforge.net/trunk/rdesktop/cache.c 2004/06/27 17:51:54 725 @@ -21,22 +21,59 @@ #include "rdesktop.h" #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0])) +#define TOUCH(id, idx) (g_bmpcache[id][idx].usage = ++g_stamp) +#define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0) + +extern int g_pstcache_fd[]; + +uint32 g_stamp; +int g_num_bitmaps_in_memory[3]; /* BITMAP CACHE */ -static HBITMAP g_bmpcache[3][600]; +static BMPCACHEENTRY g_bmpcache[3][0xa00]; + +/* Remove the least-recently used bitmap from the cache */ +void +cache_remove_lru_bitmap(uint8 cache_id) +{ + int i; + uint16 cache_idx = 0; + uint32 m = -1; + BMPCACHEENTRY *pbce; + + for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++) + { + if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m) + { + cache_idx = i; + m = g_bmpcache[cache_id][i].usage; + } + } + + pbce = &g_bmpcache[cache_id][cache_idx]; + ui_destroy_bitmap(pbce->bitmap); + --g_num_bitmaps_in_memory[cache_id]; + pbce->bitmap = 0; + pbce->usage = 0; +} /* Retrieve a bitmap from the cache */ HBITMAP cache_get_bitmap(uint8 cache_id, uint16 cache_idx) { - HBITMAP bitmap; + HBITMAP *pbitmap; if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0]))) { - bitmap = g_bmpcache[cache_id][cache_idx]; - if (bitmap != NULL) - return bitmap; + pbitmap = &g_bmpcache[cache_id][cache_idx].bitmap; + if ((*pbitmap != 0) || pstcache_load_bitmap(cache_id, cache_idx)) + { + if (IS_PERSISTENT(cache_id)) + TOUCH(cache_id, cache_idx); + + return *pbitmap; + } } error("get bitmap %d:%d\n", cache_id, cache_idx); @@ -45,17 +82,25 @@ /* Store a bitmap in the cache */ void -cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap) +cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp) { HBITMAP old; if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0]))) { - old = g_bmpcache[cache_id][cache_idx]; + old = g_bmpcache[cache_id][cache_idx].bitmap; if (old != NULL) + { ui_destroy_bitmap(old); + } + else + { + if (++g_num_bitmaps_in_memory[cache_id] > BMPCACHE2_C2_CELLS) + cache_remove_lru_bitmap(cache_id); + } - g_bmpcache[cache_id][cache_idx] = bitmap; + g_bmpcache[cache_id][cache_idx].bitmap = bitmap; + g_bmpcache[cache_id][cache_idx].usage = stamp; } else { @@ -63,6 +108,18 @@ } } +/* Updates the persistent bitmap cache MRU information on exit */ +void +cache_save_state(void) +{ + int id, idx; + + for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++) + if (IS_PERSISTENT(id)) + for (idx = 0; idx < NUM_ELEMENTS(g_bmpcache[id]); idx++) + pstcache_touch_bitmap(id, idx, g_bmpcache[id][idx].usage); +} + /* FONT CACHE */ static FONTGLYPH g_fontcache[12][256];