libfreerdp-cache: fix offscreen bitmap memory leaks and issues with Windows XP

This commit is contained in:
Marc-André Moreau 2011-11-11 01:48:31 -05:00
parent 809dbf7744
commit f2b88dcfae
3 changed files with 42 additions and 13 deletions

View File

@ -42,6 +42,7 @@ struct rdp_offscreen_cache
FREERDP_API rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index);
FREERDP_API void offscreen_cache_put(rdpOffscreenCache* offscreen_cache, uint16 index, rdpBitmap* bitmap);
FREERDP_API void offscreen_cache_delete(rdpOffscreenCache* offscreen, uint16 index);
FREERDP_API void offscreen_cache_register_callbacks(rdpUpdate* update);

View File

@ -51,7 +51,12 @@ void update_gdi_mem3blt(rdpUpdate* update, MEM3BLT_ORDER* mem3blt)
IFCALL(cache->bitmap->Mem3Blt, update, mem3blt);
}
void update_gdi_cache_bitmap(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap)
void update_gdi_cache_bitmap(rdpUpdate* update, CACHE_BITMAP_ORDER* cache_bitmap)
{
printf("Warning: CacheBitmapV1 Unimplemented\n");
}
void update_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
@ -59,20 +64,20 @@ void update_gdi_cache_bitmap(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bit
bitmap = Bitmap_Alloc(update->context);
Bitmap_SetDimensions(update->context, bitmap, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight);
Bitmap_SetDimensions(update->context, bitmap, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight);
bitmap->Decompress(update->context, bitmap,
cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight,
cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, cache_bitmap->compressed);
cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight,
cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed);
bitmap->New(update->context, bitmap);
prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex);
prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex);
if (prevBitmap != NULL)
Bitmap_Free(update->context, prevBitmap);
bitmap_cache_put(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex, bitmap);
bitmap_cache_put(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex, bitmap);
}
void update_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap_update)
@ -174,7 +179,8 @@ void bitmap_cache_register_callbacks(rdpUpdate* update)
update->MemBlt = update_gdi_memblt;
update->Mem3Blt = update_gdi_mem3blt;
update->CacheBitmapV2 = update_gdi_cache_bitmap;
update->CacheBitmap = update_gdi_cache_bitmap;
update->CacheBitmapV2 = update_gdi_cache_bitmap_v2;
update->BitmapUpdate = update_gdi_bitmap_update;
}

View File

@ -24,8 +24,9 @@
void update_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
int i;
uint16 index;
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
rdpCache* cache = update->context->cache;
bitmap = Bitmap_Alloc(update->context);
@ -35,15 +36,17 @@ void update_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITM
bitmap->New(update->context, bitmap);
prevBitmap = offscreen_cache_get(cache->offscreen, create_offscreen_bitmap->id);
if (prevBitmap != NULL)
Bitmap_Free(update->context, prevBitmap);
offscreen_cache_delete(cache->offscreen, create_offscreen_bitmap->id);
offscreen_cache_put(cache->offscreen, create_offscreen_bitmap->id, bitmap);
if(cache->offscreen->currentSurface == create_offscreen_bitmap->id)
Bitmap_SetSurface(update->context, bitmap, False);
for (i = 0; i < create_offscreen_bitmap->deleteList.cIndices; i++)
{
index = create_offscreen_bitmap->deleteList.indices[i];
offscreen_cache_delete(cache->offscreen, index);
}
}
void update_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
@ -93,9 +96,28 @@ void offscreen_cache_put(rdpOffscreenCache* offscreen, uint16 index, rdpBitmap*
return;
}
offscreen_cache_delete(offscreen, index);
offscreen->entries[index] = bitmap;
}
void offscreen_cache_delete(rdpOffscreenCache* offscreen, uint16 index)
{
rdpBitmap* prevBitmap;
if (index > offscreen->maxEntries)
{
printf("invalid offscreen bitmap index (delete): 0x%04X\n", index);
return;
}
prevBitmap = offscreen->entries[index];
if (prevBitmap != NULL)
Bitmap_Free(offscreen->update->context, prevBitmap);
offscreen->entries[index] = NULL;
}
void offscreen_cache_register_callbacks(rdpUpdate* update)
{
update->CreateOffscreenBitmap = update_gdi_create_offscreen_bitmap;