Unified bitmap drawing.

This commit is contained in:
Armin Novak
2016-07-20 15:34:06 +02:00
parent b8ff3cb235
commit 032bdef955
6 changed files with 109 additions and 121 deletions

View File

@@ -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);

View File

@@ -53,8 +53,6 @@ struct rdp_bitmap_cache
UINT32 paddingB[32 - 18]; /* 18 */
/* internal */
rdpBitmap* bitmap;
rdpUpdate* update;
rdpContext* context;
rdpSettings* settings;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);