libfreerdp-cache: fix brush cache

This commit is contained in:
Marc-André Moreau 2011-08-07 21:12:36 -04:00
parent 58c161adcc
commit b9c9d31451
10 changed files with 175 additions and 163 deletions

View File

@ -117,9 +117,9 @@ void test_read_patblt_order(void)
CU_ASSERT(patblt.bRop == 240);
CU_ASSERT(patblt.backColor == 0x00FFFF);
CU_ASSERT(patblt.foreColor == 0x00EF5B);
CU_ASSERT(patblt.brushOrgX == 0);
CU_ASSERT(patblt.brushOrgY == 0);
CU_ASSERT(patblt.brushStyle == (BMF_1BPP | CACHED_BRUSH));
CU_ASSERT(patblt.brush.x == 0);
CU_ASSERT(patblt.brush.y == 0);
CU_ASSERT(patblt.brush.style == (BMF_1BPP | CACHED_BRUSH));
CU_ASSERT(stream_get_length(s) == (sizeof(patblt_order) - 1));
}
@ -544,9 +544,9 @@ void test_read_polygon_cb_order(void)
CU_ASSERT(polygon_cb.fillMode == 1);
CU_ASSERT(polygon_cb.backColor == 0);
CU_ASSERT(polygon_cb.foreColor == 0x00000008);
CU_ASSERT(polygon_cb.brushOrgX == 4);
CU_ASSERT(polygon_cb.brushOrgY == 3);
CU_ASSERT(polygon_cb.brushStyle == 0x81);
CU_ASSERT(polygon_cb.brush.x == 4);
CU_ASSERT(polygon_cb.brush.y == 3);
CU_ASSERT(polygon_cb.brush.style == 0x81);
CU_ASSERT(polygon_cb.nDeltaEntries == 3);
CU_ASSERT(polygon_cb.cbData == 5);
@ -722,8 +722,9 @@ void test_read_switch_surface_order(void)
int opaque_rect_count;
int polyline_count;
int patblt_count;
uint8 orders_update[] =
uint8 orders_update_1[] =
"\x00\x00\x33\xd0\x07\x00\x80\xba\x0d\x0a\x7f\x1e\x2c\x4d\x00\x36"
"\x02\xd3\x00\x47\x00\x4d\x00\xf0\x01\x87\x00\xc2\xdc\xff\x05\x7f"
"\x0f\x67\x01\x90\x01\x8e\x01\xa5\x01\x67\x01\x90\x01\x28\x00\x16"
@ -733,6 +734,11 @@ uint8 orders_update[] =
"\x03\x15\x0f\xf0\x65\x01\x15\xfe\x65\x01\xb0\xfd\x1d\x16\x01\xf0"
"\xff\xff\x01\x01\x7a";
uint8 orders_update_2[] =
"\x00\x00\x45\x62\x03\x00\x93\x14\x55\x01\x50\xff\xff\xff\x55\x01"
"\x50\x01\x01\x01\x55\x01\x50\xff\xff\xff\x16\x00\x17\x00\xea\x03"
"\xea\x03\x02\x00\x85\x02\x16\x00\x02\x00\x00\x00\x03\x00\x14\xb2";
void test_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect)
{
opaque_rect_count++;
@ -743,6 +749,11 @@ void test_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline)
polyline_count++;
}
void test_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
{
patblt_count++;
}
void test_update_recv_orders(void)
{
STREAM* s;
@ -750,17 +761,27 @@ void test_update_recv_orders(void)
s = stream_new(0);
update = update_new(NULL);
s->p = s->data = orders_update;
opaque_rect_count = 0;
polyline_count = 0;
patblt_count = 0;
update->OpaqueRect = test_opaque_rect;
update->Polyline = test_polyline;
update->PatBlt = test_patblt;
s->p = s->data = orders_update_1;
update_recv(update, s);
CU_ASSERT(opaque_rect_count == 5);
CU_ASSERT(polyline_count == 2);
update->order_info.orderType = ORDER_TYPE_PATBLT;
s->p = s->data = orders_update_2;
update_recv(update, s);
CU_ASSERT(patblt_count == 3);
}

View File

