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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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,
|
||||
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
|
||||
|
||||
|
@ -126,6 +126,13 @@ typedef struct guac_common_surface {
|
||||
*/
|
||||
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,
|
||||
* 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,
|
||||
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
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
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,
|
||||
display->client->socket, layer, width, height);
|
||||
|
||||
/* Apply current display losslessness */
|
||||
guac_common_surface_set_lossless(surface, display->lossless);
|
||||
|
||||
/* Add layer and surface to list */
|
||||
guac_common_display_layer* display_layer =
|
||||
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,
|
||||
display->client->socket, buffer, width, height);
|
||||
|
||||
/* Apply current display losslessness */
|
||||
guac_common_surface_set_lossless(surface, display->lossless);
|
||||
|
||||
/* Add buffer and surface to list */
|
||||
guac_common_display_layer* display_layer =
|
||||
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) {
|
||||
|
||||
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,
|
||||
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 */
|
||||
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 */
|
||||
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
||||
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);
|
||||
surface->realized = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user