From: Ray Strode Date: Fri, 12 Jun 2009 03:11:26 +0000 (-0400) Subject: [frame-buffer] Discard overlapping flush areas X-Git-Tag: 0.7.0~161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bed202ac28519b4c23e75f017a41b024e49b8161;p=thirdparty%2Fplymouth.git [frame-buffer] Discard overlapping flush areas One advantage of the previous bounding box approach to flushing is overlapping flush areas wouldn't get flushed multiple times. This commit tries to identify overlapping flush areas and eliminate them. It's not perfect though. A better approach might be to store a sorted tree of areas to be flushed, and walk the tree when adding new flush areas to quickly find overlapping areas. Then we'd split each area into two or more new areas to avoid overlaps. --- diff --git a/src/libply/ply-frame-buffer.c b/src/libply/ply-frame-buffer.c index 44a6cffb..ee079db5 100644 --- a/src/libply/ply-frame-buffer.c +++ b/src/libply/ply-frame-buffer.c @@ -517,6 +517,59 @@ ply_frame_buffer_area_union (ply_frame_buffer_area_t *area1, result->height = MAX(y1, y2) - result->y; } +static void +integrate_area_with_flush_area (ply_frame_buffer_t *buffer, + ply_frame_buffer_area_t *new_area) +{ + ply_list_node_t *node; + ply_frame_buffer_area_t overlapping_area; + + /* FIXME: The logic in the function isn't as sophisticated as it could be. + * It only culls if one old area completely overlaps the new flush area. + * + * It doesn't cull if two or more old flush areas collectively overlap the + * new flush area. + */ + + node = ply_list_get_first_node (buffer->areas_to_flush); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_frame_buffer_area_t *existing_area_to_flush; + + existing_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); + + ply_frame_buffer_area_intersect (new_area, + existing_area_to_flush, + &overlapping_area); + + /* If an existing flush area is completely inside the + * new area, then we can remove the old area from the list. + * + * If the new area is completely inside an old area then + * we don't need to add the new area at all. + */ + if (overlapping_area.width == existing_area_to_flush->width && + overlapping_area.height == existing_area_to_flush->height) + { + free (existing_area_to_flush); + ply_list_remove_node (buffer->areas_to_flush, node); + } + else if (overlapping_area.width == new_area->width && + overlapping_area.height == new_area->height) + { + free (new_area); + return; + } + + node = next_node; + } + + ply_list_append_data (buffer->areas_to_flush, new_area); +} + static void ply_frame_buffer_add_area_to_flush_area (ply_frame_buffer_t *buffer, ply_frame_buffer_area_t *area) @@ -535,7 +588,7 @@ ply_frame_buffer_add_area_to_flush_area (ply_frame_buffer_t *buffer, return; } - ply_list_append_data (buffer->areas_to_flush, cropped_area); + integrate_area_with_flush_area (buffer, cropped_area); } static bool