@ -33,6 +33,19 @@ struct _BOUNDS
};
typedef struct _BOUNDS BOUNDS;
struct _BRUSH
{
uint8 x;
uint8 y;
uint8 bpp;
uint8 style;
uint8 hatch;
uint8 index;
uint8* data;
uint8 p8x8[8];
};
typedef struct _BRUSH BRUSH;
/* Bitmap Updates */
struct _BITMAP_DATA
@ -102,11 +115,7 @@ struct _PATBLT_ORDER
uint8 bRop;
uint32 backColor;
uint32 foreColor;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
};
typedef struct _PATBLT_ORDER PATBLT_ORDER;
@ -173,11 +182,7 @@ struct _MULTI_PATBLT_ORDER
uint8 bRop;
uint32 backColor;
uint32 foreColor;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
uint8 numRectangles;
uint16 cbData;
DELTA_RECT rectangles[45];
@ -285,11 +290,7 @@ struct _MEM3BLT_ORDER
sint16 nYSrc;
uint32 backColor;
uint32 foreColor;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
uint16 cacheIndex;
};
typedef struct _MEM3BLT_ORDER MEM3BLT_ORDER;
@ -321,11 +322,7 @@ struct _GLYPH_INDEX_ORDER
sint16 opTop;
sint16 opRight;
sint16 opBottom;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
sint16 x;
sint16 y;
uint8 cbData;
@ -398,11 +395,7 @@ struct _POLYGON_CB_ORDER
uint8 fillMode;
uint32 backColor;
uint32 foreColor;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
uint8 nDeltaEntries;
uint8 cbData;
uint8* codeDeltaList;
@ -431,11 +424,7 @@ struct _ELLIPSE_CB_ORDER
uint8 fillMode;
uint32 backColor;
uint32 foreColor;
uint8 brushOrgX;
uint8 brushOrgY;
uint8 brushStyle;
uint8 brushHatch;
uint8 brushExtra[7];
BRUSH brush;
};
typedef struct _ELLIPSE_CB_ORDER ELLIPSE_CB_ORDER;

View File

@ -26,18 +26,32 @@ void* brush_get(rdpBrush* brush, uint8 index, uint8* bpp)
{
void* entry;
if (index > brush->maxEntries)
if (*bpp == 1)
{
printf("invalid brush index: 0x%04X\n", index);
return NULL;
}
if (index > brush->maxMonoEntries)
{
printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
return NULL;
}
*bpp = brush->entries[index].bpp;
entry = brush->entries[index].entry;
*bpp = brush->monoEntries[index].bpp;
entry = brush->monoEntries[index].entry;
}
else
{
if (index > brush->maxEntries)
{
printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
return NULL;
}
*bpp = brush->entries[index].bpp;
entry = brush->entries[index].entry;
}
if (entry == NULL)
{
printf("invalid brush at index: 0x%04X\n", index);
printf("invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index);
return NULL;
}
@ -46,14 +60,28 @@ void* brush_get(rdpBrush* brush, uint8 index, uint8* bpp)
void brush_put(rdpBrush* brush, uint8 index, void* entry, uint8 bpp)
{
if (index > brush->maxEntries)
if (bpp == 1)
{
printf("invalid brush index: 0x%04X\n", index);
return;
}
if (index > brush->maxMonoEntries)
{
printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
return;
}
brush->entries[index].bpp = bpp;
brush->entries[index].entry = entry;
brush->monoEntries[index].bpp = bpp;
brush->monoEntries[index].entry = entry;
}
else
{
if (index > brush->maxEntries)
{
printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
return;
}
brush->entries[index].bpp = bpp;
brush->entries[index].entry = entry;
}
}
rdpBrush* brush_new(rdpSettings* settings)
@ -67,8 +95,10 @@ rdpBrush* brush_new(rdpSettings* settings)
brush->settings = settings;
brush->maxEntries = 64;
brush->maxMonoEntries = 64;
brush->entries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxEntries);
brush->monoEntries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxMonoEntries);
}
return brush;

View File

@ -32,9 +32,11 @@ typedef struct _BRUSH_ENTRY BRUSH_ENTRY;
struct rdp_brush
{
uint8 maxEntries;
rdpSettings* settings;
uint8 maxEntries;
uint8 maxMonoEntries;
BRUSH_ENTRY* entries;
BRUSH_ENTRY* monoEntries;
};
typedef struct rdp_brush rdpBrush;

View File

@ -170,6 +170,7 @@ void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags)
void rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings)
{
rdp->activated = True;
update_reset_state(rdp->update);
rdp->update->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
IFCALL(rdp->update->SwitchSurface, rdp->update, &(rdp->update->switch_surface));
}

View File

@ -283,6 +283,44 @@ void update_read_delta(STREAM* s, sint16* value)
}
}
void update_read_brush(STREAM* s, BRUSH* brush, uint8 fieldFlags)
{
if (fieldFlags & ORDER_FIELD_01)
stream_read_uint8(s, brush->x);
if (fieldFlags & ORDER_FIELD_02)
stream_read_uint8(s, brush->y);
if (fieldFlags & ORDER_FIELD_03)
stream_read_uint8(s, brush->style);
if (fieldFlags & ORDER_FIELD_04)
stream_read_uint8(s, brush->hatch);
if (brush->style & CACHED_BRUSH)
{
brush->index = brush->hatch;
brush->bpp = BMF_BPP[brush->style & 0x0F];
if (brush->bpp == 0)
brush->bpp = 1;
}
if (fieldFlags & ORDER_FIELD_05)
{
brush->data = (uint8*) brush->p8x8;
stream_read_uint8(s, brush->data[7]);
stream_read_uint8(s, brush->data[6]);
stream_read_uint8(s, brush->data[5]);
stream_read_uint8(s, brush->data[4]);
stream_read_uint8(s, brush->data[3]);
stream_read_uint8(s, brush->data[2]);
stream_read_uint8(s, brush->data[1]);
brush->data[0] = brush->hatch;
}
}
void update_read_delta_rects(STREAM* s, DELTA_RECT* rectangles, int number)
{
int i;
@ -409,20 +447,7 @@ void update_read_patblt_order(STREAM* s, ORDER_INFO* orderInfo, PATBLT_ORDER* pa
if (orderInfo->fieldFlags & ORDER_FIELD_07)
update_read_color(s, &patblt->foreColor);
if (orderInfo->fieldFlags & ORDER_FIELD_08)
stream_read_uint8(s, patblt->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_09)
stream_read_uint8(s, patblt->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_10)
stream_read_uint8(s, patblt->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_11)
stream_read_uint8(s, patblt->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read(s, patblt->brushExtra, 7);
update_read_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7);
}
void update_read_scrblt_order(STREAM* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt)
@ -552,20 +577,7 @@ void update_read_multi_patblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_PATB
if (orderInfo->fieldFlags & ORDER_FIELD_07)
update_read_color(s, &multi_patblt->foreColor);
if (orderInfo->fieldFlags & ORDER_FIELD_08)
stream_read_uint8(s, multi_patblt->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_09)
stream_read_uint8(s, multi_patblt->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_10)
stream_read_uint8(s, multi_patblt->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_11)
stream_read_uint8(s, multi_patblt->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read(s, multi_patblt->brushExtra, 7);
update_read_brush(s, &multi_patblt->brush, orderInfo->fieldFlags >> 7);
if (orderInfo->fieldFlags & ORDER_FIELD_13)
stream_read_uint8(s, multi_patblt->numRectangles);
@ -809,20 +821,7 @@ void update_read_mem3blt_order(STREAM* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER*
if (orderInfo->fieldFlags & ORDER_FIELD_10)
update_read_color(s, &mem3blt->foreColor);
if (orderInfo->fieldFlags & ORDER_FIELD_11)
stream_read_uint8(s, mem3blt->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read_uint8(s, mem3blt->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_13)
stream_read_uint8(s, mem3blt->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_14)
stream_read_uint8(s, mem3blt->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_15)
stream_read(s, mem3blt->brushExtra, 7);
update_read_brush(s, &mem3blt->brush, orderInfo->fieldFlags >> 10);
if (orderInfo->fieldFlags & ORDER_FIELD_16)
stream_read_uint16(s, mem3blt->cacheIndex);
@ -893,20 +892,7 @@ void update_read_glyph_index_order(STREAM* s, ORDER_INFO* orderInfo, GLYPH_INDEX
if (orderInfo->fieldFlags & ORDER_FIELD_14)
stream_read_uint16(s, glyph_index->opBottom);
if (orderInfo->fieldFlags & ORDER_FIELD_15)
stream_read_uint8(s, glyph_index->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_16)
stream_read_uint8(s, glyph_index->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_17)
stream_read_uint8(s, glyph_index->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_18)
stream_read_uint8(s, glyph_index->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_19)
stream_read(s, glyph_index->brushExtra, 7);
update_read_brush(s, &glyph_index->brush, orderInfo->fieldFlags >> 14);
if (orderInfo->fieldFlags & ORDER_FIELD_20)
stream_read_uint16(s, glyph_index->x);
@ -1076,20 +1062,7 @@ void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_O
if (orderInfo->fieldFlags & ORDER_FIELD_06)
update_read_color(s, &polygon_cb->foreColor);
if (orderInfo->fieldFlags & ORDER_FIELD_07)
stream_read_uint8(s, polygon_cb->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_08)
stream_read_uint8(s, polygon_cb->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_09)
stream_read_uint8(s, polygon_cb->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_10)
stream_read_uint8(s, polygon_cb->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_11)
stream_read(s, polygon_cb->brushExtra, 7);
update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read_uint8(s, polygon_cb->nDeltaEntries);
@ -1151,20 +1124,7 @@ void update_read_ellipse_cb_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_CB_O
if (orderInfo->fieldFlags & ORDER_FIELD_08)
update_read_color(s, &ellipse_cb->foreColor);
if (orderInfo->fieldFlags & ORDER_FIELD_09)
stream_read_uint8(s, ellipse_cb->brushOrgX);
if (orderInfo->fieldFlags & ORDER_FIELD_10)
stream_read_uint8(s, ellipse_cb->brushOrgY);
if (orderInfo->fieldFlags & ORDER_FIELD_11)
stream_read_uint8(s, ellipse_cb->brushStyle);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read_uint8(s, ellipse_cb->brushHatch);
if (orderInfo->fieldFlags & ORDER_FIELD_13)
stream_read(s, ellipse_cb->brushExtra, 7);
update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8);
}
/* Secondary Drawing Orders */
@ -1409,6 +1369,7 @@ void update_decompress_brush(STREAM* s, uint8* output, uint8 bpp)
void update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_order, uint16 flags)
{
int i;
int size;
uint8 iBitmapFormat;
@ -1430,8 +1391,6 @@ void update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
if (cache_brush_order->bpp == 1)
{
int i;
if (cache_brush_order->length != 8)
{
printf("incompatible 1bpp brush of length:%d\n", cache_brush_order->length);
@ -1455,11 +1414,14 @@ void update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
else
{
/* uncompressed brush */
stream_read(s, cache_brush_order->data, cache_brush_order->length);
int scanline = (cache_brush_order->bpp / 8) * 8;
for (i = 7; i >= 0; i--)
{
stream_read(s, &cache_brush_order->data[i * scanline], scanline);
}
}
}
stream_read(s, cache_brush_order->data, cache_brush_order->length);
}
}
@ -1613,10 +1575,10 @@ void update_read_field_flags(STREAM* s, uint32* fieldFlags, uint8 flags, uint8 f
if (flags & ORDER_ZERO_FIELD_BYTE_BIT1)
{
if (fieldBytes < 2)
fieldBytes = 0;
else
if (fieldBytes > 1)
fieldBytes -= 2;
else
fieldBytes = 0;
}
*fieldFlags = 0;

View File

@ -233,7 +233,7 @@ void rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id)
rdp_write_share_control_header(s, length, PDU_TYPE_DATA, channel_id);
rdp_write_share_data_header(s, length, type, rdp->settings->share_id);
printf("send %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length);
//printf("send %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length);
stream_set_pos(s, length);
transport_write(rdp->transport, s);

View File

@ -162,7 +162,7 @@ void update_recv(rdpUpdate* update, STREAM* s)
stream_read_uint16(s, updateType); /* updateType (2 bytes) */
printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
//printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
IFCALL(update->BeginPaint, update);
@ -210,6 +210,12 @@ void update_recv(rdpUpdate* update, STREAM* s)
}
}
void update_reset_state(rdpUpdate* update)
{
memset(&update->order_info, 0, sizeof(ORDER_INFO));
update->order_info.orderType = ORDER_TYPE_PATBLT;
}
rdpUpdate* update_new(rdpRdp* rdp)
{
rdpUpdate* update;

View File

@ -37,6 +37,7 @@
rdpUpdate* update_new(rdpRdp* rdp);
void update_free(rdpUpdate* update);
void update_reset_state(rdpUpdate* update);
void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update);
void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update);

