Implement deferred cache via memblt.
This commit is contained in:
parent
8d9a0211d3
commit
82c2594320
@ -61,6 +61,7 @@ typedef struct guac_rdp_bitmap {
|
||||
|
||||
} guac_rdp_bitmap;
|
||||
|
||||
void guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap);
|
||||
void guac_rdp_bitmap_new(rdpContext* context, rdpBitmap* bitmap);
|
||||
void guac_rdp_bitmap_decompress(rdpContext* context, rdpBitmap* bitmap, uint8* data, int width, int height, int bpp, int length, boolean compressed);
|
||||
void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap);
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "client.h"
|
||||
#include "rdp_bitmap.h"
|
||||
|
||||
void __guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap) {
|
||||
void guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_socket* socket = client->socket;
|
||||
@ -122,12 +122,8 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
|
||||
|
||||
/* If not cached, cache if necessary */
|
||||
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
|
||||
&& ((guac_rdp_bitmap*) bitmap)->used >= 2) {
|
||||
__guac_rdp_cache_bitmap(context, bitmap);
|
||||
|
||||
guac_client_log_info(client, "Deferred cache! bitmap used=%i", ((guac_rdp_bitmap*) bitmap)->used);
|
||||
|
||||
}
|
||||
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
|
||||
guac_rdp_cache_bitmap(context, bitmap);
|
||||
|
||||
/* If cached, retrieve from cache */
|
||||
if (((guac_rdp_bitmap*) bitmap)->layer != NULL)
|
||||
@ -158,8 +154,6 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
|
||||
/* Increment usage counter */
|
||||
((guac_rdp_bitmap*) bitmap)->used++;
|
||||
|
||||
guac_client_log_info(client, "Used bitmap... used=%i", ((guac_rdp_bitmap*) bitmap)->used);
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
|
||||
@ -182,7 +176,7 @@ void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, boolean
|
||||
|
||||
/* If not available as a surface, make available. */
|
||||
if (((guac_rdp_bitmap*) bitmap)->layer == NULL)
|
||||
__guac_rdp_cache_bitmap(context, bitmap);
|
||||
guac_rdp_cache_bitmap(context, bitmap);
|
||||
|
||||
((rdp_guac_client_data*) client->data)->current_surface
|
||||
= ((guac_rdp_bitmap*) bitmap)->layer;
|
||||
|
@ -159,9 +159,7 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
||||
guac_socket* socket = client->socket;
|
||||
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
|
||||
|
||||
if (bitmap->layer != NULL) {
|
||||
|
||||
switch (memblt->bRop) {
|
||||
switch (memblt->bRop) {
|
||||
|
||||
/* If blackness, send black rectangle */
|
||||
case 0x00:
|
||||
@ -180,12 +178,45 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
||||
|
||||
/* If operation is just SRC, simply copy */
|
||||
case 0xCC:
|
||||
guac_protocol_send_copy(socket,
|
||||
bitmap->layer,
|
||||
memblt->nXSrc, memblt->nYSrc,
|
||||
memblt->nWidth, memblt->nHeight,
|
||||
GUAC_COMP_OVER,
|
||||
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
||||
|
||||
/* If not cached, cache if necessary */
|
||||
if (((guac_rdp_bitmap*) bitmap)->used >= 1)
|
||||
guac_rdp_cache_bitmap(context, memblt->bitmap);
|
||||
|
||||
/* If not cached, send as PNG */
|
||||
if (bitmap->layer == NULL) {
|
||||
if (memblt->bitmap->data != NULL) {
|
||||
|
||||
/* Create surface from image data */
|
||||
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
||||
memblt->bitmap->data + 4*(memblt->nXSrc + memblt->nYSrc*memblt->bitmap->width),
|
||||
CAIRO_FORMAT_RGB24,
|
||||
memblt->nWidth, memblt->nHeight,
|
||||
4*memblt->bitmap->width);
|
||||
|
||||
/* Send surface to buffer */
|
||||
guac_protocol_send_png(socket,
|
||||
GUAC_COMP_OVER, current_layer,
|
||||
memblt->nLeftRect, memblt->nTopRect, surface);
|
||||
|
||||
/* Free surface */
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, copy */
|
||||
else
|
||||
guac_protocol_send_copy(socket,
|
||||
bitmap->layer,
|
||||
memblt->nXSrc, memblt->nYSrc,
|
||||
memblt->nWidth, memblt->nHeight,
|
||||
GUAC_COMP_OVER,
|
||||
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
||||
|
||||
/* Increment usage counter */
|
||||
((guac_rdp_bitmap*) bitmap)->used++;
|
||||
|
||||
break;
|
||||
|
||||
/* If whiteness, send white rectangle */
|
||||
@ -201,6 +232,11 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
||||
|
||||
/* Otherwise, use transfer */
|
||||
default:
|
||||
|
||||
/* If not available as a surface, make available. */
|
||||
if (bitmap->layer == NULL)
|
||||
guac_rdp_cache_bitmap(context, memblt->bitmap);
|
||||
|
||||
guac_protocol_send_transfer(socket,
|
||||
bitmap->layer,
|
||||
memblt->nXSrc, memblt->nYSrc,
|
||||
@ -208,9 +244,10 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
||||
guac_rdp_rop3_transfer_function(client, memblt->bRop),
|
||||
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
||||
|
||||
}
|
||||
/* Increment usage counter */
|
||||
((guac_rdp_bitmap*) bitmap)->used++;
|
||||
|
||||
} /* end if layer not NULL */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user