aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2018-01-30 17:06:48 -0600
committerDerek Foreman <derekf@osg.samsung.com>2018-01-30 17:09:52 -0600
commit90fecc7485b2cb8c4ac2d0a4a79f9dc761c51067 (patch)
treea77be90288e37fc32547f2badf43e819fa4defb4
parentecore_wl2_surface: Flush surfaces for offscreen windows (diff)
downloadefl-90fecc7485b2cb8c4ac2d0a4a79f9dc761c51067.tar.gz
wl2_surface_dmabuf: Trim the buffer queue after a while
If we have more buffers than we need for 100 frames then drop the oldest. This can happen if we're on a hardware plane and then removed from it, or really whenever the compositor feels like holding onto a few frames. Trimming the queue too soon could result in having to do a costly full frame redraw, so we wait a while to make sure we don't need one again. Having more frames than we need costs us a little every draw since we always use the oldest available. It also wastes memory.
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c b/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c
index 2be8ded399..6cc7123c04 100644
--- a/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c
+++ b/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c
@@ -10,6 +10,7 @@
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#define MAX_BUFFERS 4
+#define QUEUE_TRIM_DURATION 100
int ECORE_WL2_SURFACE_DMABUF = 0;
@@ -17,6 +18,7 @@ typedef struct _Ecore_Wl2_Dmabuf_Private
{
Ecore_Wl2_Buffer *current;
Eina_List *buffers;
+ int unused_duration;
} Ecore_Wl2_Dmabuf_Private;
static void *
@@ -95,10 +97,16 @@ _evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p)
Eina_List *l;
int best_age = -1;
int age;
+ int num_required = 1, num_allocated = 0;
EINA_LIST_FOREACH(p->buffers, l, b)
{
- if (ecore_wl2_buffer_busy_get(b)) continue;
+ num_allocated++;
+ if (ecore_wl2_buffer_busy_get(b))
+ {
+ num_required++;
+ continue;
+ }
age = ecore_wl2_buffer_age_get(b);
if (age > best_age)
{
@@ -107,6 +115,23 @@ _evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p)
}
}
+ if (num_required < num_allocated)
+ p->unused_duration++;
+ else
+ p->unused_duration = 0;
+
+ /* If we've had unused buffers for longer than QUEUE_TRIM_DURATION, then
+ * destroy the oldest buffer (currently in best) and recursively call
+ * ourself to get the next oldest.
+ */
+ if (best && (p->unused_duration > QUEUE_TRIM_DURATION))
+ {
+ p->unused_duration = 0;
+ p->buffers = eina_list_remove(p->buffers, best);
+ ecore_wl2_buffer_destroy(best);
+ best = _evas_dmabuf_surface_wait(s, p);
+ }
+
if (!best && (eina_list_count(p->buffers) < MAX_BUFFERS))
{
best = ecore_wl2_surface_buffer_create(s);