GUACAMOLE-1302: Add surface/display level support for forcing lossless compression.
This commit is contained in:
parent
7bbab0efdd
commit
0729a6cc73
@ -99,6 +99,13 @@ typedef struct guac_common_display {
|
|||||||
*/
|
*/
|
||||||
guac_common_display_layer* buffers;
|
guac_common_display_layer* buffers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-zero if all graphical updates for this display should use lossless
|
||||||
|
* compression, 0 otherwise. By default, newly-created displays will use
|
||||||
|
* lossy compression when heuristics determine it is appropriate.
|
||||||
|
*/
|
||||||
|
int lossless;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mutex which is locked internally when access to the display must be
|
* Mutex which is locked internally when access to the display must be
|
||||||
* synchronized. All public functions of guac_common_display should be
|
* synchronized. All public functions of guac_common_display should be
|
||||||
@ -228,5 +235,27 @@ void guac_common_display_free_layer(guac_common_display* display,
|
|||||||
void guac_common_display_free_buffer(guac_common_display* display,
|
void guac_common_display_free_buffer(guac_common_display* display,
|
||||||
guac_common_display_layer* display_buffer);
|
guac_common_display_layer* display_buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the overall lossless compression policy of the given display to the
|
||||||
|
* given value, affecting all current and future layers/buffers maintained by
|
||||||
|
* the display. By default, newly-created displays will use lossy compression
|
||||||
|
* for graphical updates when heuristics determine that doing so is
|
||||||
|
* appropriate. Specifying a non-zero value here will force all graphical
|
||||||
|
* updates to always use lossless compression, whereas specifying zero will
|
||||||
|
* restore the default policy.
|
||||||
|
*
|
||||||
|
* Note that this can also be adjusted on a per-layer / per-buffer basis with
|
||||||
|
* guac_common_surface_set_lossless().
|
||||||
|
*
|
||||||
|
* @param display
|
||||||
|
* The display to modify.
|
||||||
|
*
|
||||||
|
* @param lossless
|
||||||
|
* Non-zero if all graphical updates for this display should use lossless
|
||||||
|
* compression, 0 otherwise.
|
||||||
|
*/
|
||||||
|
void guac_common_display_set_lossless(guac_common_display* display,
|
||||||
|
int lossless);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -126,6 +126,13 @@ typedef struct guac_common_surface {
|
|||||||
*/
|
*/
|
||||||
int touches;
|
int touches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-zero if all graphical updates for this surface should use lossless
|
||||||
|
* compression, 0 otherwise. By default, newly-created surfaces will use
|
||||||
|
* lossy compression when heuristics determine it is appropriate.
|
||||||
|
*/
|
||||||
|
int lossless;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The X coordinate of the upper-left corner of this layer, in pixels,
|
* The X coordinate of the upper-left corner of this layer, in pixels,
|
||||||
* relative to its parent layer. This is only applicable to visible
|
* relative to its parent layer. This is only applicable to visible
|
||||||
@ -510,5 +517,23 @@ void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
|
|||||||
void guac_common_surface_set_multitouch(guac_common_surface* surface,
|
void guac_common_surface_set_multitouch(guac_common_surface* surface,
|
||||||
int touches);
|
int touches);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the lossless compression policy of the given surface to the given
|
||||||
|
* value. By default, newly-created surfaces will use lossy compression for
|
||||||
|
* graphical updates when heuristics determine that doing so is appropriate.
|
||||||
|
* Specifying a non-zero value here will force all graphical updates to always
|
||||||
|
* use lossless compression, whereas specifying zero will restore the default
|
||||||
|
* policy.
|
||||||
|
*
|
||||||
|
* @param surface
|
||||||
|
* The surface to modify.
|
||||||
|
*
|
||||||
|
* @param lossless
|
||||||
|
* Non-zero if all graphical updates for this surface should use lossless
|
||||||
|
* compression, 0 otherwise.
|
||||||
|
*/
|
||||||
|
void guac_common_surface_set_lossless(guac_common_surface* surface,
|
||||||
|
int lossless);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -182,6 +182,30 @@ void guac_common_display_dup(guac_common_display* display, guac_user* user,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_common_display_set_lossless(guac_common_display* display,
|
||||||
|
int lossless) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&display->_lock);
|
||||||
|
|
||||||
|
/* Update lossless setting to be applied to all newly-allocated
|
||||||
|
* layers/buffers */
|
||||||
|
display->lossless = lossless;
|
||||||
|
|
||||||
|
/* Update losslessness of all allocated layers/buffers */
|
||||||
|
guac_common_display_layer* current = display->layers;
|
||||||
|
while (current != NULL) {
|
||||||
|
guac_common_surface_set_lossless(current->surface, lossless);
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update losslessness of default display layer (not included within layers
|
||||||
|
* list) */
|
||||||
|
guac_common_surface_set_lossless(display->default_surface, lossless);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&display->_lock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_common_display_flush(guac_common_display* display) {
|
void guac_common_display_flush(guac_common_display* display) {
|
||||||
|
|
||||||
pthread_mutex_lock(&display->_lock);
|
pthread_mutex_lock(&display->_lock);
|
||||||
@ -287,6 +311,9 @@ guac_common_display_layer* guac_common_display_alloc_layer(
|
|||||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||||
display->client->socket, layer, width, height);
|
display->client->socket, layer, width, height);
|
||||||
|
|
||||||
|
/* Apply current display losslessness */
|
||||||
|
guac_common_surface_set_lossless(surface, display->lossless);
|
||||||
|
|
||||||
/* Add layer and surface to list */
|
/* Add layer and surface to list */
|
||||||
guac_common_display_layer* display_layer =
|
guac_common_display_layer* display_layer =
|
||||||
guac_common_display_add_layer(&display->layers, layer, surface);
|
guac_common_display_add_layer(&display->layers, layer, surface);
|
||||||
@ -308,6 +335,9 @@ guac_common_display_layer* guac_common_display_alloc_buffer(
|
|||||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||||
display->client->socket, buffer, width, height);
|
display->client->socket, buffer, width, height);
|
||||||
|
|
||||||
|
/* Apply current display losslessness */
|
||||||
|
guac_common_surface_set_lossless(surface, display->lossless);
|
||||||
|
|
||||||
/* Add buffer and surface to list */
|
/* Add buffer and surface to list */
|
||||||
guac_common_display_layer* display_layer =
|
guac_common_display_layer* display_layer =
|
||||||
guac_common_display_add_layer(&display->buffers, buffer, surface);
|
guac_common_display_add_layer(&display->buffers, buffer, surface);
|
||||||
|
@ -116,6 +116,15 @@ void guac_common_surface_set_multitouch(guac_common_surface* surface,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_common_surface_set_lossless(guac_common_surface* surface,
|
||||||
|
int lossless) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&surface->_lock);
|
||||||
|
surface->lossless = lossless;
|
||||||
|
pthread_mutex_unlock(&surface->_lock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_common_surface_move(guac_common_surface* surface, int x, int y) {
|
void guac_common_surface_move(guac_common_surface* surface, int x, int y) {
|
||||||
|
|
||||||
pthread_mutex_lock(&surface->_lock);
|
pthread_mutex_lock(&surface->_lock);
|
||||||
@ -534,6 +543,10 @@ static int __guac_common_surface_png_optimality(guac_common_surface* surface,
|
|||||||
static int __guac_common_surface_should_use_jpeg(guac_common_surface* surface,
|
static int __guac_common_surface_should_use_jpeg(guac_common_surface* surface,
|
||||||
const guac_common_rect* rect) {
|
const guac_common_rect* rect) {
|
||||||
|
|
||||||
|
/* Do not use JPEG if lossless quality is required */
|
||||||
|
if (surface->lossless)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Calculate the average framerate for the given rect */
|
/* Calculate the average framerate for the given rect */
|
||||||
int framerate = __guac_common_surface_calculate_framerate(surface, rect);
|
int framerate = __guac_common_surface_calculate_framerate(surface, rect);
|
||||||
|
|
||||||
@ -1806,7 +1819,8 @@ static void __guac_common_surface_flush_to_webp(guac_common_surface* surface,
|
|||||||
/* Send WebP for rect */
|
/* Send WebP for rect */
|
||||||
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
||||||
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
||||||
guac_common_surface_suggest_quality(surface->client), 0);
|
guac_common_surface_suggest_quality(surface->client),
|
||||||
|
surface->lossless ? 1 : 0);
|
||||||
|
|
||||||
cairo_surface_destroy(rect);
|
cairo_surface_destroy(rect);
|
||||||
surface->realized = 1;
|
surface->realized = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user