diff options
author | Derek Foreman <derekf@osg.samsung.com> | 2018-01-30 17:06:48 -0600 |
---|---|---|
committer | Derek Foreman <derekf@osg.samsung.com> | 2018-01-30 17:09:52 -0600 |
commit | 90fecc7485b2cb8c4ac2d0a4a79f9dc761c51067 (patch) | |
tree | a77be90288e37fc32547f2badf43e819fa4defb4 | |
parent | 879f248f0845be0163dbee0807a4eb859cf12786 (diff) | |
download | efl-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.c | 27 |
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); |