From 4dee873ab6df2d5667f0fb996040839b1cc29ec7 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 1 Apr 2016 08:52:38 +0900 Subject: [PATCH] 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 --- src/lib/evas/canvas/evas_render.c | 53 ++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 911440929a..ea32a906ac 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -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); + } } }