On Fri, 20 Dec 2013 15:44:28 -0200 Ulisses Furquim <[email protected]> said:

> Iván,
> 
> On Fri, Dec 20, 2013 at 3:25 PM, Iván Briano <[email protected]> wrote:
> > The current async render is sending each render command to the thread,
> > and here it seems you want a thread to do the whole render.
> > That wasn't very clear, let's try again.
> >
> > Are you planning on messing with the object's render functions so they can
> > be called from a thread? As opposed as what we have now, where they are
> > called from the main loop, they in turn call the engine functions and these
> > will check the do_async flag to decide if they draw in place or if they
> > send a command to the render thread.
> 
> If he's going in that direction as it seems from the patch he'll have
> to change all of that and more. And we're also going to need to
> revisit several assumptions we had in the previous code and make other
> parts thread safe as well. It might be a better approach but not sure
> if after solving all the problems it's going to be worth it. I'll try
> to follow this closely.

i agree. it's a lot of work (see previous mail), and while the theory seems
sound, in practice... it's evil evil evil. i'm right now trying to settle the
thread infra so i can extend it to have > 1 thread going at a time. but before
i go to that, iw ant to just sketch out a rough bit of render2 infra. do not
consider this final in any way or form. it's a sandpit that can be played in
that is effectively branched from the main code, but it's in master and
switchable with a single evironment variable set. i am convinced we will need
this because frankly... it's going to be a long haul re-doing render infra and
we need to be able to switch back to "what works" trivially and yet get as much
testing of new stuff as possible. i don't think a git branch is the right way
to go here.

