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.

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

Reply via email to