forked from enlightenment/efl
Merge branch 'devs/devilhorns/wip'
This push merges some changes to the evas wayland shm engine. These changes help to reduce dropped frames, fix max buffer age, provide a better next buffer selection algorithm, and move buffer flipping out of the render thread. In total, these provide better wayland_shm engine performance. These patches are based on previous drm engine work by Derek Foreman.
This commit is contained in:
commit
c759ec6362
|
@ -649,11 +649,11 @@ _evas_dmabuf_buffer_init(Dmabuf_Surface *s, int w, int h)
|
|||
out->surface = s;
|
||||
out->bh = bm->alloc(bm, "name", w, h, &out->stride, &out->fd);
|
||||
if (!out->bh)
|
||||
{
|
||||
free(out);
|
||||
_fallback(s, w, h);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
free(out);
|
||||
_fallback(s, w, h);
|
||||
return NULL;
|
||||
}
|
||||
out->w = w;
|
||||
out->h = h;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ _evas_outbuf_setup(int w, int h, Evas_Engine_Info_Wayland_Shm *info)
|
|||
ob->depth = info->info.depth;
|
||||
ob->priv.destination_alpha = info->info.destination_alpha;
|
||||
|
||||
/* default to double buffer */
|
||||
ob->num_buff = 2;
|
||||
/* 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")))
|
||||
|
@ -199,12 +199,14 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf
|
|||
{
|
||||
Eina_Rectangle *result;
|
||||
RGBA_Image *img;
|
||||
unsigned int n = 0, i = 0;
|
||||
unsigned int i = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
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,8 +229,6 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf
|
|||
eina_rectangle_free(rect);
|
||||
}
|
||||
|
||||
ob->surface->funcs.post(ob->surface, result, n);
|
||||
|
||||
/* clean array */
|
||||
eina_array_clean(&ob->priv.onebuf_regions);
|
||||
|
||||
|
@ -245,11 +247,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 +309,6 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf
|
|||
|
||||
i++;
|
||||
}
|
||||
|
||||
ob->surface->funcs.post(ob->surface, result, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +320,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 +620,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;
|
||||
}
|
||||
|
|
|
@ -461,18 +461,19 @@ _evas_shm_surface_reconfigure(Surface *s, int w, int h, uint32_t flags)
|
|||
static Shm_Leaf *
|
||||
_evas_shm_surface_wait(Shm_Surface *surface)
|
||||
{
|
||||
int iterations = 0, i;
|
||||
int i = 0, best = -1, best_age = -1;
|
||||
|
||||
while (iterations++ < 10)
|
||||
for (i = 0; i < surface->num_buff; i++)
|
||||
{
|
||||
for (i = 0; i < surface->num_buff; i++)
|
||||
if (surface->leaf[i].busy) continue;
|
||||
if ((surface->leaf[i].valid) && (surface->leaf[i].age > best_age))
|
||||
{
|
||||
if (surface->leaf[i].busy) continue;
|
||||
if (surface->leaf[i].valid) return &surface->leaf[i];
|
||||
best = i;
|
||||
best_age = surface->leaf[i].age;
|
||||
}
|
||||
|
||||
wl_display_dispatch_pending(surface->disp);
|
||||
}
|
||||
|
||||
if (best >= 0) return &surface->leaf[best];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -506,7 +507,7 @@ _evas_shm_surface_assign(Surface *s)
|
|||
if (surface->leaf[i].valid && surface->leaf[i].drawn)
|
||||
{
|
||||
surface->leaf[i].age++;
|
||||
if (surface->leaf[i].age > surface->num_buff)
|
||||
if (surface->leaf[i].age > 4)
|
||||
{
|
||||
surface->leaf[i].age = 0;
|
||||
surface->leaf[i].drawn = EINA_FALSE;
|
||||
|
|
Loading…
Reference in New Issue