evas render: fix updates sometimes are list of rects sometimes updates

ssometimes the evas render updates are a list of Render_Updates
structs ... sometimes Eina_Rectangles. this is horrible and i think a
bug turns up (but its not reproducable on linux - just bsd) with an
invalid free ... likely because we free() a ptr from the mem pool
eina_rectangle gets rects from. thats most likely the cause of
https://phab.enlightenment.org/T3226 - but as i can't know for sure,
this is a guess, but readiong the code i see posible vectors of
problemss here ... maybe.

so this redoes the update rects to ALWAYS be Render_Updates struct
and appropriately returns correct structures etc. etc. in api which
demand a list of Eina_Rectangles there.

pending testing on foreign sysstems to confirm this by @netstar

@fix
This commit is contained in:
Carsten Haitzler 2016-04-01 08:52:38 +09:00
parent 5e9d838e60
commit 4dee873ab6
1 changed files with 35 additions and 18 deletions

View File

@ -2745,7 +2745,7 @@ evas_render_updates_internal(Evas *eo_e,
}
/* phase 6.2 render all the object on the target surface */
if (do_async)
if ((do_async) || (make_updates))
{
ru = malloc(sizeof(*ru));
ru->surface = surface;
@ -2755,17 +2755,6 @@ evas_render_updates_internal(Evas *eo_e,
evas_cache_image_ref(surface);
eina_spinlock_release(&(e->render.lock));
}
else if (make_updates)
{
Eina_Rectangle *rect;
NEW_RECT(rect, ux, uy, uw, uh);
eina_spinlock_take(&(e->render.lock));
if (rect)
e->render.updates = eina_list_append(e->render.updates,
rect);
eina_spinlock_release(&(e->render.lock));
}
clean_them |= evas_render_updates_internal_loop(eo_e, e, surface, e->engine.data.context,
NULL,
@ -2934,11 +2923,18 @@ evas_render_updates_internal(Evas *eo_e,
if (!do_async)
{
Evas_Event_Render_Post post;
Eina_List *l;
Render_Updates *ru;
post.updated_area = NULL;
EINA_LIST_FOREACH(e->render.updates, l, ru)
{
post.updated_area = eina_list_append(post.updated_area, ru->area);
}
eina_spinlock_take(&(e->render.lock));
post.updated_area = e->render.updates;
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, e->render.updates ? &post : NULL);
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, post.updated_area ? &post : NULL);
eina_spinlock_release(&(e->render.lock));
if (post.updated_area) eina_list_free(post.updated_area);
}
RD(0, "---]\n");
@ -3135,7 +3131,8 @@ evas_render_updates_internal_wait(Evas *eo_e,
EOLIAN Eina_List*
_evas_canvas_render_updates(Eo *eo_e, Evas_Public_Data *e)
{
Eina_List *ret;
Eina_List *ret, *updates = NULL;
Render_Updates *ru;
if (!e->changed) return NULL;
eina_evlog("+render_block", eo_e, 0.0, NULL);
evas_canvas_async_block(e);
@ -3143,19 +3140,31 @@ _evas_canvas_render_updates(Eo *eo_e, Evas_Public_Data *e)
eina_evlog("+render", eo_e, 0.0, NULL);
ret = evas_render_updates_internal_wait(eo_e, 1, 1);
eina_evlog("-render", eo_e, 0.0, NULL);
return ret;
EINA_LIST_FREE(ret, ru)
{
updates = eina_list_append(updates, ru->area);
free(ru);
}
return updates;
}
EOLIAN void
_evas_canvas_render(Eo *eo_e, Evas_Public_Data *e)
{
Eina_List *ret;
Render_Updates *ru;
if (!e->changed) return;
eina_evlog("+render_block", eo_e, 0.0, NULL);
evas_canvas_async_block(e);
eina_evlog("-render_block", eo_e, 0.0, NULL);
eina_evlog("+render", eo_e, 0.0, NULL);
evas_render_updates_internal_wait(eo_e, 0, 1);
ret = evas_render_updates_internal_wait(eo_e, 0, 1);
eina_evlog("-render", eo_e, 0.0, NULL);
EINA_LIST_FREE(ret, ru)
{
eina_rectangle_free(ru->area);
free(ru);
}
}
EOLIAN void
@ -3164,9 +3173,17 @@ _evas_canvas_norender(Eo *eo_e, Evas_Public_Data *e)
if (e->render2) _evas_norender2(eo_e, e);
else
{
Eina_List *ret;
Render_Updates *ru;
evas_canvas_async_block(e);
// if (!e->changed) return;
evas_render_updates_internal_wait(eo_e, 0, 0);
ret = evas_render_updates_internal_wait(eo_e, 0, 1);
EINA_LIST_FREE(ret, ru)
{
eina_rectangle_free(ru->area);
free(ru);
}
}
}