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
This commit is contained in:
Derek Foreman 2018-07-10 16:53:12 -04:00 committed by Chris Michael
parent 2668f6196e
commit 8cd3860d00
2 changed files with 27 additions and 2 deletions

View File

@ -67,6 +67,7 @@ struct _Outbuf
Eina_List *pending;
Eina_Rectangle *rects;
unsigned int rect_count;
int unused_duration;
} priv;
Eina_Bool alpha : 1;

View File

@ -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;
}