forked from enlightenment/efl
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.
This commit is contained in:
parent
879f248f08
commit
90fecc7485
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue