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 \
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 \
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.
#include <sys/time.h>
#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
}
EOLIAN Eina_Bool
-_evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e)
+_evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e)
{
- static int render_2 = -1;
+ return _evas_render2(eo_e, e);
+}
+EOLIAN Eina_Bool
+_evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e)
+{
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 *
{
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,
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);
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;
}
}
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 (e->render2) _evas_render2_sync(eo_e, e);
+ else
{
- if (getenv("EVAS_RENDER2")) render_2 = 1;
- else render_2 = 0;
+ evas_canvas_async_block(e);
+ evas_render_rendering_wait(e);
}
- if (render_2)
- _evas_render2_wait(eo_e);
- else
- evas_render_rendering_wait(e);
}
void
}
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)
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);
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();
}
}
--- /dev/null
+#include "evas_render2.h"
+
+#ifdef EVAS_RENDER_DEBUG_TIMING
+#include <sys/time.h>
+#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);
+}
--- /dev/null
+#ifndef EVAS_RENDER2_H
+#define EVAS_RENDER2_H
+#include "evas_common_private.h"
+#include "evas_private.h"
+#include <math.h>
+#include <assert.h>
+#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
unsigned char focus : 1;
Eina_Bool is_frozen : 1;
Eina_Bool rendering : 1;
+ Eina_Bool render2 : 1;
};
struct _Evas_Layer