]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[frame-buffer] Discard overlapping flush areas
authorRay Strode <rstrode@redhat.com>
Fri, 12 Jun 2009 03:11:26 +0000 (23:11 -0400)
committerRay Strode <rstrode@redhat.com>
Fri, 12 Jun 2009 03:37:03 +0000 (23:37 -0400)
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.

src/libply/ply-frame-buffer.c

index 44a6cffbc0ed2a71e470de5a8864f2b3cb80071f..ee079db59acbbe0144dc1dc6a3137a88d7c46fa2 100644 (file)
@@ -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