View File

@ -496,24 +496,19 @@ void gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt)
void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
{
uint8* data;
BRUSH* brush;
HGDI_BRUSH originalBrush;
GDI* gdi = GET_GDI(update);
if (patblt->brushStyle & CACHED_BRUSH)
brush = &patblt->brush;
if (brush->style & CACHED_BRUSH)
{
uint8 bpp;
uint8* cachedBrush;
data = (uint8*) &patblt->brushHatch;
cachedBrush = brush_get(gdi->cache->brush, patblt->brushHatch, &bpp);
memcpy(data, cachedBrush, (bpp / 8) * 64);
patblt->brushStyle = 0;
brush->data = brush_get(gdi->cache->brush, brush->index, &brush->bpp);
brush->style = BS_PATTERN;
}
patblt->brushStyle &= 0x7F;
if (patblt->brushStyle == BS_SOLID)
if (brush->style == BS_SOLID)
{
uint32 color;
originalBrush = gdi->drawing->hdc->brush;
@ -527,14 +522,19 @@ void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (patblt->brushStyle == BS_PATTERN)
else if (brush->style == BS_PATTERN)
{
HGDI_BITMAP hBmp;
data = (uint8*) &patblt->brushHatch;
data = gdi_mono_image_convert(data, 8, 8, gdi->srcBpp, gdi->dstBpp,
if (brush->bpp > 1)
{
data = gdi_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
}
else
{
data = gdi_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
patblt->backColor, patblt->foreColor, gdi->clrconv);
}
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
@ -549,7 +549,7 @@ void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
}
else
{
printf("unimplemented brush style:%d\n", patblt->brushStyle);
printf("unimplemented brush style:%d\n", brush->style);
}
}