diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index af00028038..d992380837 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -131,9 +131,8 @@ lib/evas/canvas/evas_object_grid.c \ lib/evas/canvas/evas_font_dir.c \ lib/evas/canvas/evas_rectangle.c \ lib/evas/canvas/evas_render.c \ -lib/evas/canvas/evas_render2.c \ -lib/evas/canvas/evas_render2.h \ -lib/evas/canvas/evas_render2_updates.c \ +lib/evas/canvas/render2/evas_render2.c \ +lib/evas/canvas/render2/evas_render2.h \ lib/evas/canvas/evas_smart.c \ lib/evas/canvas/evas_stack.c \ lib/evas/canvas/evas_async_events.c \ @@ -287,6 +286,8 @@ lib/evas/common/evas_text_utils.h \ lib/evas/common/evas_font_ot.h lib_evas_libevas_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ +-I$(top_srcdir)/src/lib/evas/canvas \ +-I$(top_srcdir)/src/lib/evas/canvas/render2 \ -I$(top_srcdir)/src/lib/evas/common \ -I$(top_srcdir)/src/lib/evas/cserve2 \ -I$(top_srcdir)/src/lib/evas/file \ diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo index 94e1082d7b..6ce459e0c5 100644 --- a/src/lib/evas/canvas/evas_canvas.eo +++ b/src/lib/evas/canvas/evas_canvas.eo @@ -875,6 +875,24 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface) return: bool; } + render2 { + /*@ + Render the given Evas canvas using the new rendering infra. + + This is experimental and will change over time until noted here. + + @return EINA_TRUE if the canvas will render, EINA_FALSE otherwise. + + This function only returns EINA_TRUE when a frame will be rendered. If the + previous frame is still rendering, EINA_FALSE will be returned so the users + know not to wait for the updates callback and just return to their main + loop. + + @ingroup Evas_Canvas + @since 1.14 */ + + return: bool; + } focus_out { /*@ Inform to the evas that it lost the focus. diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 81fa68b26f..b761bbe00d 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -10,13 +10,7 @@ #include #endif -// 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); - +#include "evas_render2.h" /* debug rendering * NOTE: Define REND_DBG 1 in evas_private.h to enable debugging. Don't define @@ -2755,22 +2749,18 @@ evas_render_updates_free(Eina_List *updates) eina_rectangle_free(r); } +EOLIAN Eina_Bool +_evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e) +{ + return _evas_render2(eo_e, e); +} + EOLIAN Eina_Bool _evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e) { - static int render_2 = -1; - evas_canvas_async_block(e); - if (render_2 == -1) - { - if (getenv("EVAS_RENDER2")) render_2 = 1; - else render_2 = 0; - } - if (render_2) - return _evas_render2_begin(eo_e, EINA_TRUE, EINA_TRUE, EINA_TRUE); - else - return evas_render_updates_internal(eo_e, 1, 1, evas_render_pipe_wakeup, - e, EINA_TRUE); + return evas_render_updates_internal(eo_e, 1, 1, evas_render_pipe_wakeup, + e, EINA_TRUE); } static Eina_List * @@ -2780,18 +2770,7 @@ evas_render_updates_internal_wait(Evas *eo_e, { Eina_List *ret = NULL; Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); - static int render_2 = -1; - - if (render_2 == -1) - { - if (getenv("EVAS_RENDER2")) render_2 = 1; - else render_2 = 0; - } - if (render_2) - { - if (!_evas_render2_begin(eo_e, make_updates, do_draw, EINA_FALSE)) - return NULL; - } + if (e->render2) return _evas_render2_updates_wait(eo_e, e); else { if (!evas_render_updates_internal(eo_e, make_updates, do_draw, NULL, @@ -2824,37 +2803,31 @@ _evas_canvas_render(Eo *eo_e, Evas_Public_Data *e) EOLIAN void _evas_canvas_norender(Eo *eo_e, Evas_Public_Data *e) { - evas_canvas_async_block(e); - // if (!e->changed) return; - evas_render_updates_internal_wait(eo_e, 0, 0); + if (e->render2) _evas_norender2(eo_e, e); + else + { + evas_canvas_async_block(e); + // if (!e->changed) return; + evas_render_updates_internal_wait(eo_e, 0, 0); + } } EOLIAN void _evas_canvas_render_idle_flush(Eo *eo_e, Evas_Public_Data *e) { - static int render_2 = -1; - - evas_canvas_async_block(e); - if (render_2 == -1) - { - if (getenv("EVAS_RENDER2")) render_2 = 1; - else render_2 = 0; - } - if (render_2) - { - _evas_render2_idle_flush(eo_e); - } + if (e->render2) _evas_render2_idle_flush(eo_e, e); else { + evas_canvas_async_block(e); evas_render_rendering_wait(e); - + evas_fonts_zero_pressure(eo_e); - + if ((e->engine.func) && (e->engine.func->output_idle_flush) && (e->engine.data.output)) e->engine.func->output_idle_flush(e->engine.data.output); - + OBJS_ARRAY_FLUSH(&e->active_objects); OBJS_ARRAY_FLUSH(&e->render_objects); OBJS_ARRAY_FLUSH(&e->restack_objects); @@ -2863,7 +2836,7 @@ _evas_canvas_render_idle_flush(Eo *eo_e, Evas_Public_Data *e) OBJS_ARRAY_FLUSH(&e->temporary_objects); eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL); eina_array_clean(&e->clip_changes); - + e->invalidate = EINA_TRUE; } } @@ -2871,18 +2844,12 @@ _evas_canvas_render_idle_flush(Eo *eo_e, Evas_Public_Data *e) EOLIAN void _evas_canvas_sync(Eo *eo_e, Evas_Public_Data *e) { - static int render_2 = -1; - - evas_canvas_async_block(e); - if (render_2 == -1) - { - if (getenv("EVAS_RENDER2")) render_2 = 1; - else render_2 = 0; - } - if (render_2) - _evas_render2_wait(eo_e); + if (e->render2) _evas_render2_sync(eo_e, e); else - evas_render_rendering_wait(e); + { + evas_canvas_async_block(e); + evas_render_rendering_wait(e); + } } void @@ -2908,31 +2875,22 @@ _evas_render_dump_map_surfaces(Evas_Object *eo_obj) } EOLIAN void -_evas_canvas_render_dump(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +_evas_canvas_render_dump(Eo *eo_e, Evas_Public_Data *e) { - static int render_2 = -1; - - evas_canvas_async_block(e); - if (render_2 == -1) - { - if (getenv("EVAS_RENDER2")) render_2 = 1; - else render_2 = 0; - } - if (render_2) - { - _evas_render2_dump(eo_e); - } + if (e->render2) _evas_render2_dump(eo_e, e); else { Evas_Layer *lay; - + + evas_canvas_async_block(e); + evas_all_sync(); evas_cache_async_freeze(); - + EINA_INLIST_FOREACH(e->layers, lay) { Evas_Object_Protected_Data *obj; - + EINA_INLIST_FOREACH(lay->objects, obj) { if (obj->proxy) @@ -2964,13 +2922,13 @@ _evas_canvas_render_dump(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) GC_ALL(evas_object_image_pixels_cow); GC_ALL(evas_object_image_load_opts_cow); GC_ALL(evas_object_image_state_cow); - + evas_fonts_zero_pressure(eo_e); - + if ((e->engine.func) && (e->engine.func->output_idle_flush) && (e->engine.data.output)) e->engine.func->output_idle_flush(e->engine.data.output); - + OBJS_ARRAY_FLUSH(&e->active_objects); OBJS_ARRAY_FLUSH(&e->render_objects); OBJS_ARRAY_FLUSH(&e->restack_objects); @@ -2979,9 +2937,9 @@ _evas_canvas_render_dump(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) OBJS_ARRAY_FLUSH(&e->temporary_objects); eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL); eina_array_clean(&e->clip_changes); - + e->invalidate = EINA_TRUE; - + evas_cache_async_thaw(); } } diff --git a/src/lib/evas/canvas/render2/evas_render2.c b/src/lib/evas/canvas/render2/evas_render2.c new file mode 100644 index 0000000000..04596b9990 --- /dev/null +++ b/src/lib/evas/canvas/render2/evas_render2.c @@ -0,0 +1,136 @@ +#include "evas_render2.h" + +#ifdef EVAS_RENDER_DEBUG_TIMING +#include +#endif + +#ifndef _WIN32 +static inline double +get_time(void) +{ + struct timeval timev; + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} +#else +static inline double +get_time(void) +{ + return (double)GetTickCount()/1000.0; +} +#endif + + + + + + + + + +// a list of canvases currently rendering +static Eina_List *_rendering = NULL; + +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); +} + +static void +_always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) +{ + int freeze_num = 0, i; + + eo_do(eo_e, freeze_num = eo_event_freeze_count_get()); + 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()); +} + + +Eina_Bool +_evas_render2(Eo *eo_e, Evas_Public_Data *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 + if (e->rendering) return EINA_FALSE; + // mark this canvas as a render2 canvas - not normal render + e->render2 = EINA_TRUE; + // 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!"); + + // wait for any previous render pass to do its thing + evas_canvas_async_block(e); + // we have to calculate smare objects before render so do that here + evas_call_smarts_calculate(eo_e); + // 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 + eo_ref(eo_e); + // XXX: 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 + _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); + + printf("%p %p\n", eo_e, e); + return EINA_FALSE; +} + +void +_evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +{ + evas_canvas_async_block(e); +} + +Eina_List * +_evas_render2_updates_wait(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +{ + evas_canvas_async_block(e); + return NULL; +} + +void +_evas_render2_idle_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +{ + evas_canvas_async_block(e); +} + +void +_evas_render2_sync(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +{ + evas_canvas_async_block(e); +} + +void +_evas_render2_dump(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 new file mode 100644 index 0000000000..95982dcef6 --- /dev/null +++ b/src/lib/evas/canvas/render2/evas_render2.h @@ -0,0 +1,18 @@ +#ifndef EVAS_RENDER2_H +#define EVAS_RENDER2_H +#include "evas_common_private.h" +#include "evas_private.h" +#include +#include +#ifdef EVAS_CSERVE2 +#include "evas_cs2_private.h" +#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_wait(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); + +#endif diff --git a/src/lib/evas/canvas/evas_render2.c b/src/lib/evas/canvas/render2/evas_render2_old.c similarity index 100% rename from src/lib/evas/canvas/evas_render2.c rename to src/lib/evas/canvas/render2/evas_render2_old.c diff --git a/src/lib/evas/canvas/evas_render2.h b/src/lib/evas/canvas/render2/evas_render2_old.h similarity index 100% rename from src/lib/evas/canvas/evas_render2.h rename to src/lib/evas/canvas/render2/evas_render2_old.h diff --git a/src/lib/evas/canvas/evas_render2_updates.c b/src/lib/evas/canvas/render2/evas_render2_updates_old.c similarity index 100% rename from src/lib/evas/canvas/evas_render2_updates.c rename to src/lib/evas/canvas/render2/evas_render2_updates_old.c diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index a3f06e1dae..b1c82e59ca 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -803,6 +803,7 @@ struct _Evas_Public_Data unsigned char focus : 1; Eina_Bool is_frozen : 1; Eina_Bool rendering : 1; + Eina_Bool render2 : 1; }; struct _Evas_Layer