evas render2 - restructure it to be an explicit api call - cleaner to do
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Fri, 20 Mar 2015 05:18:17 +0000 (14:18 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Fri, 20 Mar 2015 09:03:54 +0000 (18:03 +0900)
src/Makefile_Evas.am
src/lib/evas/canvas/evas_canvas.eo
src/lib/evas/canvas/evas_render.c
src/lib/evas/canvas/render2/evas_render2.c [new file with mode: 0644]
src/lib/evas/canvas/render2/evas_render2.h [new file with mode: 0644]
src/lib/evas/canvas/render2/evas_render2_old.c [moved from src/lib/evas/canvas/evas_render2.c with 100% similarity]
src/lib/evas/canvas/render2/evas_render2_old.h [moved from src/lib/evas/canvas/evas_render2.h with 100% similarity]
src/lib/evas/canvas/render2/evas_render2_updates_old.c [moved from src/lib/evas/canvas/evas_render2_updates.c with 100% similarity]
src/lib/evas/include/evas_private.h

index af00028..d992380 100644 (file)
@@ -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 \
index 94e1082..6ce459e 100644 (file)
@@ -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.
index 81fa68b..b761bbe 100644 (file)
 #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
@@ -2756,21 +2750,17 @@ evas_render_updates_free(Eina_List *updates)
 }
 
 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 *
@@ -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 (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
@@ -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 (file)
index 0000000..04596b9
--- /dev/null
@@ -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 (file)
index 0000000..95982dc
--- /dev/null
@@ -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
index a3f06e1..b1c82e5 100644 (file)
@@ -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