--- sourceforge.net/trunk/rdesktop/cache.c 2002/09/26 14:26:46 207 +++ 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 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(bmpcache)) && (cache_idx < NUM_ELEMENTS(bmpcache[0]))) + if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0]))) { - bitmap = 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(bmpcache)) && (cache_idx < NUM_ELEMENTS(bmpcache[0]))) + if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0]))) { - old = 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); + } - bmpcache[cache_id][cache_idx] = bitmap; + g_bmpcache[cache_id][cache_idx].bitmap = bitmap; + g_bmpcache[cache_id][cache_idx].usage = stamp; } else { @@ -63,9 +108,21 @@ } } +/* 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 fontcache[12][256]; +static FONTGLYPH g_fontcache[12][256]; /* Retrieve a glyph from the font cache */ FONTGLYPH * @@ -73,9 +130,9 @@ { FONTGLYPH *glyph; - if ((font < NUM_ELEMENTS(fontcache)) && (character < NUM_ELEMENTS(fontcache[0]))) + if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0]))) { - glyph = &fontcache[font][character]; + glyph = &g_fontcache[font][character]; if (glyph->pixmap != NULL) return glyph; } @@ -91,9 +148,9 @@ { FONTGLYPH *glyph; - if ((font < NUM_ELEMENTS(fontcache)) && (character < NUM_ELEMENTS(fontcache[0]))) + if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0]))) { - glyph = &fontcache[font][character]; + glyph = &g_fontcache[font][character]; if (glyph->pixmap != NULL) ui_destroy_glyph(glyph->pixmap); @@ -111,7 +168,7 @@ /* TEXT CACHE */ -static DATABLOB textcache[256]; +static DATABLOB g_textcache[256]; /* Retrieve a text item from the cache */ DATABLOB * @@ -119,9 +176,9 @@ { DATABLOB *text; - if (cache_id < NUM_ELEMENTS(textcache)) + if (cache_id < NUM_ELEMENTS(g_textcache)) { - text = &textcache[cache_id]; + text = &g_textcache[cache_id]; if (text->data != NULL) return text; } @@ -136,9 +193,9 @@ { DATABLOB *text; - if (cache_id < NUM_ELEMENTS(textcache)) + if (cache_id < NUM_ELEMENTS(g_textcache)) { - text = &textcache[cache_id]; + text = &g_textcache[cache_id]; if (text->data != NULL) xfree(text->data); @@ -154,7 +211,7 @@ /* DESKTOP CACHE */ -static uint8 deskcache[0x38400 * 4]; +static uint8 g_deskcache[0x38400 * 4]; /* Retrieve desktop data from the cache */ uint8 * @@ -162,9 +219,12 @@ { int length = cx * cy * bytes_per_pixel; - if ((offset + length) <= sizeof(deskcache)) + if (offset > sizeof(g_deskcache)) + offset = 0; + + if ((offset + length) <= sizeof(g_deskcache)) { - return &deskcache[offset]; + return &g_deskcache[offset]; } error("get desktop %d:%d\n", offset, length); @@ -177,12 +237,15 @@ { int length = cx * cy * bytes_per_pixel; - if ((offset + length) <= sizeof(deskcache)) + if (offset > sizeof(g_deskcache)) + offset = 0; + + if ((offset + length) <= sizeof(g_deskcache)) { cx *= bytes_per_pixel; while (cy--) { - memcpy(&deskcache[offset], data, cx); + memcpy(&g_deskcache[offset], data, cx); data += scanline; offset += cx; } @@ -195,7 +258,7 @@ /* CURSOR CACHE */ -static HCURSOR cursorcache[0x20]; +static HCURSOR g_cursorcache[0x20]; /* Retrieve cursor from cache */ HCURSOR @@ -203,9 +266,9 @@ { HCURSOR cursor; - if (cache_idx < NUM_ELEMENTS(cursorcache)) + if (cache_idx < NUM_ELEMENTS(g_cursorcache)) { - cursor = cursorcache[cache_idx]; + cursor = g_cursorcache[cache_idx]; if (cursor != NULL) return cursor; } @@ -220,13 +283,13 @@ { HCURSOR old; - if (cache_idx < NUM_ELEMENTS(cursorcache)) + if (cache_idx < NUM_ELEMENTS(g_cursorcache)) { - old = cursorcache[cache_idx]; + old = g_cursorcache[cache_idx]; if (old != NULL) ui_destroy_cursor(old); - cursorcache[cache_idx] = cursor; + g_cursorcache[cache_idx] = cursor; } else {