From 16fd8f6c7db4564b581fd5e752b5c4e1e6838798 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 17 Aug 2015 16:09:40 -0700 Subject: [PATCH] GUAC-240: Fix buffer error in calculation of framerate. Clarify naming. --- src/common/guac_surface.c | 52 +++++++++++++++++++-------------------- src/common/guac_surface.h | 19 +++++++------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/common/guac_surface.c b/src/common/guac_surface.c index c4b9e75e..f63fa47d 100644 --- a/src/common/guac_surface.c +++ b/src/common/guac_surface.c @@ -254,18 +254,18 @@ static unsigned int __guac_common_surface_calculate_framerate( int x, y; /* Calculate minimum X/Y coordinates intersecting given rect */ - int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; - int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; + int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; + int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; /* Calculate maximum X/Y coordinates intersecting given rect */ - 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_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; + int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; unsigned int sum_framerate = 0; unsigned int count = 0; /* Get start of buffer at given coordinates */ - const guac_common_surface_heat_rect* heat_row = + const guac_common_surface_heat_cell* heat_row = surface->heat_map + min_y * surface->width + min_x; /* Iterate over all the heat map cells for the area @@ -273,28 +273,28 @@ static unsigned int __guac_common_surface_calculate_framerate( for (y = min_y; y < max_y; y++) { /* Get current row of heat map */ - const guac_common_surface_heat_rect* heat_rect = heat_row; + const guac_common_surface_heat_cell* heat_cell = 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 */ - int oldest_entry = heat_rect->oldest_entry; + int oldest_entry = heat_cell->oldest_entry; int latest_entry = oldest_entry - 1; if (latest_entry < 0) - latest_entry = GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE; + latest_entry = GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE - 1; /* Calculate elapsed time covering entire history for this cell */ - int elapsed_time = heat_rect->history[latest_entry] - - heat_rect->history[oldest_entry]; + int elapsed_time = heat_cell->history[latest_entry] + - heat_cell->history[oldest_entry]; /* Calculate and add framerate */ if (elapsed_time) - sum_framerate += GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE + sum_framerate += GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE * 1000 / elapsed_time; /* Next heat map cell */ - heat_rect++; + heat_cell++; count++; } @@ -424,37 +424,37 @@ static void __guac_common_surface_touch_rect(guac_common_surface* surface, int x, y; /* Calculate minimum X/Y coordinates intersecting given rect */ - int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; - int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_MAP_CELL; + int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; + int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; /* Calculate maximum X/Y coordinates intersecting given rect */ - 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_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; + int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE; /* Get start of buffer at given coordinates */ - guac_common_surface_heat_rect* heat_row = + guac_common_surface_heat_cell* heat_row = surface->heat_map + min_y * surface->width + min_x; /* Update all heat map cells which intersect with rectangle */ for (y = min_y; y <= max_y; y++) { /* Get current row of heat map */ - guac_common_surface_heat_rect* heat_rect = heat_row; + guac_common_surface_heat_cell* heat_cell = heat_row; /* For each cell in subset of row */ for (x = min_x; x <= max_x; x++) { /* Replace oldest entry with new timestamp */ - heat_rect->history[heat_rect->oldest_entry] = time; + heat_cell->history[heat_cell->oldest_entry] = time; /* Update to next oldest entry */ - heat_rect->oldest_entry++; - if (heat_rect->oldest_entry >= - GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE) - heat_rect->oldest_entry = 0; + heat_cell->oldest_entry++; + if (heat_cell->oldest_entry >= + GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE) + heat_cell->oldest_entry = 0; /* Advance to next heat map cell */ - heat_rect++; + heat_cell++; } @@ -921,7 +921,7 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client, surface->buffer = calloc(h, surface->stride); /* Create corresponding heat map */ - surface->heat_map = calloc(w*h, sizeof(guac_common_surface_heat_rect)); + surface->heat_map = calloc(w*h, sizeof(guac_common_surface_heat_cell)); /* Reset clipping rect */ guac_common_surface_reset_clip(surface); @@ -984,7 +984,7 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) { /* 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)); + surface->heat_map = calloc(w*h, sizeof(guac_common_surface_heat_cell)); /* Resize dirty rect to fit new surface dimensions */ if (surface->dirty) { diff --git a/src/common/guac_surface.h b/src/common/guac_surface.h index 86948bea..ad99af0e 100644 --- a/src/common/guac_surface.h +++ b/src/common/guac_surface.h @@ -38,22 +38,23 @@ #define GUAC_COMMON_SURFACE_QUEUE_SIZE 256 /** - * Heat map square size in pixels. + * Heat map cell size in pixels. Each side of each heat map cell will consist + * of this many pixels. */ -#define GUAC_COMMON_SURFACE_HEAT_MAP_CELL 64 +#define GUAC_COMMON_SURFACE_HEAT_CELL_SIZE 64 /** * The number of entries to collect within each heat map cell. Collected * history entries are used to determine the framerate of the region associated * with that cell. */ -#define GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE 5 +#define GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE 5 /** - * Representation of a rectangle or cell in the refresh heat map. This rectangle - * is used to keep track of how often an area on a surface is refreshed. + * Representation of a cell in the refresh heat map. This cell is used to keep + * track of how often an area on a surface is refreshed. */ -typedef struct guac_common_surface_heat_rect { +typedef struct guac_common_surface_heat_cell { /** * Timestamps of each of the last N updates covering the location @@ -63,14 +64,14 @@ typedef struct guac_common_surface_heat_rect { * pointed to by oldest_entry and proceeding through all other entries, * wrapping around if the end of the array is reached. */ - guac_timestamp history[GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE]; + guac_timestamp history[GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE]; /** * Index of the oldest entry within the history. */ int oldest_entry; -} guac_common_surface_heat_rect; +} guac_common_surface_heat_cell; /** * Representation of a bitmap update, having a rectangle of image data (stored @@ -171,7 +172,7 @@ typedef struct guac_common_surface { * A heat map keeping track of the refresh frequency of * the areas of the screen. */ - guac_common_surface_heat_rect* heat_map; + guac_common_surface_heat_cell* heat_map; } guac_common_surface;