aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/evas/canvas/render2
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-03-20 14:18:17 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-03-20 18:03:54 +0900
commit2347c6ff01ab248cddcdc8607b16fa96b0d1fd0a (patch)
treec2323ae03eb18d29cadb0928abd277d2746f25cf /src/lib/evas/canvas/render2
parentevas-3d: materials in .mtl format are deleted (diff)
downloadefl-2347c6ff01ab248cddcdc8607b16fa96b0d1fd0a.tar.gz
evas render2 - restructure it to be an explicit api call - cleaner to do
Diffstat (limited to 'src/lib/evas/canvas/render2')
-rw-r--r--src/lib/evas/canvas/render2/evas_render2.c136
-rw-r--r--src/lib/evas/canvas/render2/evas_render2.h18
-rw-r--r--src/lib/evas/canvas/render2/evas_render2_old.c485
-rw-r--r--src/lib/evas/canvas/render2/evas_render2_old.h43
-rw-r--r--src/lib/evas/canvas/render2/evas_render2_updates_old.c78
5 files changed, 760 insertions, 0 deletions
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 <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);
+}
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 <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
diff --git a/src/lib/evas/canvas/render2/evas_render2_old.c b/src/lib/evas/canvas/render2/evas_render2_old.c
new file mode 100644
index 0000000000..4b30543381
--- /dev/null
+++ b/src/lib/evas/canvas/render2/evas_render2_old.c
@@ -0,0 +1,485 @@
+#include "evas_render2.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// this is the start of a rewrite of the evas rendering infra. first port of
+// call is to just make it work and still support async rendering with no
+// optimizations at all. once it WORKS properly start adding back
+// optimizations one at a time very carefully until it is equivalent to where
+// evas render was before, THEN... we can consider switching it on by default
+// but until then it's off unless you set:
+//
+// export EVAS_RENDER2=1
+//
+// at runtime.
+//////////////////////////////////////////////////////////////////////////////
+
+// data types
+//////////////////////////////////////////////////////////////////////////////
+typedef struct _Update Update;
+
+struct _Update
+{
+ Eina_Rectangle *area;
+ void *surface;
+};
+
+typedef struct _Update_Info Update_Info;
+
+struct _Update_Info
+{
+ void *surface;
+ int ux, uy, uw, uh;
+ int cx, cy, cw, ch;
+};
+
+// funcs
+//////////////////////////////////////////////////////////////////////////////
+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);
+
+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, Eina_Bool do_async);
+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, Eina_Bool do_async);
+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;
+
+ 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, 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());
+}
+
+static void
+_evas_render2_updates_clean(Evas_Public_Data *e)
+{
+ void *u;
+
+ // clean out updates and tmp surfaces we were holding/tracking
+ EINA_LIST_FREE(e->render.updates, u) eina_rectangle_free(u);
+}
+
+static void
+_evas_render2_stage_last(Eo *eo_e, Eina_Bool make_updates, Eina_Bool do_async)
+{
+ Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+ Eina_List *ret_updates = NULL;
+ Evas_Event_Render_Post post;
+
+ // XXX:
+ // 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)
+ {
+ Update *ru;
+
+ _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL);
+ EINA_LIST_FREE(e->render.updates, ru)
+ {
+ /* punch rect out */
+ e->engine.func->output_redraws_next_update_push
+ (e->engine.data.output, ru->surface,
+ ru->area->x, ru->area->y, ru->area->w, ru->area->h,
+ EVAS_RENDER_MODE_ASYNC_END);
+ ret_updates = eina_list_append(ret_updates, ru->area);
+ evas_cache_image_drop(ru->surface);
+ free(ru);
+ }
+ if (do_async) post.updated_area = ret_updates;
+ else e->render.updates = ret_updates;
+ 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 (do_async)
+ _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_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))
+ {
+ e->engine.func->output_resize(e->engine.data.output,
+ e->output.w, e->output.h);
+ e->engine.func->output_redraws_rect_add(e->engine.data.output, 0, 0,
+ e->output.w, e->output.h);
+ }
+ // if there are explicit update regions - add them
+ EINA_LIST_FREE(e->damages, r)
+ {
+ // if we didnt just do a full redraw if output changed
+ if ((!e->output.changed) && (!e->framespace.changed))
+ e->engine.func->output_redraws_rect_add(e->engine.data.output,
+ r->x, r->y, r->w, r->h);
+ eina_rectangle_free(r);
+ }
+ // remove obscures from rendering - we keep them around
+ 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);
+}
+
+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);
+}
+
+static void
+_evas_render2_object_render(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, Update_Info *uinf, int l)
+{
+ Evas_Object_Protected_Data *obj2;
+ Evas_Object *eo_obj = obj->object;
+ const Eina_Inlist *il;
+
+ if ((!evas_object_is_visible(eo_obj, obj)) ||
+ (obj->clip.clipees) || (obj->cur->have_clipees)) return;
+ il = evas_object_smart_members_get_direct(eo_obj);
+ if (il)
+ {
+ EINA_INLIST_FOREACH(il, obj2)
+ _evas_render2_object_render(e, obj2, uinf, l + 1);
+ }
+ else
+ {
+ void *ctx = e->engine.func->context_new(e->engine.data.output);
+ if (ctx)
+ {
+ int offx = uinf->cx - uinf->ux;
+ int offy = uinf->cy - uinf->uy;
+ int x, y, w, h;
+
+ x = obj->cur->cache.clip.x;
+ y = obj->cur->cache.clip.y;
+ w = obj->cur->cache.clip.w;
+ h = obj->cur->cache.clip.h;
+ e->engine.func->context_clip_set(e->engine.data.output,
+ ctx, x + offx, y + offy, w, h);
+ obj->func->render(eo_obj, obj, obj->private_data,
+ e->engine.data.output,
+ ctx, uinf->surface,
+ offx, offy,
+ EINA_FALSE);
+ e->engine.func->context_free(e->engine.data.output, ctx);
+ }
+ }
+}
+
+static void
+_evas_render2_stage_render_do(Evas_Public_Data *e, Eina_Bool do_async EINA_UNUSED)
+{
+ Update_Info uinf;
+ Eina_Bool alpha;
+
+ // XXX: actually render now (either in thread or in mainloop)
+ // XXX:
+ printf(" _evas_render2_stage_render_do %p\n", e);
+ alpha = e->engine.func->canvas_alpha_get(e->engine.data.output,
+ e->engine.data.context);
+ while ((uinf.surface =
+ e->engine.func->output_redraws_next_update_get
+ (e->engine.data.output,
+ &uinf.ux, &uinf.uy, &uinf.uw, &uinf.uh,
+ &uinf.cx, &uinf.cy, &uinf.cw, &uinf.ch)))
+ {
+ Update *ru = NULL;
+ Evas_Layer *lay;
+ Evas_Object_Protected_Data *obj;
+
+ // if the canvas has an alpha channel, we must fill the region with
+ // empty (0 value argb)
+ if (alpha)
+ {
+ void *ctx = e->engine.func->context_new(e->engine.data.output);
+
+ if (ctx)
+ {
+ e->engine.func->context_render_op_set
+ (e->engine.data.output, ctx, EVAS_RENDER_COPY);
+ e->engine.func->context_color_set
+ (e->engine.data.output, ctx, 0, 0, 0, 0);
+ e->engine.func->rectangle_draw(e->engine.data.output,
+ ctx, uinf.surface,
+ uinf.cx, uinf.cy,
+ uinf.cw, uinf.ch,
+ EINA_FALSE);
+ e->engine.func->context_free(e->engine.data.output, ctx);
+ }
+ }
+ EINA_INLIST_FOREACH(e->layers, lay)
+ {
+ EINA_INLIST_FOREACH(lay->objects, obj)
+ {
+ _evas_render2_object_render(e, obj, &uinf, 0);
+ }
+ }
+
+ ru = malloc(sizeof(*ru));
+ ru->surface = uinf.surface;
+ NEW_RECT(ru->area, uinf.ux, uinf.uy, uinf.uw, uinf.uh);
+ e->render.updates = eina_list_append(e->render.updates, ru);
+ evas_cache_image_ref(uinf.surface);
+ }
+ e->engine.func->output_redraws_clear(e->engine.data.output);
+}
+
+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);
+}
+
+static void
+_evas_render2_th_render(void *data)
+{
+ Evas_Public_Data *e = data;
+ printf(".....................................................%p\n", e);
+ _evas_render2_stage_render_do(e, EINA_TRUE);
+ printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%p\n", 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_CANVAS_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!");
+ // 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
+ _evas_render2_always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL);
+ // 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)
+ {
+ // 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)
+ {
+ // ref the canvas so it stays while threads work
+ eo_ref(eo_e);
+ // track canvas 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, EINA_FALSE);
+ }
+ // reset flags since rendering is processed now
+ _evas_render2_stage_reset(e);
+ // clean/delete/gc objects here
+ _evas_render2_stage_object_cleanup(e);
+ // 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, EINA_FALSE);
+ if (!do_draw) _evas_render2_updates_clean(e);
+ evas_module_clean();
+ return EINA_TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+// END RENDERING (in mainloop)
+///////////////////////////////////////////////////////////////////////
+static void
+_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_render2_stage_last(eo_e, EINA_TRUE, EINA_TRUE);
+ // release canvas object ref
+ eo_unref(eo_e);
+}
+
+///////////////////////////////////////////////////////////////////////
+// IDLE FLUSH (in mainloop)
+///////////////////////////////////////////////////////////////////////
+void
+_evas_render2_idle_flush(Eo *eo_e)
+{
+ Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+
+ // wait for rendering to finish so we don't mess up shared resources
+ _evas_render2_wait(eo_e);
+ // clean fonts
+ evas_fonts_zero_pressure(eo_e);
+ // call engine idle flush call
+ if ((e->engine.func) && (e->engine.func->output_idle_flush) &&
+ (e->engine.data.output))
+ e->engine.func->output_idle_flush(e->engine.data.output);
+ // mark as invalidated
+ e->invalidate = EINA_TRUE;
+ // garbage collect up to 500 cow segments from our cow types
+ // not e that we should probably expose a call to do this outside of evas
+ // so ecore evas can call it in an idler
+ _evas_render2_cow_all_gc(500);
+}
+
+///////////////////////////////////////////////////////////////////////
+// DUMP DATA (in mainloop)
+///////////////////////////////////////////////////////////////////////
+void
+_evas_render2_dump(Eo *eo_e)
+{
+ Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+
+ // freeze core cache system async work
+ evas_cache_async_freeze();
+ // wait for all canvases to render as they may share data we are dumping
+ _evas_render2_all_sync();
+ // go through idle flush first
+ _evas_render2_idle_flush(eo_e);
+ // also now tell engine to dump too
+ if ((e->engine.func) && (e->engine.func->output_dump) &&
+ (e->engine.data.output))
+ e->engine.func->output_dump(e->engine.data.output);
+ // clean up all cow sections no matter how many
+ _evas_render2_cow_all_gc(0);
+ // unfreeze core cache system
+ evas_cache_async_thaw();
+}
+
+///////////////////////////////////////////////////////////////////////
+// WAIT ON CANVAS RENDER (if async, in mainloop)
+///////////////////////////////////////////////////////////////////////
+void
+_evas_render2_wait(Eo *eo_e)
+{
+ Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+ while (e->rendering) evas_async_events_process_blocking();
+}
diff --git a/src/lib/evas/canvas/render2/evas_render2_old.h b/src/lib/evas/canvas/render2/evas_render2_old.h
new file mode 100644
index 0000000000..2eb77e7dc7
--- /dev/null
+++ b/src/lib/evas/canvas/render2/evas_render2_old.h
@@ -0,0 +1,43 @@
+#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
+
+#ifdef EVAS_RENDER_DEBUG_TIMING
+#include <sys/time.h>
+#endif
+
+/* render stuff here */
+void _evas_render2_stage_generate_object_updates(Evas_Public_Data *e);
+
+#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
+
+static inline void
+out_time(double t)
+{
+ double b;
+
+ b = (t * 100.0) / (1.0 / 60.0);
+ printf("%1.8fs (%1.2f%% 60fps budget)\n", t, b);
+}
+
+#endif
diff --git a/src/lib/evas/canvas/render2/evas_render2_updates_old.c b/src/lib/evas/canvas/render2/evas_render2_updates_old.c
new file mode 100644
index 0000000000..b17b934730
--- /dev/null
+++ b/src/lib/evas/canvas/render2/evas_render2_updates_old.c
@@ -0,0 +1,78 @@
+#include "evas_render2.h"
+
+static void
+_obj_basic_process(Evas_Public_Data *e,
+ Evas_Object_Protected_Data *obj, int l)
+{
+ Evas_Object *eo_obj = obj->object;
+
+ obj->rect_del = EINA_FALSE;
+ obj->render_pre = EINA_FALSE;
+ if (obj->delete_me == 2) return;
+ else if (obj->delete_me != 0) obj->delete_me++;
+ evas_object_clip_recalc(obj);
+ obj->is_active = 1;
+ obj->func->render_pre(eo_obj, obj, obj->private_data);
+ obj->pre_render_done = EINA_TRUE;
+ int i; for (i = 0; i < l; i++) printf(" ");
+ printf("BASIC %p %p [%10s]\n", e, eo_obj, obj->type);
+ obj->func->render_post(eo_obj, obj, obj->private_data);
+ obj->restack = EINA_FALSE;
+ obj->pre_render_done = EINA_FALSE;
+ evas_object_change_reset(eo_obj);
+}
+
+static void
+_obj_process(Evas_Public_Data *e,
+ Evas_Object_Protected_Data *obj, int l)
+{
+ // 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)
+ {
+ obj->rect_del = EINA_FALSE;
+ obj->render_pre = EINA_FALSE;
+ if (obj->delete_me == 2) return;
+ else if (obj->delete_me != 0) obj->delete_me++;
+ evas_object_clip_recalc(obj);
+ obj->is_active = 1;
+ obj->func->render_pre(eo_obj, obj, obj->private_data);
+ obj->pre_render_done = EINA_TRUE;
+ int i; for (i = 0; i < l; i++) printf(" ");
+ printf("SMART %p %p [%10s] ch %i\n", e, eo_obj, obj->type, obj->changed);
+
+ EINA_INLIST_FOREACH(il, obj2) _obj_process(e, obj2, l + 1);
+
+ obj->func->render_post(eo_obj, obj, obj->private_data);
+ obj->restack = EINA_FALSE;
+ obj->pre_render_done = EINA_FALSE;
+ evas_object_change_reset(eo_obj);
+ }
+ else _obj_basic_process(e, obj, l);
+}
+
+void
+_evas_render2_stage_generate_object_updates(Evas_Public_Data *e)
+{
+ Evas_Layer *lay;
+ Evas_Object_Protected_Data *obj;
+ double t;
+
+ static int num = 0;
+ printf("........... updates # %i\n", num++);
+ t = get_time();
+ EINA_INLIST_FOREACH(e->layers, lay)
+ {
+ EINA_INLIST_FOREACH(lay->objects, obj)
+ {
+ _obj_process(e, obj, 0);
+ }
+ }
+ t = get_time() - t;
+ printf("T: update generation: "); out_time(t);
+}