[vte/wip/sixels: 53/111] ring: Implement hard image resource limits for device-friendly storage




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

    ring: Implement hard image resource limits for device-friendly storage

 src/ring.cc | 47 +++++++++++++++++++++++++++++++----------------
 src/ring.hh |  5 ++---
 2 files changed, 33 insertions(+), 19 deletions(-)
---
diff --git a/src/ring.cc b/src/ring.cc
index 3b97df51..707f8166 100644
--- a/src/ring.cc
+++ b/src/ring.cc
@@ -27,6 +27,14 @@
 #include <string.h>
 #include <new>
 
+/* We should be able to hold a single fullscreen 4K image at most.
+ * 35MiB equals 3840 * 2160 * 4 plus a little extra. */
+#define IMAGE_FAST_MEMORY_USED_MAX (35 * 1024 * 1024)
+
+/* Hard limit on number of images to keep around. This limits the impact
+ * of potential issues related to algorithmic complexity. */
+#define IMAGE_FAST_COUNT_MAX 4096
+
 /*
  * Copy the common attributes from VteCellAttr to VteStreamCellAttr or vice versa.
  */
@@ -90,8 +98,7 @@ Ring::Ring(row_t max_rows,
         m_next_image_priority = 0;
         m_image_map = new (std::nothrow) std::map<gint, vte::image::Image *>();
         m_image_priority_map = new (std::nothrow) std::map<int, vte::image::Image *>();
-        m_image_onscreen_resource_counter = 0;
-        m_image_offscreen_resource_counter = 0;
+        m_image_fast_memory_used = 0;
 
        validate();
 }
@@ -207,6 +214,24 @@ Ring::hyperlink_maybe_gc(row_t increment)
                 hyperlink_gc();
 }
 
+void
+Ring::image_gc()
+{
+        while (m_image_fast_memory_used > IMAGE_FAST_MEMORY_USED_MAX
+               || m_image_priority_map->size() > IMAGE_FAST_COUNT_MAX) {
+                if (m_image_priority_map->empty()) {
+                        /* If this happens, we've miscounted somehow. */
+                        break;
+                }
+
+                vte::image::Image *image = m_image_priority_map->begin()->second;
+                m_image_fast_memory_used -= image->resource_size();
+                m_image_map->erase(image->get_bottom());
+                m_image_priority_map->erase(m_image_priority_map->begin());
+                delete image;
+        }
+}
+
 /*
  * Find existing idx for the hyperlink or allocate a new one.
  *
@@ -1543,7 +1568,7 @@ Ring::append_image (cairo_surface_t *surface, gint pixelwidth, gint pixelheight,
 
                /* Delete images that are completely covered by this image */
                if (image->contains (*current)) {
-                        m_image_onscreen_resource_counter -= current->resource_size ();
+                        m_image_fast_memory_used -= current->resource_size ();
 
                         /* We must advance the iterator before erasure */
                        m_image_map->erase (it++);
@@ -1565,20 +1590,10 @@ Ring::append_image (cairo_surface_t *surface, gint pixelwidth, gint pixelheight,
         */
        m_image_map->insert (std::make_pair (image->get_bottom (), image));
         m_image_priority_map->insert (std::make_pair (image->get_priority (), image));
-       m_image_onscreen_resource_counter += image->resource_size ();
+       m_image_fast_memory_used += image->resource_size ();
+
+        image_gc();
 end:
        /* noop */
        ;
 }
-
-void
-Ring::shrink_image_stream ()
-{
-       using namespace vte::image;
-       Image *first_image;
-
-       if (m_image_map->empty())
-               return;
-
-       first_image = m_image_map->begin()->second;
-}
diff --git a/src/ring.hh b/src/ring.hh
index 730cd156..04c38d2b 100644
--- a/src/ring.hh
+++ b/src/ring.hh
@@ -92,7 +92,6 @@ public:
         VteRowData* append(guint8 bidi_flags);
         void remove(row_t position);
         void append_image (cairo_surface_t *surface, gint pixelwidth, gint pixelheight, glong left, glong 
top, glong width, glong height);
-        void shrink_image_stream ();
         void drop_scrollback(row_t position);
         void set_visible_rows(row_t rows);
         void rewrap(column_t columns,
@@ -116,8 +115,7 @@ public:
 
         std::map<gint, vte::image::Image *> *m_image_map;
         std::map<int, vte::image::Image *> *m_image_priority_map;
-        gulong m_image_onscreen_resource_counter;
-        gulong m_image_offscreen_resource_counter;
+        unsigned int m_image_fast_memory_used;
 
         /* <<< */
 
@@ -132,6 +130,7 @@ private:
         inline VteRowData* get_writable_index(row_t position) const { return &m_array[position & m_mask]; }
 
         void hyperlink_gc();
+        void image_gc();
         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]