diff options
| author | Ray Strode <rstrode@redhat.com> | 2009-06-11 22:50:07 -0400 |
|---|---|---|
| committer | Ray Strode <rstrode@redhat.com> | 2009-06-11 23:18:30 -0400 |
| commit | a741222aca6b7bceebe002e5c01a3825088c2987 (patch) | |
| tree | 99a6f5130f23332d3903aa7c0c550da67f3e8a2e | |
| parent | ffec2f1e6701773ddf399c15ab954ed08e561064 (diff) | |
[frame-buffer] Track multiple flush areas
Previously we would always aggregate flush areas together even
if they were disjoint and far apart. That meant that if two
images on opposites sides of the screen were updated in one
frame, then the entire screen would get redrawn.
We now track flush areas in a list, instead of a bounding box.
| -rw-r--r-- | src/libply/ply-frame-buffer.c | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/src/libply/ply-frame-buffer.c b/src/libply/ply-frame-buffer.c index 66019ff5..44a6cffb 100644 --- a/src/libply/ply-frame-buffer.c +++ b/src/libply/ply-frame-buffer.c @@ -23,6 +23,7 @@ * Ray Strode <rstrode@redhat.com> */ #include "config.h" +#include "ply-list.h" #include "ply-frame-buffer.h" #include "ply-logger.h" @@ -76,7 +77,7 @@ struct _ply_frame_buffer unsigned int row_stride; ply_frame_buffer_area_t area; - ply_frame_buffer_area_t area_to_flush; + ply_list_t *areas_to_flush; void (*flush_area) (ply_frame_buffer_t *buffer, ply_frame_buffer_area_t *area_to_flush); @@ -520,34 +521,49 @@ static void ply_frame_buffer_add_area_to_flush_area (ply_frame_buffer_t *buffer, ply_frame_buffer_area_t *area) { - ply_frame_buffer_area_t cropped_area; + ply_frame_buffer_area_t *cropped_area; + assert (buffer != NULL); assert (area != NULL); - ply_frame_buffer_area_intersect (area, &buffer->area, &cropped_area); + cropped_area = malloc (sizeof (ply_frame_buffer_area_t)); + ply_frame_buffer_area_intersect (area, &buffer->area, cropped_area); - if (cropped_area.width == 0 || cropped_area.height == 0) - return; + if (cropped_area->width == 0 || cropped_area->height == 0) + { + free (cropped_area); + return; + } - ply_frame_buffer_area_union (&buffer->area_to_flush, - &cropped_area, - &buffer->area_to_flush); + ply_list_append_data (buffer->areas_to_flush, cropped_area); } static bool ply_frame_buffer_flush (ply_frame_buffer_t *buffer) { + ply_list_node_t *node; assert (buffer != NULL); if (buffer->pause_count > 0) return true; - (*buffer->flush_area) (buffer, &buffer->area_to_flush); + node = ply_list_get_first_node (buffer->areas_to_flush); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_frame_buffer_area_t *area_to_flush; + + area_to_flush = (ply_frame_buffer_area_t *) ply_list_node_get_data (node); + + next_node = ply_list_get_next_node (buffer->areas_to_flush, node); - buffer->area_to_flush.x = buffer->area.width - 1; - buffer->area_to_flush.y = buffer->area.height - 1; - buffer->area_to_flush.width = 0; - buffer->area_to_flush.height = 0; + (*buffer->flush_area) (buffer, area_to_flush); + + free (area_to_flush); + ply_list_remove_node (buffer->areas_to_flush, node); + + node = next_node; + } return true; } @@ -569,12 +585,37 @@ ply_frame_buffer_new (const char *device_name) buffer->map_address = MAP_FAILED; buffer->shadow_buffer = NULL; + buffer->areas_to_flush = ply_list_new (); buffer->pause_count = 0; return buffer; } +static void +free_flush_areas (ply_frame_buffer_t *buffer) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (buffer->areas_to_flush); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_frame_buffer_area_t *area_to_flush; + + area_to_flush = (ply_frame_buffer_area_t *) ply_list_node_get_data (node); + + next_node = ply_list_get_next_node (buffer->areas_to_flush, node); + + free (area_to_flush); + ply_list_remove_node (buffer->areas_to_flush, node); + + node = next_node; + } + + ply_list_free (buffer->areas_to_flush); +} + void ply_frame_buffer_free (ply_frame_buffer_t *buffer) { @@ -583,6 +624,8 @@ ply_frame_buffer_free (ply_frame_buffer_t *buffer) if (ply_frame_buffer_device_is_open (buffer)) ply_frame_buffer_close (buffer); + free_flush_areas (buffer); + free (buffer->device_name); free (buffer->shadow_buffer); free (buffer); |
