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

> Hi Cedric,
> 
> On Fri, Dec 20, 2013 at 11:14 PM, Cedric BAIL <[email protected]> wrote:
> > Cedric Bail
> > On Dec 21, 2013 2:44 AM, "Ulisses Furquim" <[email protected]> wrote:
> >>
> >> 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.
> >
> > The goal is to basically spawn more smaller threads to be able to do things
> > like:
> > - asynchronous rendering for all backend
> > - smaller task division per thread to be able to have more CPU running at a
> > likely lower frequency to use less battery.
> > - rendering map surface first (should improve gl speed)
> > - tile based rendering to have a sane pipe render that does actually
> > improve performance (should also make mask and filter doable sanely)
> > - specialize thread for io / cpu / memory bound task
> > - cleaner and saner code to handle proxy, map and the tree hierarchy of our
> > modern use of efl.
> >
> > That the basic idea behind this change which is the result of what we
> > learned over the year with our current infrastructure and applications. The
> > work to do is insanely huge, but worth it even if not all the goal are met.
> 
> Thanks! Yes, sounds like an ambitious plan. If we do some of the first
> point and improve map and proxy rendering would be awesome already.
> :-)

that's one of the main things i hope to come from this.

fix up all of the nasty corner-case bugs in map+proxy by building render
code from the ground up to deal with "pre-render buffers for later use".

also i can move the generation of buffers to a "prepare" stage... maybe prepare
2 (after first stage prepare). then all map/proxy buffers can get pre-rendered
before the main "composition" stage kicks in. :)

> -- Ulisses
> 
> >
> > Cedric
> >
> >> -- 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
> >>
> > ------------------------------------------------------------------------------
> > 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