summaryrefslogtreecommitdiff
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
parent879f248f0845be0163dbee0807a4eb859cf12786 (diff)
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 @@
10#include "linux-dmabuf-unstable-v1-client-protocol.h" 10#include "linux-dmabuf-unstable-v1-client-protocol.h"
11 11
12#define MAX_BUFFERS 4 12#define MAX_BUFFERS 4
13#define QUEUE_TRIM_DURATION 100
13 14
14int ECORE_WL2_SURFACE_DMABUF = 0; 15int ECORE_WL2_SURFACE_DMABUF = 0;
15 16
@@ -17,6 +18,7 @@ typedef struct _Ecore_Wl2_Dmabuf_Private
17{ 18{
18 Ecore_Wl2_Buffer *current; 19 Ecore_Wl2_Buffer *current;
19 Eina_List *buffers; 20 Eina_List *buffers;
21 int unused_duration;
20} Ecore_Wl2_Dmabuf_Private; 22} Ecore_Wl2_Dmabuf_Private;
21 23
22static void * 24static void *
@@ -95,10 +97,16 @@ _evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p)
95 Eina_List *l; 97 Eina_List *l;
96 int best_age = -1; 98 int best_age = -1;
97 int age; 99 int age;
100 int num_required = 1, num_allocated = 0;
98 101
99 EINA_LIST_FOREACH(p->buffers, l, b) 102 EINA_LIST_FOREACH(p->buffers, l, b)
100 { 103 {
101 if (ecore_wl2_buffer_busy_get(b)) continue; 104 num_allocated++;
105 if (ecore_wl2_buffer_busy_get(b))
106 {
107 num_required++;
108 continue;
109 }
102 age = ecore_wl2_buffer_age_get(b); 110 age = ecore_wl2_buffer_age_get(b);
103 if (age > best_age) 111 if (age > best_age)
104 { 112 {
@@ -107,6 +115,23 @@ _evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p)
107 } 115 }
108 } 116 }
109 117
118 if (num_required < num_allocated)
119 p->unused_duration++;
120 else
121 p->unused_duration = 0;
122
123 /* If we've had unused buffers for longer than QUEUE_TRIM_DURATION, then
124 * destroy the oldest buffer (currently in best) and recursively call
125 * ourself to get the next oldest.
126 */
127 if (best && (p->unused_duration > QUEUE_TRIM_DURATION))
128 {
129 p->unused_duration = 0;
130 p->buffers = eina_list_remove(p->buffers, best);
131 ecore_wl2_buffer_destroy(best);
132 best = _evas_dmabuf_surface_wait(s, p);
133 }
134
110 if (!best && (eina_list_count(p->buffers) < MAX_BUFFERS)) 135 if (!best && (eina_list_count(p->buffers) < MAX_BUFFERS))
111 { 136 {
112 best = ecore_wl2_surface_buffer_create(s); 137 best = ecore_wl2_surface_buffer_create(s);