[vte/wip/sixels: 54/111] ring: Add GC for overlapped images




commit 13b022e3f146373af2074dda55cf83a69b650fe0
Author: Hans Petter Jansson <hpj cl no>
Date:   Sat Aug 8 20:42:49 2020 +0200

    ring: Add GC for overlapped images

 src/image.hh |  2 ++
 src/ring.cc  | 54 +++++++++++++++++++++++++++++++++++++-----------------
 src/ring.hh  |  1 +
 3 files changed, 40 insertions(+), 17 deletions(-)
---
diff --git a/src/image.hh b/src/image.hh
index ad411656..2c9a172b 100644
--- a/src/image.hh
+++ b/src/image.hh
@@ -64,6 +64,8 @@ public:
         inline constexpr auto get_left() const noexcept { return m_left_cells; }
         inline constexpr auto get_top() const noexcept { return m_top_cells; }
         inline constexpr auto get_bottom() const noexcept { return m_top_cells + m_height_cells - 1; }
+        inline constexpr auto get_width() const noexcept { return m_width_cells; }
+        inline constexpr auto get_height() const noexcept { return m_height_cells; }
         inline auto resource_size() const noexcept {
                 if (cairo_image_surface_get_stride(m_surface.get()) != 0)
                         return cairo_image_surface_get_stride(m_surface.get()) * m_height_pixels;
diff --git a/src/ring.cc b/src/ring.cc
index 707f8166..1b9bae90 100644
--- a/src/ring.cc
+++ b/src/ring.cc
@@ -214,6 +214,41 @@ Ring::hyperlink_maybe_gc(row_t increment)
                 hyperlink_gc();
 }
 
+void
+Ring::image_gc_region()
+{
+       using namespace vte::image;
+        cairo_region_t *region = cairo_region_create();
+
+       for (auto it = m_image_priority_map->rbegin(); it != m_image_priority_map->rend(); ) {
+                vte::image::Image *image = it->second;
+                cairo_rectangle_int_t r;
+
+                r.x = image->get_left();
+                r.y = image->get_top();
+                r.width = image->get_width();
+                r.height = image->get_height();
+
+                if (cairo_region_contains_rectangle(region, &r) == CAIRO_REGION_OVERLAP_IN) {
+                        /* Image has been completely overdrawn; delete it */
+
+                        m_image_fast_memory_used -= image->resource_size();
+
+                        /* Apparently this is the cleanest way to erase() with a reverse iterator... */
+                        it = decltype(it){m_image_priority_map->erase(std::next(it).base())};
+
+                        m_image_map->erase(image->get_bottom());
+                        delete image;
+                        continue;
+                }
+
+                cairo_region_union_rectangle(region, &r);
+                it++;
+        }
+
+        cairo_region_destroy(region);
+}
+
 void
 Ring::image_gc()
 {
@@ -1563,23 +1598,6 @@ Ring::append_image (cairo_surface_t *surface, gint pixelwidth, gint pixelheight,
        char_width = pixelwidth / width;
        char_height = pixelwidth / height;
 
-       for (auto it = m_image_map->lower_bound (top); it != m_image_map->end (); ) {
-               Image *current = it->second;
-
-               /* Delete images that are completely covered by this image */
-               if (image->contains (*current)) {
-                        m_image_fast_memory_used -= current->resource_size ();
-
-                        /* We must advance the iterator before erasure */
-                       m_image_map->erase (it++);
-                        m_image_priority_map->erase(current->get_priority());
-                       delete current;
-                        continue;
-               }
-
-                it++;
-       }
-
        /*
         * Now register new image to the m_image_map container.
         * the key is bottom positon.
@@ -1592,7 +1610,9 @@ Ring::append_image (cairo_surface_t *surface, gint pixelwidth, gint pixelheight,
         m_image_priority_map->insert (std::make_pair (image->get_priority (), image));
        m_image_fast_memory_used += image->resource_size ();
 
+        image_gc_region();
         image_gc();
+
 end:
        /* noop */
        ;
diff --git a/src/ring.hh b/src/ring.hh
index 04c38d2b..5974f9a6 100644
--- a/src/ring.hh
+++ b/src/ring.hh
@@ -131,6 +131,7 @@ private:
 
         void hyperlink_gc();
         void image_gc();
+        void image_gc_region();
         hyperlink_idx_t get_hyperlink_idx_no_update_current(char const* hyperlink);
 
         typedef struct _CellAttrChange {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]