evas render2 - restructure it to be an explicit api call - cleaner to do

This commit is contained in:
Carsten Haitzler 2015-03-20 14:18:17 +09:00
parent 59271716ba
commit 2347c6ff01
9 changed files with 217 additions and 85 deletions

View 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 \

View 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.

View File

@ -10,13 +10,7 @@
#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
@ -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();
}
}

View File

@ -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);
}

View File

@ -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

View 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