GUAC-240: Dynamically allocate heat map. Throw away heat map during resize.

This commit is contained in:
Michael Jumper 2015-08-17 16:02:19 -07:00
parent cc21092ac2
commit 62572073b0
2 changed files with 40 additions and 27 deletions

View File

@ -278,13 +278,19 @@ static unsigned int __guac_common_surface_calculate_framerate(
unsigned int sum_framerate = 0; unsigned int sum_framerate = 0;
unsigned int count = 0; unsigned int count = 0;
/* Get start of buffer at given coordinates */
const guac_common_surface_heat_rect* heat_row =
surface->heat_map + min_y * surface->width + min_x;
/* Iterate over all the heat map cells for the area /* Iterate over all the heat map cells for the area
* and calculate the average framerate */ * and calculate the average framerate */
for (y = min_y; y < max_y; y++) { for (y = min_y; y < max_y; y++) {
for (x = min_x; x < max_x; x++) {
const guac_common_surface_heat_rect* heat_rect = /* Get current row of heat map */
&surface->heat_map[y][x]; const guac_common_surface_heat_rect* heat_rect = heat_row;
/* For each cell in subset of row */
for (x = min_x; x < max_x; x++) {
/* Calculate indicies for latest and oldest history entries */ /* Calculate indicies for latest and oldest history entries */
int oldest_entry = heat_rect->oldest_entry; int oldest_entry = heat_rect->oldest_entry;
@ -301,9 +307,15 @@ static unsigned int __guac_common_surface_calculate_framerate(
sum_framerate += GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE sum_framerate += GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE
* 1000 / elapsed_time; * 1000 / elapsed_time;
/* Next heat map cell */
heat_rect++;
count++; count++;
} }
/* Next heat map row */
heat_row += surface->width;
} }
/* Calculate the average framerate over entire rect */ /* Calculate the average framerate over entire rect */
@ -433,12 +445,18 @@ static void __guac_common_surface_touch_rect(guac_common_surface* surface,
int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_MAP_CELL;
int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_MAP_CELL;
/* Get start of buffer at given coordinates */
guac_common_surface_heat_rect* heat_row =
surface->heat_map + min_y * surface->width + min_x;
/* Update all heat map cells which intersect with rectangle */ /* Update all heat map cells which intersect with rectangle */
for (y = min_y; y <= max_y; y++) { for (y = min_y; y <= max_y; y++) {
for (x = min_x; x <= max_x; x++) {
/* Get heat map cell at current location */ /* Get current row of heat map */
guac_common_surface_heat_rect* heat_rect = &surface->heat_map[y][x]; guac_common_surface_heat_rect* heat_rect = heat_row;
/* For each cell in subset of row */
for (x = min_x; x <= max_x; x++) {
/* Replace oldest entry with new timestamp */ /* Replace oldest entry with new timestamp */
heat_rect->history[heat_rect->oldest_entry] = time; heat_rect->history[heat_rect->oldest_entry] = time;
@ -449,7 +467,14 @@ static void __guac_common_surface_touch_rect(guac_common_surface* surface,
GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE) GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE)
heat_rect->oldest_entry = 0; heat_rect->oldest_entry = 0;
/* Advance to next heat map cell */
heat_rect++;
} }
/* Next heat map row */
heat_row += surface->width;
} }
} }
@ -909,6 +934,9 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client,
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w); surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
surface->buffer = calloc(h, surface->stride); surface->buffer = calloc(h, surface->stride);
/* Create corresponding heat map */
surface->heat_map = calloc(w*h, sizeof(guac_common_surface_heat_rect));
/* Reset clipping rect */ /* Reset clipping rect */
guac_common_surface_reset_clip(surface); guac_common_surface_reset_clip(surface);
@ -931,6 +959,7 @@ void guac_common_surface_free(guac_common_surface* surface) {
if (surface->realized) if (surface->realized)
guac_protocol_send_dispose(surface->socket, surface->layer); guac_protocol_send_dispose(surface->socket, surface->layer);
free(surface->heat_map);
free(surface->buffer); free(surface->buffer);
free(surface); free(surface);
@ -967,6 +996,10 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
/* Free old data */ /* Free old data */
free(old_buffer); free(old_buffer);
/* Allocate completely new heat map (can safely discard old stats) */
free(surface->heat_map);
surface->heat_map = calloc(w*h, sizeof(guac_common_surface_heat_rect));
/* Resize dirty rect to fit new surface dimensions */ /* Resize dirty rect to fit new surface dimensions */
if (surface->dirty) { if (surface->dirty) {
__guac_common_bound_rect(surface, &surface->dirty_rect, NULL, NULL); __guac_common_bound_rect(surface, &surface->dirty_rect, NULL, NULL);

View File

@ -37,31 +37,11 @@
*/ */
#define GUAC_COMMON_SURFACE_QUEUE_SIZE 256 #define GUAC_COMMON_SURFACE_QUEUE_SIZE 256
/**
* The maximum surface width; 2x WQXGA @ 16:10.
*/
#define GUAC_COMMON_SURFACE_MAX_WIDTH 5120
/**
* The maximum surface height; 2x WQXGA @ 16:10.
*/
#define GUAC_COMMON_SURFACE_MAX_HEIGHT 3200
/** /**
* Heat map square size in pixels. * Heat map square size in pixels.
*/ */
#define GUAC_COMMON_SURFACE_HEAT_MAP_CELL 64 #define GUAC_COMMON_SURFACE_HEAT_MAP_CELL 64
/**
* Heat map number of columns.
*/
#define GUAC_COMMON_SURFACE_HEAT_MAP_COLS (GUAC_COMMON_SURFACE_MAX_WIDTH / GUAC_COMMON_SURFACE_HEAT_MAP_CELL)
/**
* Heat map number of rows.
*/
#define GUAC_COMMON_SURFACE_HEAT_MAP_ROWS (GUAC_COMMON_SURFACE_MAX_HEIGHT / GUAC_COMMON_SURFACE_HEAT_MAP_CELL)
/** /**
* The number of entries to collect within each heat map cell. Collected * The number of entries to collect within each heat map cell. Collected
* history entries are used to determine the framerate of the region associated * history entries are used to determine the framerate of the region associated
@ -191,7 +171,7 @@ typedef struct guac_common_surface {
* A heat map keeping track of the refresh frequency of * A heat map keeping track of the refresh frequency of
* the areas of the screen. * the areas of the screen.
*/ */
guac_common_surface_heat_rect heat_map[GUAC_COMMON_SURFACE_HEAT_MAP_ROWS][GUAC_COMMON_SURFACE_HEAT_MAP_COLS]; guac_common_surface_heat_rect* heat_map;
} guac_common_surface; } guac_common_surface;