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;
|
} 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_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_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);
|
void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap);
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "rdp_bitmap.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_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
guac_socket* socket = client->socket;
|
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 not cached, cache if necessary */
|
||||||
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
|
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
|
||||||
&& ((guac_rdp_bitmap*) bitmap)->used >= 2) {
|
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
|
||||||
__guac_rdp_cache_bitmap(context, bitmap);
|
guac_rdp_cache_bitmap(context, bitmap);
|
||||||
|
|
||||||
guac_client_log_info(client, "Deferred cache! bitmap used=%i", ((guac_rdp_bitmap*) bitmap)->used);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If cached, retrieve from cache */
|
/* If cached, retrieve from cache */
|
||||||
if (((guac_rdp_bitmap*) bitmap)->layer != NULL)
|
if (((guac_rdp_bitmap*) bitmap)->layer != NULL)
|
||||||
@ -158,8 +154,6 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
|
|||||||
/* Increment usage counter */
|
/* Increment usage counter */
|
||||||
((guac_rdp_bitmap*) bitmap)->used++;
|
((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) {
|
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 not available as a surface, make available. */
|
||||||
if (((guac_rdp_bitmap*) bitmap)->layer == NULL)
|
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
|
((rdp_guac_client_data*) client->data)->current_surface
|
||||||
= ((guac_rdp_bitmap*) bitmap)->layer;
|
= ((guac_rdp_bitmap*) bitmap)->layer;
|
||||||
|
@ -159,8 +159,6 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
|||||||
guac_socket* socket = client->socket;
|
guac_socket* socket = client->socket;
|
||||||
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
|
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
|
||||||
|
|
||||||
if (bitmap->layer != NULL) {
|
|
||||||
|
|
||||||
switch (memblt->bRop) {
|
switch (memblt->bRop) {
|
||||||
|
|
||||||
/* If blackness, send black rectangle */
|
/* If blackness, send black rectangle */
|
||||||
@ -180,12 +178,45 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
|||||||
|
|
||||||
/* If operation is just SRC, simply copy */
|
/* If operation is just SRC, simply copy */
|
||||||
case 0xCC:
|
case 0xCC:
|
||||||
|
|
||||||
|
/* 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,
|
guac_protocol_send_copy(socket,
|
||||||
bitmap->layer,
|
bitmap->layer,
|
||||||
memblt->nXSrc, memblt->nYSrc,
|
memblt->nXSrc, memblt->nYSrc,
|
||||||
memblt->nWidth, memblt->nHeight,
|
memblt->nWidth, memblt->nHeight,
|
||||||
GUAC_COMP_OVER,
|
GUAC_COMP_OVER,
|
||||||
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
||||||
|
|
||||||
|
/* Increment usage counter */
|
||||||
|
((guac_rdp_bitmap*) bitmap)->used++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If whiteness, send white rectangle */
|
/* If whiteness, send white rectangle */
|
||||||
@ -201,6 +232,11 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
|||||||
|
|
||||||
/* Otherwise, use transfer */
|
/* Otherwise, use transfer */
|
||||||
default:
|
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,
|
guac_protocol_send_transfer(socket,
|
||||||
bitmap->layer,
|
bitmap->layer,
|
||||||
memblt->nXSrc, memblt->nYSrc,
|
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),
|
guac_rdp_rop3_transfer_function(client, memblt->bRop),
|
||||||
current_layer, memblt->nLeftRect, memblt->nTopRect);
|
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