mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Unified bitmap drawing.
This commit is contained in:
@@ -135,10 +135,6 @@ static BOOL xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
UINT32 SrcFormat;
|
||||
UINT32 bytesPerPixel;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
if (!Bitmap_SetDimensions(bitmap, width, height))
|
||||
return FALSE;
|
||||
|
||||
bytesPerPixel = (bpp + 7) / 8;
|
||||
size = width * height * 4;
|
||||
bitmap->data = (BYTE*) _aligned_malloc(size, 16);
|
||||
|
||||
2
include/freerdp/cache/bitmap.h
vendored
2
include/freerdp/cache/bitmap.h
vendored
@@ -53,8 +53,6 @@ struct rdp_bitmap_cache
|
||||
UINT32 paddingB[32 - 18]; /* 18 */
|
||||
|
||||
/* internal */
|
||||
|
||||
rdpBitmap* bitmap;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
rdpSettings* settings;
|
||||
|
||||
135
libfreerdp/cache/bitmap.c
vendored
135
libfreerdp/cache/bitmap.c
vendored
@@ -36,12 +36,12 @@
|
||||
#define TAG FREERDP_TAG("cache.bitmap")
|
||||
|
||||
static rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
||||
UINT32 index);
|
||||
UINT32 index);
|
||||
static void bitmap_cache_put(rdpBitmapCache* bitmap_cache, UINT32 id,
|
||||
UINT32 index, rdpBitmap* bitmap);
|
||||
UINT32 index, rdpBitmap* bitmap);
|
||||
|
||||
static BOOL update_gdi_memblt(rdpContext* context,
|
||||
MEMBLT_ORDER* memblt)
|
||||
MEMBLT_ORDER* memblt)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpCache* cache = context->cache;
|
||||
@@ -50,7 +50,7 @@ static BOOL update_gdi_memblt(rdpContext* context,
|
||||
bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId,
|
||||
memblt->cacheIndex);
|
||||
memblt->cacheIndex);
|
||||
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (bitmap == NULL)
|
||||
@@ -61,7 +61,7 @@ static BOOL update_gdi_memblt(rdpContext* context,
|
||||
}
|
||||
|
||||
static BOOL update_gdi_mem3blt(rdpContext* context,
|
||||
MEM3BLT_ORDER* mem3blt)
|
||||
MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
BYTE style;
|
||||
rdpBitmap* bitmap;
|
||||
@@ -73,7 +73,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context,
|
||||
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId,
|
||||
mem3blt->cacheIndex);
|
||||
mem3blt->cacheIndex);
|
||||
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (!bitmap)
|
||||
@@ -98,7 +98,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context,
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
||||
const CACHE_BITMAP_ORDER* cacheBitmap)
|
||||
const CACHE_BITMAP_ORDER* cacheBitmap)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpBitmap* prevBitmap;
|
||||
@@ -108,11 +108,14 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
||||
if (!bitmap)
|
||||
return FALSE;
|
||||
|
||||
Bitmap_SetDimensions(bitmap, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight,
|
||||
cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength,
|
||||
cacheBitmap->compressed, RDP_CODEC_ID_NONE))
|
||||
cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight,
|
||||
cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength,
|
||||
cacheBitmap->compressed, RDP_CODEC_ID_NONE))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
@@ -125,18 +128,18 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
||||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId,
|
||||
cacheBitmap->cacheIndex);
|
||||
cacheBitmap->cacheIndex);
|
||||
|
||||
if (prevBitmap != NULL)
|
||||
prevBitmap->Free(context, prevBitmap);
|
||||
|
||||
bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex,
|
||||
bitmap);
|
||||
bitmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap_v2(rdpContext* context,
|
||||
CACHE_BITMAP_V2_ORDER* cacheBitmapV2)
|
||||
CACHE_BITMAP_V2_ORDER* cacheBitmapV2)
|
||||
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
@@ -154,35 +157,41 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context,
|
||||
if ((settings->ColorDepth == 15) && (cacheBitmapV2->bitmapBpp == 16))
|
||||
cacheBitmapV2->bitmapBpp = settings->ColorDepth;
|
||||
|
||||
Bitmap_SetDimensions(bitmap, cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
cacheBitmapV2->bitmapDataStream,
|
||||
cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight,
|
||||
cacheBitmapV2->bitmapBpp,
|
||||
cacheBitmapV2->bitmapLength,
|
||||
cacheBitmapV2->compressed,
|
||||
RDP_CODEC_ID_NONE))
|
||||
cacheBitmapV2->bitmapDataStream,
|
||||
cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight,
|
||||
cacheBitmapV2->bitmapBpp,
|
||||
cacheBitmapV2->bitmapLength,
|
||||
cacheBitmapV2->compressed,
|
||||
RDP_CODEC_ID_NONE))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV2->cacheId,
|
||||
cacheBitmapV2->cacheIndex);
|
||||
cacheBitmapV2->cacheIndex);
|
||||
|
||||
if (!bitmap->New(context, bitmap))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (prevBitmap)
|
||||
prevBitmap->Free(context, prevBitmap);
|
||||
|
||||
bitmap_cache_put(cache->bitmap, cacheBitmapV2->cacheId,
|
||||
cacheBitmapV2->cacheIndex, bitmap);
|
||||
cacheBitmapV2->cacheIndex, bitmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap_v3(rdpContext* context,
|
||||
CACHE_BITMAP_V3_ORDER* cacheBitmapV3)
|
||||
CACHE_BITMAP_V3_ORDER* cacheBitmapV3)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpBitmap* prevBitmap;
|
||||
@@ -199,74 +208,83 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context,
|
||||
cacheBitmapV3->bpp = settings->ColorDepth;
|
||||
|
||||
compressed = (bitmapData->codecID != RDP_CODEC_ID_NONE);
|
||||
bitmap->Decompress(context, bitmap,
|
||||
bitmapData->data, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bpp, bitmapData->length, compressed,
|
||||
bitmapData->codecID);
|
||||
Bitmap_SetDimensions(bitmap, bitmapData->width, bitmapData->height);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
bitmapData->data, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bpp, bitmapData->length, compressed,
|
||||
bitmapData->codecID))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!bitmap->New(context, bitmap))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV3->cacheId,
|
||||
cacheBitmapV3->cacheIndex);
|
||||
cacheBitmapV3->cacheIndex);
|
||||
|
||||
if (prevBitmap)
|
||||
prevBitmap->Free(context, prevBitmap);
|
||||
|
||||
bitmap_cache_put(cache->bitmap, cacheBitmapV3->cacheId,
|
||||
cacheBitmapV3->cacheIndex, bitmap);
|
||||
cacheBitmapV3->cacheIndex, bitmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL update_gdi_bitmap_update(rdpContext* context,
|
||||
const BITMAP_UPDATE* bitmapUpdate)
|
||||
const BITMAP_UPDATE* bitmapUpdate)
|
||||
{
|
||||
UINT32 i;
|
||||
BOOL reused = TRUE;
|
||||
rdpBitmap* bitmap;
|
||||
rdpCache* cache = context->cache;
|
||||
|
||||
if (!cache->bitmap->bitmap)
|
||||
{
|
||||
cache->bitmap->bitmap = Bitmap_Alloc(context);
|
||||
cache->bitmap->bitmap->ephemeral = TRUE;
|
||||
reused = FALSE;
|
||||
}
|
||||
|
||||
bitmap = cache->bitmap->bitmap;
|
||||
|
||||
for (i = 0; i < bitmapUpdate->number; i++)
|
||||
{
|
||||
const BITMAP_DATA* bitmapData = &bitmapUpdate->rectangles[i];
|
||||
rdpBitmap* bitmap = Bitmap_Alloc(context);
|
||||
|
||||
if (!bitmap)
|
||||
return FALSE;
|
||||
|
||||
bitmap->format = gdi_get_pixel_format(bitmapData->bitsPerPixel, FALSE);
|
||||
bitmap->length = bitmapData->bitmapLength;
|
||||
bitmap->compressed = bitmapData->compressed;
|
||||
Bitmap_SetRectangle(bitmap,
|
||||
bitmapData->destLeft, bitmapData->destTop,
|
||||
bitmapData->destRight, bitmapData->destBottom);
|
||||
bitmapData->destLeft, bitmapData->destTop,
|
||||
bitmapData->destRight, bitmapData->destBottom);
|
||||
|
||||
bitmap->Decompress(context, bitmap,
|
||||
bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bitsPerPixel, bitmapData->bitmapLength,
|
||||
bitmapData->compressed, RDP_CODEC_ID_NONE);
|
||||
|
||||
if (reused)
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bitsPerPixel, bitmapData->bitmapLength,
|
||||
bitmapData->compressed, RDP_CODEC_ID_NONE))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
|
||||
reused = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!bitmap->New(context, bitmap))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!bitmap->Paint(context, bitmap))
|
||||
{
|
||||
bitmap->Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bitmap->Free(context, bitmap);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
||||
UINT32 index)
|
||||
UINT32 index)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
|
||||
@@ -291,7 +309,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
||||
}
|
||||
|
||||
void bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index,
|
||||
rdpBitmap* bitmap)
|
||||
rdpBitmap* bitmap)
|
||||
{
|
||||
if (id > bitmapCache->maxCells)
|
||||
{
|
||||
@@ -338,7 +356,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
|
||||
bitmapCache->context = bitmapCache->update->context;
|
||||
bitmapCache->maxCells = settings->BitmapCacheV2NumCells;
|
||||
bitmapCache->cells = (BITMAP_V2_CELL*) calloc(bitmapCache->maxCells,
|
||||
sizeof(BITMAP_V2_CELL));
|
||||
sizeof(BITMAP_V2_CELL));
|
||||
|
||||
if (!bitmapCache->cells)
|
||||
{
|
||||
@@ -351,7 +369,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
|
||||
bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries;
|
||||
/* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */
|
||||
bitmapCache->cells[i].entries = (rdpBitmap**) calloc((
|
||||
bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*));
|
||||
bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,9 +396,6 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache)
|
||||
free(bitmapCache->cells[i].entries);
|
||||
}
|
||||
|
||||
if (bitmapCache->bitmap)
|
||||
bitmapCache->bitmap->Free(bitmapCache->context, bitmapCache->bitmap);
|
||||
|
||||
free(bitmapCache->cells);
|
||||
free(bitmapCache);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ BOOL Bitmap_SetRectangle(rdpBitmap* bitmap,
|
||||
bitmap->top = top;
|
||||
bitmap->right = right;
|
||||
bitmap->bottom = bottom;
|
||||
bitmap->width = bitmap->right - bitmap->left + 1;
|
||||
bitmap->height = bitmap->bottom - bitmap->top + 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -86,6 +88,8 @@ BOOL Bitmap_SetDimensions(rdpBitmap* bitmap,
|
||||
if (!bitmap)
|
||||
return FALSE;
|
||||
|
||||
bitmap->right = bitmap->left + width - 1;
|
||||
bitmap->bottom = bitmap->top + height - 1;
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
return TRUE;
|
||||
|
||||
@@ -486,61 +486,40 @@ static BOOL gdi_bitmap_update(rdpContext* context,
|
||||
|
||||
for (index = 0; index < bitmapUpdate->number; index++)
|
||||
{
|
||||
const BITMAP_DATA* bitmap = &(bitmapUpdate->rectangles[index]);
|
||||
UINT32 nXSrc = 0;
|
||||
UINT32 nYSrc = 0;
|
||||
UINT32 nXDst = bitmap->destLeft;
|
||||
UINT32 nYDst = bitmap->destTop;
|
||||
UINT32 nWidth = MIN(bitmap->destRight,
|
||||
gdi->width - 1) - bitmap->destLeft + 1; /* clip width */
|
||||
UINT32 nHeight = MIN(bitmap->destBottom,
|
||||
gdi->height - 1) - bitmap->destTop + 1; /* clip height */
|
||||
const BYTE* pSrcData = bitmap->bitmapDataStream;
|
||||
UINT32 SrcSize = bitmap->bitmapLength;
|
||||
BOOL compressed = bitmap->compressed;
|
||||
UINT32 bitsPerPixel = bitmap->bitsPerPixel;
|
||||
const BITMAP_DATA* bitmapData = &(bitmapUpdate->rectangles[index]);
|
||||
rdpBitmap* bmp = Bitmap_Alloc(context);
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
if (bitsPerPixel < 32)
|
||||
{
|
||||
if (!interleaved_decompress(codecs->interleaved,
|
||||
pSrcData, SrcSize,
|
||||
bitmap->width, bitmap->height,
|
||||
bitsPerPixel,
|
||||
gdi->primary_buffer,
|
||||
gdi->primary->hdc->format,
|
||||
gdi->stride, nXDst, nYDst,
|
||||
nWidth, nHeight,
|
||||
&gdi->palette))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!planar_decompress(codecs->planar, pSrcData,
|
||||
SrcSize, bitmap->width, bitmap->height,
|
||||
gdi->primary_buffer,
|
||||
gdi->primary->hdc->format,
|
||||
gdi->stride,
|
||||
nXDst, nYDst, nWidth, nHeight, TRUE))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
|
||||
UINT32 nSrcStep = nWidth * GetBytesPerPixel(SrcFormat);
|
||||
if (!bmp)
|
||||
return FALSE;
|
||||
|
||||
if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format,
|
||||
gdi->stride,
|
||||
nXDst, nYDst, nWidth, nHeight,
|
||||
pSrcData, SrcFormat, nSrcStep,
|
||||
nXSrc, nYSrc, &gdi->palette))
|
||||
return FALSE;
|
||||
Bitmap_SetRectangle(bmp, bitmapData->destLeft, bitmapData->destTop,
|
||||
bitmapData->destRight, bitmapData->destBottom);
|
||||
|
||||
if (!bmp->Decompress(context, bmp, bitmapData->bitmapDataStream,
|
||||
bitmapData->width, bitmapData->height,
|
||||
bitmapData->bitsPerPixel, bitmapData->bitmapLength,
|
||||
bitmapData->compressed, RDP_CODEC_ID_NONE))
|
||||
{
|
||||
bmp->Free(context, bmp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst,
|
||||
nWidth, nHeight))
|
||||
if (!bmp->New(context, bmp))
|
||||
{
|
||||
bmp->Free(context, bmp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!bmp->Paint(context, bmp))
|
||||
{
|
||||
bmp->Free(context, bmp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bmp->Free(context, bmp);
|
||||
|
||||
if (!gdi_InvalidateRegion(gdi->primary->hdc, bmp->left, bmp->top,
|
||||
bmp->width, bmp->height))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,10 +141,6 @@ static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
UINT32 DstWidth = width;
|
||||
UINT32 DstHeight = height;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
if (!Bitmap_SetDimensions(bitmap, width, height))
|
||||
return FALSE;
|
||||
|
||||
bytesPerPixel = (bpp + 7) / 8;
|
||||
size = width * height * GetBytesPerPixel(gdi->dstFormat);
|
||||
bitmap->data = (BYTE*) _aligned_malloc(size, 16);
|
||||
|
||||
Reference in New Issue
Block a user