devilhorns pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=8cd3860d001d95a26ba016c01738abb3f015df49
commit 8cd3860d001d95a26ba016c01738abb3f015df49 Author: Derek Foreman <der...@osg.samsung.com> Date: Tue Jul 10 16:53:12 2018 -0400 evas_drm: Trim the queue of buffers if we've had extra for too long Summary: In fixing T7099 I've also allowed the buffer queue to grow quite large, so now we should prune it back if it's bigger than it needs to be for a long time. ref T7099 Depends on D6565 Reviewers: devilhorns Reviewed By: devilhorns Subscribers: cedric, #committers, zmike Tags: #efl Maniphest Tasks: T7099 Differential Revision: https://phab.enlightenment.org/D6566 --- src/modules/evas/engines/drm/evas_engine.h | 1 + src/modules/evas/engines/drm/evas_outbuf.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h index 9d3a16d169..ea8a6cec03 100644 --- a/src/modules/evas/engines/drm/evas_engine.h +++ b/src/modules/evas/engines/drm/evas_engine.h @@ -67,6 +67,7 @@ struct _Outbuf Eina_List *pending; Eina_Rectangle *rects; unsigned int rect_count; + int unused_duration; } priv; Eina_Bool alpha : 1; diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index aa667a9c76..8b87c00661 100644 --- a/src/modules/evas/engines/drm/evas_outbuf.c +++ b/src/modules/evas/engines/drm/evas_outbuf.c @@ -9,6 +9,7 @@ #define BLUE_MASK 0x0000ff #define MAX_BUFFERS 10 +#define QUEUE_TRIM_DURATION 100 static void _outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) @@ -186,6 +187,7 @@ _outbuf_reconfigure(Outbuf *ob, int w, int h, int rotation, Outbuf_Depth depth) ob->depth = depth; ob->format = format; ob->rotation = rotation; + ob->priv.unused_duration = 0; EINA_LIST_FREE(ob->priv.fb_list, ofb) _outbuf_fb_destroy(ofb); @@ -198,14 +200,19 @@ _outbuf_fb_wait(Outbuf *ob) { Eina_List *l; Outbuf_Fb *ofb, *best = NULL; - int best_age = -1; + int best_age = -1, num_required = 1, num_allocated = 0; /* We pick the oldest available buffer to avoid using the same two * repeatedly and then having the third be stale when we need it */ EINA_LIST_FOREACH(ob->priv.fb_list, l, ofb) { - if (ecore_drm2_fb_busy_get(ofb->fb)) continue; + num_allocated++; + if (ecore_drm2_fb_busy_get(ofb->fb)) + { + num_required++; + continue; + } if (ofb->valid && (ofb->age > best_age)) { best = ofb; @@ -213,6 +220,23 @@ _outbuf_fb_wait(Outbuf *ob) } } + if (num_required < num_allocated) + ob->priv.unused_duration++; + else + ob->priv.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 && (ob->priv.unused_duration > QUEUE_TRIM_DURATION)) + { + ob->priv.unused_duration = 0; + ob->priv.fb_list = eina_list_remove(ob->priv.fb_list, best); + _outbuf_fb_destroy(best); + best = _outbuf_fb_wait(ob); + } + return best; } --