mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-01-07 16:03:51 +08:00
libfreerdp-cache: fix offscreen bitmap memory leaks and issues with Windows XP
This commit is contained in:
parent
809dbf7744
commit
f2b88dcfae
1
include/freerdp/cache/offscreen.h
vendored
1
include/freerdp/cache/offscreen.h
vendored
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user