From 796de8cb86fab56c009ecfe9ade65c25116d109f Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Fri, 17 Nov 2017 14:32:30 -0600 Subject: [PATCH] wayland_shm: Don't use a fixed number of buffers We no longer allocate 3 buffers at startup, we now allocate only as needed. Trimming the queue will come later, as there are some situations where we might need 3 buffers and later drop down to 2 (when on a hardware plane) Most clients will only ever need 2 buffers, so this is a reasonable RAM savings. --- src/lib/ecore_wl2/Ecore_Wl2.h | 1 - src/modules/evas/engines/wayland_shm/evas_dmabuf.c | 100 ++++++++------------- src/modules/evas/engines/wayland_shm/evas_engine.h | 4 +- src/modules/evas/engines/wayland_shm/evas_outbuf.c | 39 +------- 4 files changed, 42 insertions(+), 102 deletions(-) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 1f58cd4..88fbeda 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -376,7 +376,6 @@ struct _Ecore_Wl2_Buffer int index; Eina_Bool locked : 1; Eina_Bool busy : 1; - Eina_Bool used : 1; Eina_Bool orphaned : 1; Eina_Bool alpha : 1; }; diff --git a/src/modules/evas/engines/wayland_shm/evas_dmabuf.c b/src/modules/evas/engines/wayland_shm/evas_dmabuf.c index b137c27..350ec59 100644 --- a/src/modules/evas/engines/wayland_shm/evas_dmabuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_dmabuf.c @@ -13,8 +13,7 @@ struct _Dmabuf_Surface Surface *surface; Ecore_Wl2_Buffer *current; - Ecore_Wl2_Buffer **buffer; - int nbuf; + Eina_List *buffers; Eina_Bool alpha : 1; }; @@ -25,31 +24,24 @@ static void _evas_dmabuf_surface_destroy(Surface *s); static void _evas_dmabuf_surface_reconfigure(Surface *s, int w, int h, uint32_t flags EINA_UNUSED, Eina_Bool force) { - Ecore_Wl2_Buffer *buf; + Ecore_Wl2_Buffer *b; + Eina_List *l, *tmp; Dmabuf_Surface *surface; - int i; if ((!w) || (!h)) return; surface = s->surf.dmabuf; - for (i = 0; i < surface->nbuf; i++) + EINA_LIST_FOREACH_SAFE(surface->buffers, l, tmp, b) { - if (surface->buffer[i]) - { - Ecore_Wl2_Buffer *b = surface->buffer[i]; - int stride = b->stride; + int stride = b->stride; - /* If stride is a little bigger than width we still fit */ - if (!force && (w >= b->w) && (w <= stride / 4) && (h == b->h)) - { - b->w = w; - continue; - } - - ecore_wl2_buffer_destroy(b); + /* If stride is a little bigger than width we still fit */ + if (!force && (w >= b->w) && (w <= stride / 4) && (h == b->h)) + { + b->w = w; + continue; } - buf = ecore_wl2_buffer_create(s->ob->ewd, w, h, surface->alpha); - if (!buf) return; - surface->buffer[i] = buf; + ecore_wl2_buffer_destroy(b); + surface->buffers = eina_list_remove_list(surface->buffers, l); } } @@ -83,39 +75,48 @@ _evas_dmabuf_surface_data_get(Surface *s, int *w, int *h) static Ecore_Wl2_Buffer * _evas_dmabuf_surface_wait(Dmabuf_Surface *s) { - int i = 0, best = -1, best_age = -1; + Ecore_Wl2_Buffer *b, *best = NULL; + Eina_List *l; + int best_age = -1; - for (i = 0; i < s->nbuf; i++) + EINA_LIST_FOREACH(s->buffers, l, b) { - if (s->buffer[i]->locked || s->buffer[i]->busy) continue; - if (s->buffer[i]->age > best_age) + if (b->locked || b->busy) continue; + if (b->age > best_age) { - best = i; - best_age = s->buffer[i]->age; + best = b; + best_age = b->age; } } - if (best >= 0) return s->buffer[best]; - return NULL; + if (!best && (eina_list_count(s->buffers) < MAX_BUFFERS)) + { + Outbuf *ob; + ob = s->surface->ob; + best = ecore_wl2_buffer_create(ob->ewd, ob->w, ob->h, s->alpha); + s->buffers = eina_list_append(s->buffers, best); + } + return best; } static int _evas_dmabuf_surface_assign(Surface *s) { + Ecore_Wl2_Buffer *b; + Eina_List *l; Dmabuf_Surface *surface; - int i; surface = s->surf.dmabuf; surface->current = _evas_dmabuf_surface_wait(surface); if (!surface->current) { WRN("No free DMAbuf buffers, dropping a frame"); - for (i = 0; i < surface->nbuf; i++) - surface->buffer[i]->age = 0; + EINA_LIST_FOREACH(surface->buffers, l, b) + b->age = 0; return 0; } - for (i = 0; i < surface->nbuf; i++) - if (surface->buffer[i]->used) surface->buffer[i]->age++; + EINA_LIST_FOREACH(surface->buffers, l, b) + if (b->age) b->age++; return surface->current->age; } @@ -135,7 +136,6 @@ _evas_dmabuf_surface_post(Surface *s, Eina_Rectangle *rects, unsigned int count) surface->current = NULL; b->busy = EINA_TRUE; - b->used = EINA_TRUE; b->age = 0; win = s->info->info.wl2_win; @@ -149,14 +149,11 @@ _evas_dmabuf_surface_post(Surface *s, Eina_Rectangle *rects, unsigned int count) static void _internal_evas_dmabuf_surface_destroy(Dmabuf_Surface *surface) { - int i; + Ecore_Wl2_Buffer *b; - for (i = 0; i < surface->nbuf; i++) - ecore_wl2_buffer_destroy(surface->buffer[i]); + EINA_LIST_FREE(surface->buffers, b) + ecore_wl2_buffer_destroy(b); - free(surface->buffer); - surface->buffer = NULL; - surface->nbuf = 0; free(surface); } @@ -169,12 +166,11 @@ _evas_dmabuf_surface_destroy(Surface *s) } Eina_Bool -_evas_dmabuf_surface_create(Surface *s, int w, int h, int num_buff) +_evas_dmabuf_surface_create(Surface *s) { Ecore_Wl2_Display *ewd; Ecore_Wl2_Buffer_Type types = 0; Dmabuf_Surface *surf = NULL; - int i = 0; ewd = s->info->info.wl2_display; if (ecore_wl2_display_shm_get(ewd)) @@ -189,27 +185,8 @@ _evas_dmabuf_surface_create(Surface *s, int w, int h, int num_buff) surf->alpha = s->info->info.destination_alpha; /* create surface buffers */ - surf->nbuf = num_buff; - surf->buffer = calloc(surf->nbuf, sizeof(Ecore_Wl2_Buffer *)); - if (!surf->buffer) goto err; - if (!ecore_wl2_buffer_init(ewd, types)) goto err; - if (w && h) - { - for (i = 0; i < num_buff; i++) - { - surf->buffer[i] = ecore_wl2_buffer_create(s->ob->ewd, - w, h, surf->alpha); - if (!surf->buffer[i]) - { - DBG("Could not create buffers"); - /* _init() handled surface cleanup when it failed */ - return EINA_FALSE; - } - } - } - s->funcs.destroy = _evas_dmabuf_surface_destroy; s->funcs.reconfigure = _evas_dmabuf_surface_reconfigure; s->funcs.data_get = _evas_dmabuf_surface_data_get; @@ -219,7 +196,6 @@ _evas_dmabuf_surface_create(Surface *s, int w, int h, int num_buff) return EINA_TRUE; err: - free(surf->buffer); free(surf); return EINA_FALSE; } diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.h b/src/modules/evas/engines/wayland_shm/evas_engine.h index 726f424..79a76ce 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.h +++ b/src/modules/evas/engines/wayland_shm/evas_engine.h @@ -100,7 +100,6 @@ struct _Outbuf int w, h; int rotation; int onebuf; - int num_buff; Outbuf_Depth depth; Ecore_Wl2_Display *ewd; @@ -130,8 +129,7 @@ struct _Outbuf Eina_Bool dirty : 1; }; -Eina_Bool _evas_dmabuf_surface_create(Surface *s, int w, int h, int num_buff); -Eina_Bool _evas_shm_surface_create(Surface *s, int w, int h, int num_buff); +Eina_Bool _evas_dmabuf_surface_create(Surface *s); Outbuf *_evas_outbuf_setup(int w, int h, Evas_Engine_Info_Wayland *info); void _evas_outbuf_free(Outbuf *ob); diff --git a/src/modules/evas/engines/wayland_shm/evas_outbuf.c b/src/modules/evas/engines/wayland_shm/evas_outbuf.c index 6732fb2..fdcaf21 100644 --- a/src/modules/evas/engines/wayland_shm/evas_outbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_outbuf.c @@ -10,7 +10,7 @@ #define BLUE_MASK 0x0000ff static Surface * -_evas_surface_create(Evas_Engine_Info_Wayland *info, int w, int h, Outbuf *ob) +_evas_surface_create(Evas_Engine_Info_Wayland *info, Outbuf *ob) { Surface *out; @@ -19,7 +19,7 @@ _evas_surface_create(Evas_Engine_Info_Wayland *info, int w, int h, Outbuf *ob) out->info = info; out->ob = ob; - if (_evas_dmabuf_surface_create(out, w, h, ob->num_buff)) return out; + if (_evas_dmabuf_surface_create(out)) return out; free(out); return NULL; @@ -29,8 +29,6 @@ Outbuf * _evas_outbuf_setup(int w, int h, Evas_Engine_Info_Wayland *info) { Outbuf *ob = NULL; - char *num; - int sw, sh; LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -46,39 +44,9 @@ _evas_outbuf_setup(int w, int h, Evas_Engine_Info_Wayland *info) ob->priv.destination_alpha = info->info.destination_alpha; ob->ewd = info->info.wl2_display; - /* default to triple buffer */ - ob->num_buff = 3; - - /* check for any 'number of buffers' override in the environment */ - if ((num = getenv("EVAS_WAYLAND_SHM_BUFFERS"))) - { - int n = 0; - - n = atoi(num); - if (n <= 0) n = 1; - if (n > MAX_BUFFERS) n = MAX_BUFFERS; - - ob->num_buff = n; - } - - /* try to create the outbuf surface */ - if ((ob->rotation == 0) || (ob->rotation == 180)) - { - sw = w; - sh = h; - } - else if ((ob->rotation == 90) || (ob->rotation == 270)) - { - sw = h; - sh = w; - } - else - goto unhandled_rotation; - - ob->surface = _evas_surface_create(info, sw, sh, ob); + ob->surface = _evas_surface_create(info, ob); if (!ob->surface) goto surf_err; -unhandled_rotation: eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8); return ob; @@ -295,7 +263,6 @@ _evas_outbuf_swap_mode_get(Outbuf *ob) age = ob->surface->funcs.assign(ob->surface); if (!age) return MODE_FULL; - if (age > ob->num_buff) return MODE_FULL; else if (age == 1) return MODE_COPY; else if (age == 2) return MODE_DOUBLE; else if (age == 3) return MODE_TRIPLE; -- 2.7.4