GUAC-240: Fix buffer error in calculation of framerate. Clarify naming.

This commit is contained in:
Michael Jumper 2015-08-17 16:09:40 -07:00
parent c604777622
commit 16fd8f6c7d
2 changed files with 36 additions and 35 deletions

View File

@ -254,18 +254,18 @@ static unsigned int __guac_common_surface_calculate_framerate(
int x, y; int x, y;
/* Calculate minimum X/Y coordinates intersecting given rect */ /* Calculate minimum X/Y coordinates intersecting given rect */
int min_x = rect->x / 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_MAP_CELL; int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
/* Calculate maximum X/Y coordinates intersecting given rect */ /* Calculate maximum X/Y coordinates intersecting given rect */
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_CELL_SIZE;
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_CELL_SIZE;
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 */ /* 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; 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
@ -273,28 +273,28 @@ static unsigned int __guac_common_surface_calculate_framerate(
for (y = min_y; y < max_y; y++) { for (y = min_y; y < max_y; y++) {
/* Get current row of heat map */ /* 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 each cell in subset of row */
for (x = min_x; x < max_x; x++) { 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_cell->oldest_entry;
int latest_entry = oldest_entry - 1; int latest_entry = oldest_entry - 1;
if (latest_entry < 0) 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 */ /* Calculate elapsed time covering entire history for this cell */
int elapsed_time = heat_rect->history[latest_entry] int elapsed_time = heat_cell->history[latest_entry]
- heat_rect->history[oldest_entry]; - heat_cell->history[oldest_entry];
/* Calculate and add framerate */ /* Calculate and add framerate */
if (elapsed_time) if (elapsed_time)
sum_framerate += GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE sum_framerate += GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE
* 1000 / elapsed_time; * 1000 / elapsed_time;
/* Next heat map cell */ /* Next heat map cell */
heat_rect++; heat_cell++;
count++; count++;
} }
@ -424,37 +424,37 @@ static void __guac_common_surface_touch_rect(guac_common_surface* surface,
int x, y; int x, y;
/* Calculate minimum X/Y coordinates intersecting given rect */ /* Calculate minimum X/Y coordinates intersecting given rect */
int min_x = rect->x / 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_MAP_CELL; int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
/* Calculate maximum X/Y coordinates intersecting given rect */ /* Calculate maximum X/Y coordinates intersecting given rect */
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_CELL_SIZE;
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_CELL_SIZE;
/* Get start of buffer at given coordinates */ /* 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; 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++) {
/* Get current row of heat map */ /* 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 each cell in subset of row */
for (x = min_x; x <= max_x; x++) { 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_cell->history[heat_cell->oldest_entry] = time;
/* Update to next oldest entry */ /* Update to next oldest entry */
heat_rect->oldest_entry++; heat_cell->oldest_entry++;
if (heat_rect->oldest_entry >= if (heat_cell->oldest_entry >=
GUAC_COMMON_SURFACE_HEAT_MAP_HISTORY_SIZE) GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE)
heat_rect->oldest_entry = 0; heat_cell->oldest_entry = 0;
/* Advance to next heat map cell */ /* 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); surface->buffer = calloc(h, surface->stride);
/* Create corresponding heat map */ /* 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 */ /* Reset clipping rect */
guac_common_surface_reset_clip(surface); 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) */ /* Allocate completely new heat map (can safely discard old stats) */
free(surface->heat_map); 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 */ /* Resize dirty rect to fit new surface dimensions */
if (surface->dirty) { if (surface->dirty) {

View File

@ -38,22 +38,23 @@
#define GUAC_COMMON_SURFACE_QUEUE_SIZE 256 #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 * 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
* with that cell. * 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 * Representation of a cell in the refresh heat map. This cell is used to keep
* is used to keep track of how often an area on a surface is refreshed. * 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 * 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, * pointed to by oldest_entry and proceeding through all other entries,
* wrapping around if the end of the array is reached. * 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. * Index of the oldest entry within the history.
*/ */
int oldest_entry; 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 * 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 * 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_cell* heat_map;
} guac_common_surface; } guac_common_surface;