From 0fa7abae7b4acd5fb610fab49d99f82cc4153f90 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 26 Oct 2016 11:56:04 -0400 Subject: [PATCH] evas-wayland-shm: Get page flips out of the render thread Now that we have redraws_clear exposed through software generic, we can use that to do the final buffer swap from the main thread instead of doing it in outbuf_flush which runs from the render thread. This becomes more important later when other call sites in the main thread will perform buffer flips. Based on 95a00b8e496839c4976259692fb7c308f7a850dc by Derek Foreman Signed-off-by: Chris Michael --- src/modules/evas/engines/wayland_shm/evas_engine.c | 2 +- src/modules/evas/engines/wayland_shm/evas_engine.h | 4 +++ src/modules/evas/engines/wayland_shm/evas_outbuf.c | 37 +++++++++++++++------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.c b/src/modules/evas/engines/wayland_shm/evas_engine.c index ee339c1..817a126 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.c +++ b/src/modules/evas/engines/wayland_shm/evas_engine.c @@ -55,7 +55,7 @@ _render_engine_swapbuf_setup(int w, int h, Evas_Engine_Info_Wayland_Shm *einfo) _evas_outbuf_update_region_free, _evas_outbuf_idle_flush, _evas_outbuf_flush, - NULL, + _evas_outbuf_redraws_clear, _evas_outbuf_free, w, h)) goto err; diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.h b/src/modules/evas/engines/wayland_shm/evas_engine.h index 3cab22b..467e406 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.h +++ b/src/modules/evas/engines/wayland_shm/evas_engine.h @@ -125,6 +125,9 @@ struct _Outbuf /* list of previous frame pending regions to write out */ Eina_List *prev_pending_writes; + Eina_Rectangle *rects; + unsigned int rect_count; + /* Eina_Bool redraw : 1; */ Eina_Bool destination_alpha : 1; } priv; @@ -145,6 +148,7 @@ void *_evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int void _evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); void _evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); void _evas_surface_damage(struct wl_surface *s, int compositor_version, int w, int h, Eina_Rectangle *rects, unsigned int count); +void _evas_outbuf_redraws_clear(Outbuf *ob); Eina_Bool _evas_surface_init(Surface *s, int w, int h, int num_buf); diff --git a/src/modules/evas/engines/wayland_shm/evas_outbuf.c b/src/modules/evas/engines/wayland_shm/evas_outbuf.c index 6327b90..65a6388 100644 --- a/src/modules/evas/engines/wayland_shm/evas_outbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_outbuf.c @@ -205,6 +205,8 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + if (ob->priv.rect_count) free(ob->priv.rects); + /* check for pending writes */ if (!ob->priv.pending_writes) { @@ -212,11 +214,13 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf Eina_Array_Iterator it; /* get number of buffer regions */ - n = eina_array_count_get(&ob->priv.onebuf_regions); - if (n == 0) return; + ob->priv.rect_count = eina_array_count_get(&ob->priv.onebuf_regions); + if (ob->priv.rect_count == 0) return; /* allocate rectangles */ - if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return; + ob->priv.rects = malloc(ob->priv.rect_count * sizeof(Eina_Rectangle)); + if (!ob->priv.rects) return; + result = ob->priv.rects; /* loop the buffer regions and assign to result */ EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it) @@ -225,7 +229,7 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf eina_rectangle_free(rect); } - ob->surface->funcs.post(ob->surface, result, n); + /* ob->surface->funcs.post(ob->surface, result, n); */ /* clean array */ eina_array_clean(&ob->priv.onebuf_regions); @@ -245,11 +249,12 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf else { /* get number of pending writes */ - n = eina_list_count(ob->priv.pending_writes); - if (n == 0) return; + ob->priv.rect_count = eina_list_count(ob->priv.pending_writes); + if (ob->priv.rect_count == 0) return; - /* allocate rectangles */ - if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return; + ob->priv.rects = malloc(ob->priv.rect_count * sizeof(Eina_Rectangle)); + if (!ob->priv.rects) return; + result = ob->priv.rects; /* loop the pending writes */ EINA_LIST_FREE(ob->priv.pending_writes, img) @@ -306,8 +311,6 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf i++; } - - ob->surface->funcs.post(ob->surface, result, n); } } @@ -319,7 +322,10 @@ _evas_outbuf_swap_mode_get(Outbuf *ob) LOGFN(__FILE__, __LINE__, __FUNCTION__); age = ob->surface->funcs.assign(ob->surface); - if (age == 1) return MODE_COPY; + 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; else if (age == 4) return MODE_QUADRUPLE; @@ -616,3 +622,12 @@ _evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_ { LOGFN(__FILE__, __LINE__, __FUNCTION__); } + +void +_evas_outbuf_redraws_clear(Outbuf *ob) +{ + if (!ob->priv.rect_count) return; + ob->surface->funcs.post(ob->surface, ob->priv.rects, ob->priv.rect_count); + free(ob->priv.rects); + ob->priv.rect_count = 0; +} -- 2.7.4