> -- Ulisses
> 
> > On Fri, Dec 20, 2013 at 11:46 AM, Ulisses Furquim <[email protected]>
> > wrote:
> >> Hi Raster,
> >>
> >> I see where you're heading... let's see the outcome. :-) I have a
> >> question below inline.
> >>
> >>
> >> On Fri, Dec 20, 2013 at 8:44 AM, Carsten Haitzler <[email protected]>
> >> wrote:
> >>>
> >>> raster pushed a commit to branch master.
> >>>
> >>> http://git.enlightenment.org/core/efl.git/commit/?id=cb841b56af11bbf787b36b3aaf6c6e69f1e1490f
> >>>
> >>> commit cb841b56af11bbf787b36b3aaf6c6e69f1e1490f
> >>> Author: Carsten Haitzler (Rasterman) <[email protected]>
> >>> Date:   Fri Dec 20 19:45:17 2013 +0900
> >>>
> >>>     evas render2 - more work on basics
> >>> ---
> >>>  src/lib/evas/canvas/evas_render.c  |  15 +-
> >>>  src/lib/evas/canvas/evas_render2.c | 459 ++++++++++++++++++++
> >>> +---------------- 2 files changed, 263 insertions(+), 211 deletions(-)
> >>>
> >>> diff --git a/src/lib/evas/canvas/evas_render.c
> >>> b/src/lib/evas/canvas/evas_render.c index 6dab39c..a6b5768 100644
> >>> --- a/src/lib/evas/canvas/evas_render.c
> >>> +++ b/src/lib/evas/canvas/evas_render.c
> >>> @@ -10,15 +10,12 @@
> >>>  #include <sys/time.h>
> >>>  #endif
> >>>
> >>> -Eina_Bool
> >>> -_evas_render2_begin(Eo *eo_e, Eina_Bool make_updates,
> >>> -                    Eina_Bool do_draw, Eina_Bool do_async);
> >>> -void
> >>> -_evas_render2_idle_flush(Eo *eo_e);
> >>> -void
> >>> -_evas_render2_dump(Eo *eo_e);
> >>> -void
> >>> -_evas_render2_wait(Eo *eo_e);
> >>> +// symbols of funcs from evas_render2 which is a next-gen replacement of
> >>> +// the current evas render code. see evas_render2.c for more.
> >>> +Eina_Bool _evas_render2_begin(Eo *eo_e, Eina_Bool make_updates,
> >>> Eina_Bool do_draw, Eina_Bool do_async); +void _evas_render2_idle_flush(Eo
> >>> *eo_e); +void _evas_render2_dump(Eo *eo_e);
> >>> +void _evas_render2_wait(Eo *eo_e);
> >>>
> >>>
> >>>  /* debug rendering
> >>> diff --git a/src/lib/evas/canvas/evas_render2.c
> >>> b/src/lib/evas/canvas/evas_render2.c index ce95b02..f853473 100644
> >>> --- a/src/lib/evas/canvas/evas_render2.c
> >>> +++ b/src/lib/evas/canvas/evas_render2.c
> >>> @@ -40,49 +40,193 @@ void _evas_render2_idle_flush(Eo *eo_e);
> >>>  void _evas_render2_dump(Eo *eo_e);
> >>>  void _evas_render2_wait(Eo *eo_e);
> >>>
> >>> -static void _evas_render2_end(Eo *eo_e);
> >>> -
> >>>  static void _evas_render2_cow_gc(Eina_Cow *cow, int max);
> >>>  static void _evas_render2_cow_all_gc(int max);
> >>>  static void _evas_render2_all_sync(void);
> >>>  static void _evas_render2_wakeup_cb(void *target, Evas_Callback_Type
> >>> type, void *event_info); static void _evas_render2_wakeup_send(void
> >>> *data); static void _evas_render2_always_call(Eo *eo_e,
> >>> Evas_Callback_Type type, void *event_info); +static void
> >>> _evas_render2_updates_clean(Evas_Public_Data *e); +static void
> >>> _evas_render2_stage_last(Eo *eo_e, Eina_Bool make_updates); +static void
> >>> _evas_render2_stage_generate_object_updates(Evas_Public_Data *e); +static
> >>> void _evas_render2_stage_explicit_updates(Evas_Public_Data *e); +static
> >>> void _evas_render2_stage_main_render_prepare(Evas_Public_Data *e);
> >>> +static void _evas_render2_stage_render_do(Evas_Public_Data *e); +static
> >>> void _evas_render2_stage_reset(Evas_Public_Data *e); +static void
> >>> _evas_render2_stage_object_cleanup(Evas_Public_Data *e); +static void
> >>> _evas_render2_th_render(void *data); +static void _evas_render2_end(Eo
> >>> *eo_e);
> >>>
> >>>  // global data (for rendering only)
> >>>  
> >>> //////////////////////////////////////////////////////////////////////////////
> >>>  static Eina_List *_rendering = NULL;
> >>>
> >>> +// actual helper/internal functions
> >>>  
> >>> //////////////////////////////////////////////////////////////////////////////
> >>> +static void
> >>> +_evas_render2_cow_gc(Eina_Cow *cow, int max)
> >>> +{
> >>> +   // gc a single cow type up to max iter or if max <= 0, all of them
> >>> +   int i = 0;
> >>>
> >>> -///////////////////////////////////////////////////////////////////////
> >>> -// BEGIN RENDERING (in mainloop)
> >>> -///////////////////////////////////////////////////////////////////////
> >>> -Eina_Bool
> >>> -_evas_render2_begin(Eo *eo_e, Eina_Bool make_updates,
> >>> -                    Eina_Bool do_draw, Eina_Bool do_async)
> >>> +   while (eina_cow_gc(cow))
> >>> +     {
> >>> +        if (max < 1) continue;
> >>> +        i++;
> >>> +        if (i > max) break;
> >>> +     }
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_cow_all_gc(int max)
> >>>  {
> >>> -   Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
> >>> -   Eina_Rectangle *r;
> >>> -   Eina_List *l;
> >>> +   // gc all known cow types
> >>> +   _evas_render2_cow_gc(evas_object_proxy_cow, max);
> >>> +   _evas_render2_cow_gc(evas_object_map_cow, max);
> >>> +   _evas_render2_cow_gc(evas_object_image_pixels_cow, max);
> >>> +   _evas_render2_cow_gc(evas_object_image_load_opts_cow, max);
> >>> +   _evas_render2_cow_gc(evas_object_image_state_cow, max);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_all_sync(void)
> >>> +{
> >>> +   // wait for ALL canvases to stop rendering
> >>> +   Eo *eo_e;
> >>>
> >>> -   // if nothing changed at all since last render - skip this frame
> >>> -   if (!e->changed) return EINA_FALSE;
> >>> -   // we are still rendering while being asked to render - skip this
> >>> frame
> >>> -   if (e->rendering && do_async) return EINA_FALSE;
> >>> -   // check viewport size is same as output - not allowed to differ
> >>> -   if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
> >>> -     ERR("viewport size != output size!");
> >>> +   if (!_rendering) return;
> >>> +   eo_e = eina_list_data_get(eina_list_last(_rendering));
> >>> +   _evas_render2_wait(eo_e);
> >>> +}
> >>>
> >>> -   // call canvas callbacks saying we are in the pre-render state
> >>> -   _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL);
> >>> -   // we have to calculate smare objects before render so do that here
> >>> -   evas_call_smarts_calculate(eo_e);
> >>> +static void
> >>> +_evas_render2_wakeup_cb(void *target, Evas_Callback_Type type
> >>> EINA_UNUSED, void *event_info EINA_UNUSED) +{
> >>> +   // in mainloop run the rendering end handler
> >>> +   Eo *eo_e = target;
> >>> +
> >>> +   _evas_render2_end(eo_e);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_wakeup_send(void *data)
> >>> +{
> >>> +   // pass an event to the mainloop async event handler in evas so
> >>> mainloop
> >>> +   // runs wakeup_cb and not in any thread
> >>> +   evas_async_events_put(data, 0, NULL, _evas_render2_wakeup_cb);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_always_call(Eo *eo_e, Evas_Callback_Type type, void
> >>> *event_info) +{
> >>> +   int freeze_num = 0, i;
> >>> +
> >>> +   eo_do(eo_e, eo_event_freeze_get(&freeze_num));
> >>> +   for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_thaw());
> >>> +   evas_event_callback_call(eo_e, type, event_info);
> >>> +   for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze());
> >>> +}
> >>>
> >>> +static void
> >>> +_evas_render2_updates_clean(Evas_Public_Data *e)
> >>> +{
> >>> +   Update *u;
> >>> +
> >>> +   // clean out updates and tmp surfaces we were holding/tracking
> >>> +   EINA_LIST_FREE(e->render.updates, u)
> >>> +     {
> >>> +        //evas_cache_image_drop(u->surface);
> >>> +        free(u);
> >>> +     }
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_stage_last(Eo *eo_e, Eina_Bool make_updates)
> >>> +{
> >>> +   Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
> >>> +
> >>>     // XXX:
> >>> -   // XXX: process all objects figuring out update regions
> >>> +   // XXX: actually update screen from mainloop here if needed - eg
> >>> software
> >>> +   // XXX: engine needs to xshmputimage here - engine func does this
> >>>     // XXX:
> >>> +
> >>> +   // if we did do rendering flush output to target and call callbacks
> >>> +   if (e->render.updates)
> >>> +     {
> >>> +        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE,
> >>> NULL);
> >>> +        e->engine.func->output_flush(e->engine.data.output,
> >>> +                                     EVAS_RENDER_MODE_ASYNC_END);
> >>> +        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST,
> >>> NULL);
> >>> +     }
> >>> +   // clear our previous rendering stuff from the engine
> >>> +   e->engine.func->output_redraws_clear(e->engine.data.output);
> >>> +   // stop tracking canvas as being async rendered
> >>> +   _rendering = eina_list_remove(_rendering, eo_e);
> >>> +   e->rendering = EINA_FALSE;
> >>> +   // call the post render callback with info if appropriate
> >>> +   if ((1) || (e->render.updates))
> >>> +     {
> >>> +        Evas_Event_Render_Post post;
> >>> +
> >>> +        post.updated_area = e->render.updates;
> >>> +        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST,
> >>> &post);
> >>> +     }
> >>> +   else
> >>> +     _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, NULL);
> >>> +   // if we don't want to keep updates after this
> >>> +   if (!make_updates) _evas_render2_updates_clean(e);
> >>> +   // clean out modules we don't need anymore
> >>> +   evas_module_clean();
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_object_basic_process(Evas_Public_Data *e,
> >>> +                                   Evas_Object_Protected_Data *obj)
> >>> +{
> >>> +   printf("_evas_render2_object_basic_process %p %p\n", e, obj);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_object_process(Evas_Public_Data *e,
> >>> +                             Evas_Object_Protected_Data *obj)
> >>> +{
> >>> +   // process object OR walk through child objects if smart and process
> >>> those
> >>> +   Evas_Object_Protected_Data *obj2;
> >>> +
> >>> +   // XXX: this needs to become parallel, BUT we need new object methods
> >>> to
> >>> +   // call to make that possible as the current ones work on a single
> >>> global
> >>> +   // engine handle and single orderted redraw queue.
> >>> +   if (obj->smart.smart)
> >>> +     {
> >>> +        EINA_INLIST_FOREACH
> >>> +        (evas_object_smart_members_get_direct(obj->object), obj2)
> >>> +          _evas_render2_object_process(e, obj2);
> >>> +     }
> >>> +   else _evas_render2_object_basic_process(e, obj);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_stage_generate_object_updates(Evas_Public_Data *e)
> >>> +{
> >>> +   Evas_Layer *lay;
> >>> +
> >>> +   // XXX: should time this
> >>> +   EINA_INLIST_FOREACH(e->layers, lay)
> >>> +     {
> >>> +        Evas_Object_Protected_Data *obj;
> >>>
> >>> +        EINA_INLIST_FOREACH(lay->objects, obj)
> >>> +          _evas_render2_object_process(e, obj);
> >>> +     }
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_stage_explicit_updates(Evas_Public_Data *e)
> >>> +{
> >>> +   Eina_Rectangle *r;
> >>> +   Eina_List *l;
> >>> +
> >>> +   // XXX: should time this
> >>>     // if the output size changed, add a full redraw
> >>>     if ((e->output.changed) || (e->framespace.changed))
> >>>       {
> >>> @@ -104,87 +248,111 @@ _evas_render2_begin(Eo *eo_e, Eina_Bool
> >>> make_updates, EINA_LIST_FOREACH(e->obscures, l, r)
> >>>       e->engine.func->output_redraws_rect_del(e->engine.data.output,
> >>>                                               r->x, r->y, r->w, r->h);
> >>> -
> >>> -   // we are actually asked to draw not just go through the motions for
> >>> gc
> >>> -   if (do_draw)
> >>> -     {
> >>> -        // XXX:
> >>> -        // XXX: RENDER HERE!
> >>> -        if (do_async)
> >>> -          {
> >>> -             // XXX: send off render commands
> >>> -          }
> >>> -        else
> >>> -          {
> >>> -             // XXX: do render that is sent of above right here
> >>> -          }
> >>> -        // XXX:
> >>> +}
> >>>
> >>> -        // if we are async...
> >>> -        if (do_async)
> >>> -          {
> >>> -             // ref the canvas so it stays while threads wortk
> >>> -             eo_ref(eo_e);
> >>> -             // track hanvas in list of things going in the background
> >>> -             e->rendering = EINA_TRUE;
> >>> -             _rendering = eina_list_append(_rendering, eo_e);
> >>> -             // flush the thread queue
> >>> -             evas_thread_queue_flush
> >>> -               ((Evas_Thread_Command_Cb)_evas_render2_wakeup_send, eo_e);
> >>> -          }
> >>> -        // if not async but we had actual update regions drawn
> >>> -        else if (e->render.updates)
> >>> -          {
> >>> -             // call output flush and callbacks around it
> >>> -             _evas_render2_always_call(eo_e,
> >>> EVAS_CALLBACK_RENDER_FLUSH_PRE,
> >>> -                                       NULL);
> >>> -             e->engine.func->output_flush(e->engine.data.output,
> >>> -                                          EVAS_RENDER_MODE_SYNC);
> >>> -             _evas_render2_always_call(eo_e,
> >>> EVAS_CALLBACK_RENDER_FLUSH_POST,
> >>> -                                       NULL);
> >>> -          }
> >>> -     }
> >>> +static void
> >>> +_evas_render2_stage_main_render_prepare(Evas_Public_Data *e)
> >>> +{
> >>> +   // XXX:
> >>> +   // XXX: do any preparation work here that is needed for the render
> >>> +   // XXX: threads to do their work, but can't be done in a thread. this
> >>> +   // XXX: also includes doing the pose render and clear of change flag
> >>> +   // XXX:
> >>> +   printf("_evas_render2_stage_main_render_prepare %p\n", e);
> >>> +}
> >>>
> >>> -   // reset flags sinc rendering is processed now
> >>> +static void
> >>> +_evas_render2_stage_render_do(Evas_Public_Data *e)
> >>> +{
> >>> +   // XXX:
> >>> +   // XXX: actually render now (either in thread or in mainloop)
> >>> +   // XXX:
> >>> +   printf("_evas_render2_stage_render_do %p\n", e);
> >>> +}
> >>> +
> >>> +static void
> >>> +_evas_render2_stage_reset(Evas_Public_Data *e)
> >>> +{
> >>> +   // cleanup canvas state after a render
> >>>     e->changed = EINA_FALSE;
> >>>     e->viewport.changed = EINA_FALSE;
> >>>     e->output.changed = EINA_FALSE;
> >>>     e->framespace.changed = EINA_FALSE;
> >>>     e->invalidate = EINA_FALSE;
> >>> +}
> >>>
> >>> +static void
> >>> +_evas_render2_stage_object_cleanup(Evas_Public_Data *e)
> >>> +{
> >>> +   // cleanup objects no longer needed now they have been scanned
> >>>     // XXX:
> >>>     // XXX: delete objects no longer needed here
> >>>     // XXX:
> >>> +   printf("_evas_render2_stage_object_cleanup %p\n", e);
> >>> +}
> >>>
> >>> -   // if we are not going to be async then do post render here
> >>> -   if (!do_async)
> >>> +static void
> >>> +_evas_render2_th_render(void *data)
> >>> +{
> >>> +   Evas_Public_Data *e = data;
> >>> +   printf("th rend %p\n", e);
> >>> +   _evas_render2_stage_render_do(e);
> >>> +}
> >>> +
> >>> +// major functions (called from evas_render.c)
> >>> +//////////////////////////////////////////////////////////////////////////////
> >>> +
> >>> +///////////////////////////////////////////////////////////////////////
> >>> +// BEGIN RENDERING (in mainloop)
> >>> +///////////////////////////////////////////////////////////////////////
> >>> +Eina_Bool
> >>> +_evas_render2_begin(Eo *eo_e, Eina_Bool make_updates,
> >>> +                    Eina_Bool do_draw, Eina_Bool do_async)
> >>> +{
> >>> +   Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
> >>> +
> >>> +   // if nothing changed at all since last render - skip this frame
> >>> +   if (!e->changed) return EINA_FALSE;
> >>> +   // we are still rendering while being asked to render - skip this
> >>> frame
> >>> +   if (e->rendering && do_async) return EINA_FALSE;
> >>> +   // check viewport size is same as output - not allowed to differ
> >>> +   if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
> >>> +     ERR("viewport size != output size!");
> >>> +   // call canvas callbacks saying we are in the pre-render state
> >>> +   _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL);
> >>> +   // we have to calculate smare objects before render so do that here
> >>> +   evas_call_smarts_calculate(eo_e);
> >>> +   // begin out actual rendering bits
> >>> +   _evas_render2_stage_generate_object_updates(e);
> >>> +   _evas_render2_stage_explicit_updates(e);
> >>> +   // we are actually asked to draw not just go through the motions for
> >>> gc
> >>> +   if (do_draw)
> >>>       {
> >>> -        // clear our previous rendering stuff from the engine
> >>> -        e->engine.func->output_redraws_clear(e->engine.data.output);
> >>> -        // call the post render callback with info if appropriate
> >>> -        if (e->render.updates)
> >>> -          {
> >>> -             Evas_Event_Render_Post post;
> >>> -
> >>> -             post.updated_area = e->render.updates;
> >>> -             _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST,
> >>> &post);
> >>> -          }
> >>> -        else
> >>> -          _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST,
> >>> NULL);
> >>> -        // clean out modules we don't need anymore
> >>> -        evas_module_clean();
> >>> -        // clean out updates and tmp surfaces we were holding/tracking
> >>> -        if (!make_updates)
> >>> +        // now go through any preparation that needs doing in the
> >>> mainloop
> >>> +        _evas_render2_stage_main_render_prepare(e);
> >>> +        // send off rendering to primary thread renderer
> >>> +        if (do_async)
> >>>            {
> >>> -             Update *u;
> >>> -
> >>> -             EINA_LIST_FREE(e->render.updates, u)
> >>> -               {
> >>> -                  //evas_cache_image_drop(u->surface);
> >>> -                  free(u);
> >>> -               }
> >>> +             // ref the canvas so it stays while threads wortk
> >>> +             eo_ref(eo_e);
> >>> +             // track hanvas in list of things going in the background
> >>> +             e->rendering = EINA_TRUE;
> >>> +             _rendering = eina_list_append(_rendering, eo_e);
> >>> +             // queue the render thread command
> >>> +             evas_thread_cmd_enqueue(_evas_render2_th_render, e);
> >>> +             // flush the thread queue and call wakeup_send in the thread
> >>> +             evas_thread_queue_flush(_evas_render2_wakeup_send, eo_e);
> >>>            }
> >>> +        // or if not async, do rendering inline now
> >>> +        else _evas_render2_stage_render_do(e);
> >>>       }
> >>> +   // reset flags since rendering is processed now
> >>> +   _evas_render2_stage_reset(e);
> >>> +   // clean/delete/gc objects here
> >>> +   _evas_render2_stage_object_cleanup(e);
> >>
> >> Don't we need to do these last 2 calls only if !do_async? And if
> >> do_async then in your wake up function in the mainloop you reset flags
> >> and cleanup objects?
> >>
> >> -- Ulisses
> >>
> >>> +   // if we are not going to be async then do last render stage here
> >>> +   if (!do_async) _evas_render2_stage_last(eo_e, make_updates);
> >>> +   if (!do_draw) _evas_render2_updates_clean(e);
> >>>     return EINA_TRUE;
> >>>  }
> >>>
> >>> @@ -197,50 +365,7 @@ _evas_render2_end(Eo *eo_e)
> >>>     // this is actually called if rendering was async and is done. this is
> >>>     // run in the mainloop where rendering began and may handle any
> >>> cleanup // or pixel upload if needed here
> >>> -   Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
> >>> -   Eina_Bool have_updates = EINA_FALSE;
> >>> -   Update *u;
> >>> -
> >>> -   // XXX:
> >>> -   // XXX: actually update screen from mainloop here if needed - eg
> >>> software
> >>> -   // engine needs to xshmputimage here
> >>> -   // XXX:
> >>> -
> >>> -   // clean out updates and tmp surfaces we were holding/tracking
> >>> -   if (e->render.updates)
> >>> -     {
> >>> -        have_updates = EINA_TRUE;
> >>> -        EINA_LIST_FREE(e->render.updates, u)
> >>> -          {
> >>> -             //evas_cache_image_drop(u->surface);
> >>> -             free(u);
> >>> -          }
> >>> -     }
> >>> -   // if we did do rendering flush output to target and call callbacks
> >>> -   if (have_updates)
> >>> -     {
> >>> -        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE,
> >>> NULL);
> >>> -        e->engine.func->output_flush(e->engine.data.output,
> >>> -                                     EVAS_RENDER_MODE_ASYNC_END);
> >>> -        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST,
> >>> NULL);
> >>> -     }
> >>> -   // clear our previous rendering stuff from the engine
> >>> -   e->engine.func->output_redraws_clear(e->engine.data.output);
> >>> -   // stop tracking canvas as being async rendered
> >>> -   _rendering = eina_list_remove(_rendering, eo_e);
> >>> -   e->rendering = EINA_FALSE;
> >>> -   // call the post render callback with info if appropriate
> >>> -   if (e->render.updates)
> >>> -     {
> >>> -        Evas_Event_Render_Post post;
> >>> -
> >>> -        post.updated_area = e->render.updates;
> >>> -        _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST,
> >>> &post);
> >>> -     }
> >>> -   else
> >>> -     _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, NULL);
> >>> -   // clean out modules we don't need anymore
> >>> -   evas_module_clean();
> >>> +   _evas_render2_stage_last(eo_e, EINA_TRUE);
> >>>     // release canvas object ref
> >>>     eo_unref(eo_e);
> >>>  }
> >>> @@ -302,73 +427,3 @@ _evas_render2_wait(Eo *eo_e)
> >>>     Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
> >>>     while (e->rendering) evas_async_events_process_blocking();
> >>>  }
> >>> -
> >>> -
> >>> -
> >>> -
> >>> -// helpers
> >>> -//////////////////////////////////////////////////////////////////////////////
> >>> -
> >>> -static void
> >>> -_evas_render2_cow_gc(Eina_Cow *cow, int max)
> >>> -{
> >>> -   // gc a single cow type up to max iter or if max <= 0, all of them
> >>> -   int i = 0;
> >>> -
> >>> -   while (eina_cow_gc(cow))
> >>> -     {
> >>> -        if (max < 1) continue;
> >>> -        i++;
> >>> -        if (i > max) break;
> >>> -     }
> >>> -}
> >>> -
> >>> -static void
> >>> -_evas_render2_cow_all_gc(int max)
> >>> -{
> >>> -   // gc all known cow types
> >>> -   _evas_render2_cow_gc(evas_object_proxy_cow, max);
> >>> -   _evas_render2_cow_gc(evas_object_map_cow, max);
> >>> -   _evas_render2_cow_gc(evas_object_image_pixels_cow, max);
> >>> -   _evas_render2_cow_gc(evas_object_image_load_opts_cow, max);
> >>> -   _evas_render2_cow_gc(evas_object_image_state_cow, max);
> >>> -}
> >>> -
> >>> -static void
> >>> -_evas_render2_all_sync(void)
> >>> -{
> >>> -   // wait for ALL canvases to stop rendering
> >>> -   Eo *eo_e;
> >>> -
> >>> -   if (!_rendering) return;
> >>> -   eo_e = eina_list_data_get(eina_list_last(_rendering));
> >>> -   _evas_render2_wait(eo_e);
> >>> -}
> >>> -
> >>> -static void
> >>> -_evas_render2_wakeup_cb(void *target, Evas_Callback_Type type
> >>> EINA_UNUSED, void *event_info EINA_UNUSED) -{
> >>> -   // in mainloop run the rendering end handler
> >>> -   Eo *eo_e = target;
> >>> -
> >>> -   _evas_render2_end(eo_e);
> >>> -}
> >>> -
> >>> -static void
> >>> -_evas_render2_wakeup_send(void *data)
> >>> -{
> >>> -   // pass an event to the mainloop async event handler in evas so
> >>> mainloop
> >>> -   // runs wakeup_cb and not in any thread
> >>> -   evas_async_events_put(data, 0, NULL, _evas_render2_wakeup_cb);
> >>> -}
> >>> -
> >>> -static void
> >>> -_evas_render2_always_call(Eo *eo_e, Evas_Callback_Type type, void
> >>> *event_info) -{
> >>> -   int freeze_num = 0, i;
> >>> -
> >>> -   eo_do(eo_e, eo_event_freeze_get(&freeze_num));
> >>> -   for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_thaw());
> >>> -   evas_event_callback_call(eo_e, type, event_info);
> >>> -   for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze());
> >>> -}
> >>>
> >>> --
> >>>
> >>>
> >>
> >> ------------------------------------------------------------------------------
> >> Rapidly troubleshoot problems before they affect your business. Most IT
> >> organizations don't have a clear picture of how application performance
> >> affects their revenue. With AppDynamics, you get 100% visibility into your
> >> Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics
> >> Pro!
> >> http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
> >> _______________________________________________ enlightenment-devel
> >> mailing list [email protected]
> >> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> >
> > ------------------------------------------------------------------------------
> > Rapidly troubleshoot problems before they affect your business. Most IT
> > organizations don't have a clear picture of how application performance
> > affects their revenue. With AppDynamics, you get 100% visibility into your
> > Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics
> > Pro!
> > http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
> > _______________________________________________ enlightenment-devel mailing
> > list [email protected]
> > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> 
> ------------------------------------------------------------------------------
> Rapidly troubleshoot problems before they affect your business. Most IT 
> organizations don't have a clear picture of how application performance 
> affects their revenue. With AppDynamics, you get 100% visibility into your 
> Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
> http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
> _______________________________________________
> enlightenment-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    [email protected]


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to