GUAC-674: Inspect and re-inspect queue when combining.
This commit is contained in:
parent
7fc3fe1fdc
commit
78d7c3e9ab
@ -29,7 +29,6 @@
|
|||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
@ -252,6 +251,7 @@ static void __guac_common_surface_flush_to_queue(guac_common_surface* surface) {
|
|||||||
rect->y = surface->dirty_y;
|
rect->y = surface->dirty_y;
|
||||||
rect->width = surface->dirty_width;
|
rect->width = surface->dirty_width;
|
||||||
rect->height = surface->dirty_height;
|
rect->height = surface->dirty_height;
|
||||||
|
rect->flushed = 0;
|
||||||
|
|
||||||
/* Surface now flushed */
|
/* Surface now flushed */
|
||||||
surface->dirty = 0;
|
surface->dirty = 0;
|
||||||
@ -822,8 +822,8 @@ static int __guac_common_surface_png_rect_compare(const void* a, const void* b)
|
|||||||
guac_common_surface_png_rect* rb = (guac_common_surface_png_rect*) b;
|
guac_common_surface_png_rect* rb = (guac_common_surface_png_rect*) b;
|
||||||
|
|
||||||
/* Order roughly top to bottom, left to right */
|
/* Order roughly top to bottom, left to right */
|
||||||
if (ra->y >> 6 != rb->y >> 6) return ra->y - rb->y;
|
if (ra->y != rb->y) return ra->y - rb->y;
|
||||||
if (ra->x != rb->x) return ra->x - rb->x;
|
if (ra->x != rb->x) return ra->x - rb->x;
|
||||||
|
|
||||||
/* Wider updates should come first (more likely to intersect later) */
|
/* Wider updates should come first (more likely to intersect later) */
|
||||||
if (ra->width != rb->width) return rb->width - ra->width;
|
if (ra->width != rb->width) return rb->width - ra->width;
|
||||||
@ -837,11 +837,13 @@ void guac_common_surface_flush(guac_common_surface* surface) {
|
|||||||
|
|
||||||
guac_common_surface_png_rect* current = surface->png_queue;
|
guac_common_surface_png_rect* current = surface->png_queue;
|
||||||
|
|
||||||
int i;
|
int i, j;
|
||||||
|
int original_queue_length;
|
||||||
int flushed = 0;
|
int flushed = 0;
|
||||||
|
|
||||||
/* Flush final dirty rect to queue */
|
/* Flush final dirty rect to queue */
|
||||||
__guac_common_surface_flush_to_queue(surface);
|
__guac_common_surface_flush_to_queue(surface);
|
||||||
|
original_queue_length = surface->png_queue_length;
|
||||||
|
|
||||||
/* Sort updates to make combination less costly */
|
/* Sort updates to make combination less costly */
|
||||||
qsort(surface->png_queue, surface->png_queue_length, sizeof(guac_common_surface_png_rect),
|
qsort(surface->png_queue, surface->png_queue_length, sizeof(guac_common_surface_png_rect),
|
||||||
@ -850,30 +852,53 @@ void guac_common_surface_flush(guac_common_surface* surface) {
|
|||||||
/* Flush all rects in queue */
|
/* Flush all rects in queue */
|
||||||
for (i=0; i < surface->png_queue_length; i++) {
|
for (i=0; i < surface->png_queue_length; i++) {
|
||||||
|
|
||||||
int x = current->x;
|
/* Get next unflushed candidate */
|
||||||
int y = current->y;
|
guac_common_surface_png_rect* candidate = current;
|
||||||
int w = current->width;
|
if (!candidate->flushed) {
|
||||||
int h = current->height;
|
|
||||||
|
int combined = 0;
|
||||||
|
|
||||||
|
/* Build up rect as much as possible */
|
||||||
|
for (j=i; j < surface->png_queue_length; j++) {
|
||||||
|
|
||||||
|
if (!candidate->flushed) {
|
||||||
|
|
||||||
|
int x = candidate->x;
|
||||||
|
int y = candidate->y;
|
||||||
|
int w = candidate->width;
|
||||||
|
int h = candidate->height;
|
||||||
|
|
||||||
|
/* Combine if reasonable */
|
||||||
|
if (__guac_common_should_combine(surface, x, y, w, h, 0) || !surface->dirty) {
|
||||||
|
__guac_common_mark_dirty(surface, x, y, w, h);
|
||||||
|
candidate->flushed = 1;
|
||||||
|
combined++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
candidate++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-add to queue if there's room and this update was modified or we expect others might be */
|
||||||
|
if ((combined > 1 || i < original_queue_length)
|
||||||
|
&& surface->png_queue_length < GUAC_COMMON_SURFACE_QUEUE_SIZE)
|
||||||
|
__guac_common_surface_flush_to_queue(surface);
|
||||||
|
|
||||||
|
/* Flush as PNG otherwise */
|
||||||
|
else {
|
||||||
|
if (surface->dirty) flushed++;
|
||||||
|
__guac_common_surface_flush_to_png(surface);
|
||||||
|
}
|
||||||
|
|
||||||
/* Flush if not combining */
|
|
||||||
if (!__guac_common_should_combine(surface, x, y, w, h, 0)) {
|
|
||||||
if (surface->dirty) flushed++;
|
|
||||||
__guac_common_surface_flush_to_png(surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defer, attempt to combine with next rect */
|
|
||||||
__guac_common_mark_dirty(surface, x, y, w, h);
|
|
||||||
current++;
|
current++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the final png */
|
|
||||||
if (surface->dirty) flushed++;
|
|
||||||
__guac_common_surface_flush_to_png(surface);
|
|
||||||
|
|
||||||
/* Flush complete */
|
/* Flush complete */
|
||||||
if (flushed < surface->png_queue_length)
|
|
||||||
fprintf(stderr, "IMPROVEMENT: Flushed %i (originally %i) updates.\n", flushed, surface->png_queue_length);
|
|
||||||
surface->png_queue_length = 0;
|
surface->png_queue_length = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,11 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct guac_common_surface_png_rect {
|
typedef struct guac_common_surface_png_rect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this rectangle has been flushed.
|
||||||
|
*/
|
||||||
|
int flushed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The X coordinate of the upper-left corner of this rectangle.
|
* The X coordinate of the upper-left corner of this rectangle.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user