ecore-evas: Async render

SVN revision: 81283
This commit is contained in:
Leandro Pereira 2012-12-18 16:27:26 +00:00
parent a7b4a3c12d
commit 613659b1d8
2 changed files with 428 additions and 255 deletions

View File

@ -312,6 +312,20 @@ struct _Ecore_Evas
Ecore_Evas_Engine engine;
Eina_List *sub_ecore_evas;
struct {
unsigned char avoid_damage;
unsigned char resize_shape : 1;
unsigned char shaped : 1;
unsigned char shaped_changed : 1;
unsigned char alpha : 1;
unsigned char alpha_changed : 1;
unsigned char transparent : 1;
unsigned char transparent_changed : 1;
int rotation;
int rotation_resize;
unsigned char rotation_changed : 1;
} delayed;
int refcount;
unsigned char ignore_events : 1;
@ -322,6 +336,8 @@ struct _Ecore_Evas
unsigned char deleted : 1;
int gl_sync_draw_done; // added by gl77.lee
unsigned char profile_supported : 1;
unsigned char in_async_render : 1;
unsigned char can_async_render : 1;
};
EAPI void _ecore_evas_ref(Ecore_Evas *ee);

View File

@ -99,6 +99,13 @@ static Ecore_Evas_Interface_Software_X11 *_ecore_evas_x_interface_software_x11_n
static Ecore_Evas_Interface_Gl_X11 *_ecore_evas_x_interface_gl_x11_new(void);
#endif
static void _resize_shape_do(Ecore_Evas *);
static void _shaped_do(Ecore_Evas *, int);
static void _alpha_do(Ecore_Evas *, int);
static void _transparent_do(Ecore_Evas *, int);
static void _avoid_damage_do(Ecore_Evas *, int);
static void _rotation_do(Ecore_Evas *, int, int);
static void
_ecore_evas_x_hints_update(Ecore_Evas *ee)
{
@ -422,29 +429,11 @@ _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y,
#endif
static int
_ecore_evas_x_render(Ecore_Evas *ee)
_render_updates_process(Ecore_Evas *ee, Eina_List *updates)
{
int rend = 0;
Eina_List *updates = NULL;
Eina_List *ll;
Ecore_Evas *ee2;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
(edata->sync_counter) && (!edata->sync_began) &&
(!edata->sync_cancel))
return 0;
EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
{
if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
if (ee2->engine.func->fn_render)
rend |= ee2->engine.func->fn_render(ee2);
if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
}
if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
updates = evas_render_updates(ee->evas);
if (ee->prop.avoid_damage)
{
if (edata->using_bg_pixmap)
@ -567,6 +556,7 @@ _ecore_evas_x_render(Ecore_Evas *ee)
evas_render_updates_free(updates);
if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
/*
if (rend)
{
@ -585,19 +575,92 @@ _ecore_evas_x_render(Ecore_Evas *ee)
}
}
*/
return rend;
}
static void
_ecore_evas_x_resize_shape(Ecore_Evas *ee)
_ecore_evas_x_render_updates(void *data, Evas *e EINA_UNUSED, void *event_info)
{
Ecore_Evas *ee = data;
Eina_List *updates = event_info;
_render_updates_process(ee, updates);
ee->in_async_render = EINA_FALSE;
if (ee->delayed.resize_shape)
{
_resize_shape_do(ee);
ee->delayed.resize_shape = EINA_FALSE;
}
if (ee->delayed.shaped_changed)
{
_shaped_do(ee, ee->delayed.shaped);
ee->delayed.shaped_changed = EINA_FALSE;
}
if (ee->delayed.alpha_changed)
{
_alpha_do(ee, ee->delayed.alpha);
ee->delayed.alpha_changed = EINA_FALSE;
}
if (ee->delayed.transparent_changed)
{
_transparent_do(ee, ee->delayed.transparent);
ee->delayed.transparent_changed = EINA_FALSE;
}
if (ee->delayed.avoid_damage != ee->prop.avoid_damage)
_avoid_damage_do(ee, ee->delayed.avoid_damage);
if (ee->delayed.rotation_changed)
{
_rotation_do(ee, ee->delayed.rotation, ee->delayed.rotation_resize);
ee->delayed.rotation_changed = EINA_FALSE;
}
}
static int
_ecore_evas_x_render(Ecore_Evas *ee)
{
int rend = 0;
Eina_List *ll;
Ecore_Evas *ee2;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if (!strcmp(ee->driver, "software_x11"))
if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
(edata->sync_counter) && (!edata->sync_began) &&
(!edata->sync_cancel))
return 0;
EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
{
if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
if (ee2->engine.func->fn_render)
rend |= ee2->engine.func->fn_render(ee2);
if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
}
if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
if (ee->can_async_render)
{
ee->in_async_render |= evas_render_async(ee->evas,
_ecore_evas_x_render_updates,
ee);
rend |= ee->in_async_render;
}
else
{
Eina_List *updates;
updates = evas_render_updates(ee->evas);
rend = _render_updates_process(ee, updates);
}
return rend;
}
static void
_resize_shape_do(Ecore_Evas *ee)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
Evas_Engine_Info_Software_X11 *einfo;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (einfo)
@ -623,6 +686,19 @@ _ecore_evas_x_resize_shape(Ecore_Evas *ee)
}
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
}
static void
_ecore_evas_x_resize_shape(Ecore_Evas *ee)
{
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->in_async_render)
{
ee->delayed.resize_shape = EINA_TRUE;
return;
}
_resize_shape_do(ee);
}
}
/* TODO: we need to make this work for all the states, not just sticky */
@ -1870,6 +1946,45 @@ _ecore_evas_x_rotation_effect_setup(void)
}
#endif /* end of _USE_WIN_ROT_EFFECT */
static void
_rotation_do(Ecore_Evas *ee, int rotation, int resize)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
#if _USE_WIN_ROT_EFFECT
int angles[2];
angles[0] = rotation;
angles[1] = ee->rotation;
#endif /* end of _USE_WIN_ROT_EFFECT */
Evas_Engine_Info_Software_X11 *einfo;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (!einfo) return;
einfo->info.rotation = rotation;
_ecore_evas_x_rotation_set_internal(ee, rotation, resize,
(Evas_Engine_Info *)einfo);
# if _USE_WIN_ROT_EFFECT
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
if ((ee->visible) &&
((ecore_x_e_comp_sync_supported_get(edata->win_root)) &&
(!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) &&
(edata->sync_counter) &&
(edata->sync_val > 0))
{
_ecore_evas_x_rotation_effect_setup();
_ecore_evas_x_flush_pre(ee, NULL, NULL);
}
# else
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
# endif
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
}
static void
_ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
{
@ -1906,24 +2021,15 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
}
else if (!strcmp(ee->driver, "software_x11"))
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
Evas_Engine_Info_Software_X11 *einfo;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (!einfo) return;
einfo->info.rotation = rotation;
_ecore_evas_x_rotation_set_internal(ee, rotation, resize,
(Evas_Engine_Info *)einfo);
# if _USE_WIN_ROT_EFFECT
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
# else
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
# endif
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
if (ee->in_async_render)
{
ee->delayed.rotation = rotation;
ee->delayed.rotation_resize = resize;
ee->delayed.rotation_changed = EINA_TRUE;
return;
}
_rotation_do(ee, rotation, resize);
return;
}
#if _USE_WIN_ROT_EFFECT
@ -1940,17 +2046,13 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
}
static void
_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if ((ee->shaped == shaped)) return;
if (!strcmp(ee->driver, "opengl_x11")) return;
if (!strcmp(ee->driver, "software_x11"))
_shaped_do(Ecore_Evas *ee, int shaped)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
Evas_Engine_Info_Software_X11 *einfo;
if ((ee->shaped == shaped)) return;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
ee->shaped = shaped;
if (einfo)
@ -1992,22 +2094,33 @@ _ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
}
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
}
}
/* FIXME, round trip */
static void
_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
Ecore_X_Window_Attributes att;
char *id = NULL;
if ((ee->alpha == alpha)) return;
if (!strcmp(ee->driver, "opengl_x11")) return;
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->in_async_render)
{
ee->delayed.shaped = shaped;
ee->delayed.shaped_changed = EINA_TRUE;
return;
}
_shaped_do(ee, shaped);
}
}
static void
_alpha_do(Ecore_Evas *ee, int alpha)
{
char *id = NULL;
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
Ecore_X_Window_Attributes att;
Evas_Engine_Info_Software_X11 *einfo;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if ((ee->alpha == alpha)) return;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (!einfo) return;
@ -2090,9 +2203,30 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
// putenv((char*)"DESKTOP_STARTUP_ID=");
}
}
/* FIXME, round trip */
static void
_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
{
Ecore_X_Window_Attributes att;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
char *id = NULL;
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->in_async_render)
{
ee->delayed.alpha = alpha;
ee->delayed.alpha_changed = EINA_TRUE;
return;
}
_alpha_do(ee, alpha);
}
else if (!strcmp(ee->driver, "opengl_x11"))
{
#ifdef BUILD_ECORE_EVAS_OPENGL_X11
if ((ee->alpha == alpha)) return;
Evas_Engine_Info_GL_X11 *einfo;
einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
@ -2214,13 +2348,11 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
}
static void
_ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
{
if ((ee->transparent == transparent)) return;
if (!strcmp(ee->driver, "software_x11"))
_transparent_do(Ecore_Evas *ee, int transparent)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
if ((ee->transparent == transparent)) return;
Evas_Engine_Info_Software_X11 *einfo;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
@ -2235,6 +2367,20 @@ _ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
#endif
}
static void
_ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
{
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->in_async_render)
{
ee->delayed.transparent = transparent;
ee->delayed.transparent_changed = EINA_TRUE;
return;
}
_transparent_do(ee, transparent);
}
}
static void
@ -2687,17 +2833,11 @@ _ecore_evas_x_profiles_set(Ecore_Evas *ee, const char **plist, int n)
}
static void
_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if (ee->prop.avoid_damage == on) return;
if (!strcmp(ee->driver, "opengl_x11")) return;
if (!strcmp(ee->driver, "software_x11"))
_avoid_damage_do(Ecore_Evas *ee, int on)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
Evas_Engine_Info_Software_X11 *einfo;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
ee->prop.avoid_damage = on;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
@ -2751,6 +2891,22 @@ _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
}
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
}
static void
_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
{
if (ee->prop.avoid_damage == on) return;
if (!strcmp(ee->driver, "opengl_x11")) return;
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->in_async_render)
{
ee->delayed.avoid_damage = on;
return;
}
_avoid_damage_do(ee, on);
}
}
static void
@ -3014,6 +3170,7 @@ ecore_evas_software_x11_new_internal(const char *disp_name, Ecore_X_Window paren
ee->prop.request_pos = 0;
ee->prop.sticky = 0;
edata->state.sticky = 0;
ee->can_async_render = 1;
/* init evas here */
ee->evas = evas_new();