[vte/wip/sixels: 53/111] ring: Implement hard image resource limits for device-friendly storage
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/sixels: 53/111] ring: Implement hard image resource limits for device-friendly storage
- Date: Sat, 8 Aug 2020 18:43:01 +0000 (UTC)
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]