raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=25983dceddeda7d07220e97e227cd4c814707039
commit 25983dceddeda7d07220e97e227cd4c814707039 Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com> Date: Tue Jun 2 20:39:57 2015 +0900 evas render2 work - begin to make rectangles deal with render 2 basic infra --- src/lib/evas/canvas/evas_canvas.eo | 16 ++ src/lib/evas/canvas/evas_object_rectangle.c | 79 +++++- src/lib/evas/canvas/evas_object_smart.c | 2 - src/lib/evas/canvas/evas_render.c | 11 + src/lib/evas/canvas/render2/evas_render2.c | 80 ++++--- src/lib/evas/canvas/render2/evas_render2.h | 3 +- src/lib/evas/canvas/render2/evas_render2_th_main.c | 265 +++++++++++++++++++++ src/lib/evas/include/evas_private.h | 9 + src/modules/ecore_evas/engines/x/ecore_evas_x.c | 43 +++- 9 files changed, 462 insertions(+), 46 deletions(-) diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo index d6dc105..79462c7 100644 --- a/src/lib/evas/canvas/evas_canvas.eo +++ b/src/lib/evas/canvas/evas_canvas.eo @@ -892,6 +892,22 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface) return: bool; } + render2_updates { + /*@ + Render the given Evas canvas using the new rendering infra. + + This is experimental and will change over time until noted here. + + @return A newly allocated list of updated rectangles of thecanvas + (@c Eina.Rectangle structs). Free this list with + evas_render_updates_free(). + + @ingroup Evas_Canvas + @since 1.15 */ + + return: free(own(list<Eina.Rectangle *> *), evas_render_updates_free) + @warn_unused; + } focus_out { /*@ Inform to the evas that it lost the focus. diff --git a/src/lib/evas/canvas/evas_object_rectangle.c b/src/lib/evas/canvas/evas_object_rectangle.c index cdee4ad..8f603e6 100644 --- a/src/lib/evas/canvas/evas_object_rectangle.c +++ b/src/lib/evas/canvas/evas_object_rectangle.c @@ -41,6 +41,13 @@ static int evas_object_rectangle_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *type_private_data); +static void evas_object_rectangle_render2_walk(Evas_Object *eo_obj, + Evas_Object_Protected_Data *obj, + void *type_private_data, + void *updates, + int offx, + int offy); + #if 0 /* usless calls for a rect object. much more useful for images etc. */ static void evas_object_rectangle_store(Evas_Object *eo_obj); static void evas_object_rectangle_unstore(Evas_Object *eo_obj); @@ -73,7 +80,8 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, - NULL + NULL, + evas_object_rectangle_render2_walk }; /* the actual api call to add a rect */ @@ -117,6 +125,75 @@ evas_object_rectangle_init(Evas_Object *eo_obj) } static void +evas_object_rectangle_render2_walk(Evas_Object *eo_obj, + Evas_Object_Protected_Data *obj, + void *type_private_data EINA_UNUSED, + void *updates, int offx, int offy) +{ + Eina_Bool visible_is, visible_was; + unsigned int col_prev, col_cur; + + if (obj->clip.clipees) return; + visible_is = evas_object_is_visible(eo_obj, obj); + if (!obj->changed) goto nochange; + + if ((obj->cur->clipper) && (obj->cur->cache.clip.dirty)) + evas_object_clip_recalc(obj->cur->clipper); + visible_was = evas_object_was_visible(eo_obj,obj); + // just became visible or invisible + if (visible_is != visible_was) + { + printf(" UP1 %p - %i %i %ix%i\n", eo_obj, + obj->cur->cache.clip.x, obj->cur->cache.clip.y, + obj->cur->cache.clip.w, obj->cur->cache.clip.h); + evas_common_tilebuf_add_redraw + (updates, + obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, + obj->cur->cache.clip.w, obj->cur->cache.clip.h); + return; + } + // general change (prev and cur clip geom change) + col_prev = (obj->prev->color.a << 24) | (obj->prev->color.r << 16) | + (obj->prev->color.g << 8) | (obj->prev->color.b ); + col_cur = (obj->cur->color.a << 24) | (obj->cur->color.r << 16) | + (obj->cur->color.g << 8) | (obj->cur->color.b ); + if ((col_prev != col_cur) || + ((obj->cur->cache.clip.x != obj->prev->cache.clip.x) || + (obj->cur->cache.clip.y != obj->prev->cache.clip.y) || + (obj->cur->cache.clip.w != obj->prev->cache.clip.w) || + (obj->cur->cache.clip.h != obj->prev->cache.clip.h)) || + (obj->cur->render_op != obj->prev->render_op) || + (obj->restack) + ) + { + printf(" UP2 %p - %i %i %ix%i\n", eo_obj, + obj->prev->cache.clip.x, obj->prev->cache.clip.y, + obj->prev->cache.clip.w, obj->prev->cache.clip.h); + evas_common_tilebuf_add_redraw + (updates, + obj->prev->cache.clip.x - offx, obj->prev->cache.clip.y - offy, + obj->prev->cache.clip.w, obj->prev->cache.clip.h); + evas_common_tilebuf_add_redraw + (updates, + obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, + obj->cur->cache.clip.w, obj->cur->cache.clip.h); + return; + } +nochange: + // object hasn't really changed + if ((visible_is) && (evas_object_is_opaque(eo_obj, obj))) + { + printf(" NO- %p - %i %i %ix%i\n", eo_obj, + obj->cur->cache.clip.x, obj->cur->cache.clip.y, + obj->cur->cache.clip.w, obj->cur->cache.clip.h); + evas_common_tilebuf_del_redraw + (updates, + obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, + obj->cur->cache.clip.w, obj->cur->cache.clip.h); + } +} + +static void evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, void *type_private_data EINA_UNUSED, diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 3aeb937..b5ced9e 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -434,7 +434,6 @@ _evas_object_smart_members_get(Eo *eo_obj, Evas_Smart_Data *o) Eina_List *members = NULL; Eina_Inlist *member; - evas_object_async_block(obj); for (member = o->contained; member; member = member->next) members = eina_list_append(members, ((Evas_Object_Protected_Data *)member)->object); @@ -448,7 +447,6 @@ evas_object_smart_members_get_direct(const Evas_Object *eo_obj) MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); return NULL; MAGIC_CHECK_END(); - evas_object_async_block(obj); if (!eo_isa(eo_obj, MY_CLASS)) return NULL; Evas_Smart_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); return o->contained; diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 0625f35..b97552c 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -2818,6 +2818,17 @@ _evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e) return ret; } +EOLIAN Eina_List * +_evas_canvas_render2_updates(Eo *eo_e, Evas_Public_Data *e) +{ + Eina_List *updates = NULL; + + eina_evlog("+render2_updates", eo_e, 0.0, NULL); + updates = _evas_render2_updates(eo_e, e); + eina_evlog("-render2_updates", eo_e, 0.0, NULL); + return updates; +} + EOLIAN Eina_Bool _evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e) { diff --git a/src/lib/evas/canvas/render2/evas_render2.c b/src/lib/evas/canvas/render2/evas_render2.c index b4080e4..803101b 100644 --- a/src/lib/evas/canvas/render2/evas_render2.c +++ b/src/lib/evas/canvas/render2/evas_render2.c @@ -1,6 +1,5 @@ #include "evas_render2.h" -#ifdef EVAS_RENDER_DEBUG_TIMING #include <sys/time.h> #ifndef _WIN32 @@ -23,12 +22,8 @@ static inline void out_time(double t) { double b = (t * 100.0) / (1.0 / 60.0); - printf("%1.8fs (%1.2f%% 60fps budget)\n", t, b); + printf("%1.2f%% / 60fps\n", b); } -#endif - -// a list of canvases currently rendering -static Eina_List *_rendering = NULL; static void _always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) @@ -41,10 +36,31 @@ _always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze()); } +// a list of canvases currently rendering +static Eina_List *_rendering = NULL; + +// just put the thread code inlined here for now as opposed to separate files +#include "evas_render2_th_main.c" + +// init all relevant render threads if needed +static void +_evas_render2_th_init(void) +{ + static Eina_Bool initted = EINA_FALSE; + + if (initted) return; + initted = EINA_TRUE; + _th_main_queue = eina_thread_queue_new(); + if (!eina_thread_create(&_th_main, EINA_THREAD_URGENT, 0, + _evas_render2_th_main, NULL)) + ERR("Cannot create render2 thread"); +} Eina_Bool _evas_render2(Eo *eo_e, Evas_Public_Data *e) { + double t; + // 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 @@ -55,61 +71,61 @@ _evas_render2(Eo *eo_e, Evas_Public_Data *e) if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) ERR("viewport size != output size!"); + // if render threads not initted - init them - maybe move this later? + _evas_render2_th_init(); + + printf("------------------------------------------------ %p %p\n", eo_e, e); // wait for any previous render pass to do its thing + t = get_time(); evas_canvas_async_block(e); + t = get_time() - t; + printf("T: block wait: "); out_time(t); // we have to calculate smare objects before render so do that here + t = get_time(); evas_call_smarts_calculate(eo_e); + t = get_time() - t; + printf("T: smart calc: "); out_time(t); // call canvas callbacks saying we are in the pre-render state _always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL); // bock any susbequent rneders from doing this walk eina_lock_take(&(e->lock_objects)); - // XXX: gain a reference + // gain a reference eo_ref(eo_e); - // XXX: put into the "i'm rendering" pool + // put into the "i'm rendering" pool e->rendering = EINA_TRUE; _rendering = eina_list_append(_rendering, eo_e); - // XXX; should wake up thread here to begin doing it's work - - - // XXX: call this from object walk thread - eina_lock_release(&(e->lock_objects)); - // XXX: remove from the "i'm rendering" pool - do back in mainloop - e->rendering = EINA_FALSE; - _rendering = eina_list_remove(_rendering, eo_e); - - - - // XXX: like below - call from thread messages - figure out if they just - // should be dumbly called before render post anyway + // call our flush pre at this point before rendering begins... _always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL); - _always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); - // XXX: call render post - should be a result from thread message called - // from mainloop - also fill in post struct - Evas_Event_Render_Post post; - _always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post); - // XXX: release our reference - eo_unref(eo_e); + // tell main render thread to wake up and begin processing this canvas + _evas_render2_th_main_msg_render(eo_e, e); - printf("%p %p\n", eo_e, e); return EINA_FALSE; } -void -_evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +Eina_List * +_evas_render2_updates(Eo *eo_e, Evas_Public_Data *e) { - evas_canvas_async_block(e); + if (!_evas_render2(eo_e, e)) return NULL; + return _evas_render2_updates_wait(eo_e, e); } Eina_List * _evas_render2_updates_wait(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) { evas_canvas_async_block(e); + while (e->rendering) evas_async_events_process_blocking(); return NULL; } void +_evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +{ + evas_canvas_async_block(e); +} + +void _evas_render2_idle_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) { evas_canvas_async_block(e); diff --git a/src/lib/evas/canvas/render2/evas_render2.h b/src/lib/evas/canvas/render2/evas_render2.h index 95982dc..bdad709 100644 --- a/src/lib/evas/canvas/render2/evas_render2.h +++ b/src/lib/evas/canvas/render2/evas_render2.h @@ -9,8 +9,9 @@ #endif Eina_Bool _evas_render2(Eo *eo_e, Evas_Public_Data *e); -void _evas_norender2(Eo *eo_e, Evas_Public_Data *e); +Eina_List *_evas_render2_updates(Eo *eo_e, Evas_Public_Data *e); Eina_List *_evas_render2_updates_wait(Eo *eo_e, Evas_Public_Data *e); +void _evas_norender2(Eo *eo_e, Evas_Public_Data *e); void _evas_render2_idle_flush(Eo *eo_e, Evas_Public_Data *e); void _evas_render2_sync(Eo *eo_e, Evas_Public_Data *e); void _evas_render2_dump(Eo *eo_e, Evas_Public_Data *e); diff --git a/src/lib/evas/canvas/render2/evas_render2_th_main.c b/src/lib/evas/canvas/render2/evas_render2_th_main.c new file mode 100644 index 0000000..c462d87 --- /dev/null +++ b/src/lib/evas/canvas/render2/evas_render2_th_main.c @@ -0,0 +1,265 @@ +//#define DBG_OBJTREE 1 + +#define OBJ_ARRAY_PUSH(array, obj) \ + do \ + { \ + eina_array_push(array, obj); \ + eo_data_ref(obj->object, NULL); \ + } while (0) + +#define OBJS_ARRAY_CLEAN(array) \ + do \ + { \ + Evas_Object_Protected_Data *item; \ + Eina_Array_Iterator iterator; \ + unsigned int idx; \ + EINA_ARRAY_ITER_NEXT(array, idx, item, iterator) \ + eo_data_unref(item->object, item); \ + eina_array_clean(array); \ + } while (0) + +typedef struct _Msg_Main_Render Msg_Main_Render; +typedef struct _Render2_Finish_Data Render2_Finish_Data; + +struct _Msg_Main_Render +{ + Eina_Thread_Queue_Msg head; + Eo *eo_e; + Evas_Public_Data *e; +}; + +struct _Render2_Finish_Data +{ + Eo *eo_e; + Evas_Public_Data *e; + Eina_List *updates; +}; + +static Eina_Thread_Queue *_th_main_queue = NULL; +static Eina_Thread _th_main; + +#ifdef DBG_OBJTREE +static void +indent(int l) +{ + int i; for (i = 0; i < l; i++) printf(" "); +} +#endif + +static void +_evas_render2_th_main_delete_objects_clean(Evas_Public_Data *e) +{ + Evas_Object_Protected_Data *obj; + unsigned int i; + double t; + + // cleanup deferred object deletion + t = get_time(); + for (i = 0; i < e->delete_objects.count; ++i) + { + obj = eina_array_data_get(&e->delete_objects, i); + evas_object_free(obj->object, 1); + } +// OBJS_ARRAY_CLEAN(&e->delete_objects); + eina_array_clean(&e->delete_objects); + t = get_time() - t; + printf("T: object deletion: "); out_time(t); +} + +static void +_evas_render2_th_main_mainloop_done(void *data, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Render2_Finish_Data *render_finish_data = data; + Evas_Event_Render_Post post; + Eo *eo_e; + Evas_Public_Data *e; + Eina_Rectangle *rect; + + e = render_finish_data->e; + eo_e = render_finish_data->eo_e; + // call the flush post callbacks + _always_call(render_finish_data->eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); + + // and now call the actual render post callbacks with updates list + post.updated_area = render_finish_data->updates; + _always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post); + + EINA_LIST_FREE(render_finish_data->updates, rect) free(rect); + free(render_finish_data); + _evas_render2_th_main_delete_objects_clean(e); +} + +static Eina_Bool +_evas_render2_th_main_obj_del_handle(Evas_Public_Data *e, + Evas_Object_Protected_Data *obj) +{ + if (obj->delete_me == 2) + { + OBJ_ARRAY_PUSH(&e->delete_objects, obj); + obj->delete_me++; + return EINA_FALSE; + } + else if (obj->delete_me != 0) obj->delete_me++; + return EINA_TRUE; +} + +static void +_evas_render2_th_main_obj_basic_process(Evas_Public_Data *e, + Evas_Object_Protected_Data *obj, + void *updates, + int offx, + int offy, + int l EINA_UNUSED) +{ + Evas_Object *eo_obj = obj->object; + + if (!_evas_render2_th_main_obj_del_handle(e, obj)) return; + evas_object_clip_recalc(obj); +#ifdef DBG_OBJTREE + indent(l); printf("BASIC %p %p [%10s]\n", e, eo_obj, obj->type); +#endif + if (obj->func->render2_walk) + obj->func->render2_walk(eo_obj, obj, obj->private_data, + updates, offx, offy); + if (obj->changed) + { + evas_object_clip_changes_clean(eo_obj); + evas_object_cur_prev(eo_obj); + evas_object_change_reset(eo_obj); + } +} + +static void +_evas_render2_th_main_obj_process(Evas_Public_Data *e, + Evas_Object_Protected_Data *obj, + void *updates, + int offx, + int offy, + int l EINA_UNUSED) +{ + // process object OR walk through child objects if smart and process those + Evas_Object_Protected_Data *obj2; + Evas_Object *eo_obj = obj->object; + const Eina_Inlist *il; + + if (!obj->changed) return; + il = evas_object_smart_members_get_direct(eo_obj); + if (il) + { + if (!_evas_render2_th_main_obj_del_handle(e, obj)) return; + evas_object_clip_recalc(obj); +#ifdef DBG_OBJTREE + indent(l); printf("SMART %p %p [%10s] ch %i\n", e, eo_obj, obj->type, obj->changed); +#endif + if (obj->func->render2_walk) + obj->func->render2_walk(eo_obj, obj, obj->private_data, + updates, offx, offy); + EINA_INLIST_FOREACH(il, obj2) + _evas_render2_th_main_obj_process(e, obj2, updates, + offx, offy, l + 1); + if (obj->changed) + { + evas_object_clip_changes_clean(eo_obj); + evas_object_cur_prev(eo_obj); + evas_object_change_reset(eo_obj); + } + } + else _evas_render2_th_main_obj_basic_process(e, obj, updates, + offx, offy, l); +} + +static void +_evas_render2_th_main_do(Eo *eo_e, Evas_Public_Data *e) +{ + Render2_Finish_Data *render_finish_data; + Evas_Layer *lay; + Evas_Object_Protected_Data *obj; + double t; + Tilebuf *updates = NULL; + Tilebuf_Rect *rects, *r; + Eina_List *updates_list = NULL; + Eina_Rectangle *rect; + + updates = evas_common_tilebuf_new(e->output.w, e->output.h); + evas_common_tilebuf_set_tile_size(updates, TILESIZE, TILESIZE); +// evas_common_tilebuf_tile_strict_set(updates, EINA_TRUE); + static int num = 0; + printf("........... updates # %i\n", num++); + t = get_time(); + EINA_INLIST_FOREACH(e->layers, lay) + { + EINA_INLIST_FOREACH(lay->objects, obj) + { + _evas_render2_th_main_obj_process(e, obj, + updates, 0, 0, + 0); + } + } + t = get_time() - t; + printf("T: update generation: "); out_time(t); + + rects = evas_common_tilebuf_get_render_rects(updates); + EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) + { + rect = malloc(sizeof(Eina_Rectangle)); + if (rect) + { + printf(" %i %i %ix%i\n", r->x, r->y, r->w, r->h); + rect->x = r->x; rect->y = r->y; + rect->w = r->w; rect->h = r->h; + updates_list = eina_list_append(updates_list, rect); + } + } + evas_common_tilebuf_free_render_rects(rects); + + evas_common_tilebuf_free(updates); + + e->changed = EINA_FALSE; + // remove from the "i'm rendering" pool - do back in mainloop + e->rendering = EINA_FALSE; + _rendering = eina_list_remove(_rendering, eo_e); + // unblock mainlopp that may be waiting on the render thread + eina_lock_release(&(e->lock_objects)); + + // send back + render_finish_data = calloc(1, sizeof(Render2_Finish_Data)); + if (render_finish_data) + { + render_finish_data->eo_e = eo_e; + render_finish_data->e = e; + render_finish_data->updates = updates_list; + evas_async_events_put(render_finish_data, 0, NULL, + _evas_render2_th_main_mainloop_done); + } + else + { + EINA_LIST_FREE(updates_list, rect) free(rect); + } + eo_unref(eo_e); +} + +static void * +_evas_render2_th_main(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED) +{ + void *ref = NULL; + Msg_Main_Render *msg; + + for (;;) + { + msg = eina_thread_queue_wait(_th_main_queue, &ref); + _evas_render2_th_main_do(msg->eo_e, msg->e); + eina_thread_queue_wait_done(_th_main_queue, ref); + } + return NULL; +} + +static void +_evas_render2_th_main_msg_render(Eo *eo_e, Evas_Public_Data *e) +{ + void *ref; + Msg_Main_Render *msg = + eina_thread_queue_send(_th_main_queue, sizeof(Msg_Main_Render), &ref); + msg->eo_e = eo_e; + msg->e = e; + eina_thread_queue_send_done(_th_main_queue, ref); +} diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 52feb58..b2678df 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1216,6 +1216,15 @@ struct _Evas_Object_Func Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); int (*can_map) (Evas_Object *obj); + +// new render2 functions + + void (*render2_walk) (Evas_Object *obj, Evas_Object_Protected_Data *pd, + void *type_private_data, void *updates, + int offx, int offy); +// void (*render2) (Evas_Object *obj, Evas_Object_Protected_Data *pd, +// void *type_private_data, void *output, void *context, +// void *surface, int x, int y); }; struct _Evas_Func diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 63ccfbc..a090da7 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -759,6 +759,7 @@ _ecore_evas_x_render(Ecore_Evas *ee) Eina_List *ll; Ecore_Evas *ee2; Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data; + static int render2 = -1; if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && (edata->sync_counter) && (!edata->sync_began) && @@ -780,20 +781,42 @@ _ecore_evas_x_render(Ecore_Evas *ee) } if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - if (!ee->can_async_render) + if (render2 == -1) { - Eina_List *updates = evas_render_updates(ee->evas); - rend = _render_updates_process(ee, updates); - evas_render_updates_free(updates); + if (getenv("RENDER2")) render2 = 1; + else render2 = 0; } - else if (evas_render_async(ee->evas)) + if (render2) { - EDBG("ee=%p started asynchronous render.", ee); - ee->in_async_render = EINA_TRUE; - rend = 1; + if (!ee->can_async_render) + { + Eina_List *updates = evas_render2_updates(ee->evas); + rend = _render_updates_process(ee, updates); + evas_render_updates_free(updates); + } + else + { + ee->in_async_render = EINA_TRUE; + if (evas_render2(ee->evas)) rend = 1; + else ee->in_async_render = EINA_FALSE; + } + } + else + { + if (!ee->can_async_render) + { + Eina_List *updates = evas_render_updates(ee->evas); + rend = _render_updates_process(ee, updates); + evas_render_updates_free(updates); + } + else if (evas_render_async(ee->evas)) + { + EDBG("ee=%p started asynchronous render.", ee); + ee->in_async_render = EINA_TRUE; + rend = 1; + } + else if (ee->func.fn_post_render) ee->func.fn_post_render(ee); } - else if (ee->func.fn_post_render) ee->func.fn_post_render(ee); - return rend; } --