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;
/* 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) {

View File

@ -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;