derekf pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=90fecc7485b2cb8c4ac2d0a4a79f9dc761c51067

commit 90fecc7485b2cb8c4ac2d0a4a79f9dc761c51067
Author: Derek Foreman <der...@osg.samsung.com>
Date:   Tue Jan 30 17:06:48 2018 -0600

    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.
---
 .../ecore_wl2/ecore_wl2_surface_module_dmabuf.c    | 27 +++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

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);

-- 


Reply via email to