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 95a00b8e49 by Derek Foreman

Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
Chris Michael 2016-10-26 11:56:04 -04:00
parent f3d1b2d7da
commit 0fa7abae7b
3 changed files with 31 additions and 12 deletions

View File

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

View File

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

View File

@ -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;
}