[vte/wip/sixels: 44/82] ring: Add GC for overlapped images
- From: Hans Petter Jansson <hansp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/sixels: 44/82] ring: Add GC for overlapped images
- Date: Fri, 26 Jun 2020 00:46:48 +0000 (UTC)
commit 676a12e8833fcf6dc4b004ca61e922a5665c029f
Author: Hans Petter Jansson <hpj cl no>
Date: Thu Jun 11 17:25:50 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]