evas render - cache object arrays rto avoid processing them in phase1

evas render in phase1 in order to generate update rects, active,
render etc. object arrays has to walk every object in our tree. this
is a waste of time if we already have walked objects in a previous
frame if they havent changed, so cache this data in render cache in
smart objects to avoid re-walking and now just dumbly "memcpy" these
cached arrays into the master array. i have seen cpu usage by e drop
like about 15% in the sencarios i'm looking at "enlightenment
compositor with some window updating animation all the time, but most
other stuff being static).

@optimize
This commit is contained in:
Carsten Haitzler 2016-11-26 10:47:34 +09:00
parent 1bba6d5759
commit 69cb85aaca
7 changed files with 318 additions and 63 deletions

View File

@ -2412,10 +2412,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
} }
} }
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e,
x + e->framespace.x, x + e->framespace.x,
y + e->framespace.y, y + e->framespace.y,
w, h); w, h);
} }
EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write)
{ {
@ -2504,10 +2504,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
} }
} }
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e,
x + e->framespace.x, x + e->framespace.x,
y + e->framespace.y, y + e->framespace.y,
w, h); w, h);
} }
else if ((o->cur->border.fill == EVAS_BORDER_FILL_SOLID) && else if ((o->cur->border.fill == EVAS_BORDER_FILL_SOLID) &&
(obj->cur->color.a == 255)) (obj->cur->color.a == 255))
@ -2532,10 +2532,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
} }
} }
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e,
x + e->framespace.x, x + e->framespace.x,
y + e->framespace.y, y + e->framespace.y,
w, h); w, h);
} }
EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write)
{ {
@ -2597,10 +2597,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
obj->cur->clipper->cur->cache.clip.w, obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h); obj->cur->clipper->cur->cache.clip.h);
} }
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e,
x + e->framespace.x, x + e->framespace.x,
y + e->framespace.y, y + e->framespace.y,
w, h); w, h);
changed_prep = EINA_FALSE; changed_prep = EINA_FALSE;
} }
else else

View File

@ -299,11 +299,10 @@ evas_object_rectangle_render_pre(Evas_Object *eo_obj,
obj->cur->clipper->cur->cache.clip.w, obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h); obj->cur->clipper->cur->cache.clip.h);
} }
obj->layer->evas->engine.func->output_redraws_rect_del evas_render_update_del(obj->layer->evas,
(obj->layer->evas->engine.data.output, x + obj->layer->evas->framespace.x,
x + obj->layer->evas->framespace.x, y + obj->layer->evas->framespace.y,
y + obj->layer->evas->framespace.y, w, h);
w, h);
} }
/* if it changed geometry - and obviously not visibility or color */ /* if it changed geometry - and obviously not visibility or color */
/* calculate differences since we have a constant color fill */ /* calculate differences since we have a constant color fill */

View File

@ -29,6 +29,7 @@ struct _Evas_Smart_Data
Eina_Inlist *callbacks; Eina_Inlist *callbacks;
Eina_Inlist *contained; /** list of smart member objects */ Eina_Inlist *contained; /** list of smart member objects */
void *render_cache;
/* ptr array + data blob holding all interfaces private data for /* ptr array + data blob holding all interfaces private data for
* this object */ * this object */
void **interface_privates; void **interface_privates;
@ -481,6 +482,32 @@ evas_object_smart_members_get(const Evas_Object *eo_obj)
return members; return members;
} }
void
evas_object_smart_render_cache_clear(Evas_Object *eo_obj)
{
Evas_Smart_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return;
if (!o->render_cache) return;
evas_render_object_render_cache_free(eo_obj, o->render_cache);
o->render_cache = NULL;
}
void *
evas_object_smart_render_cache_get(const Evas_Object *eo_obj)
{
Evas_Smart_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return NULL;
return o->render_cache;
}
void
evas_object_smart_render_cache_set(Evas_Object *eo_obj, void *data)
{
Evas_Smart_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return;
o->render_cache = data;
}
const Eina_Inlist * const Eina_Inlist *
evas_object_smart_members_get_direct(const Evas_Object *eo_obj) evas_object_smart_members_get_direct(const Evas_Object *eo_obj)
{ {
@ -489,6 +516,7 @@ evas_object_smart_members_get_direct(const Evas_Object *eo_obj)
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (!efl_isa(eo_obj, MY_CLASS)) return NULL; if (!efl_isa(eo_obj, MY_CLASS)) return NULL;
Evas_Smart_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); Evas_Smart_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return NULL;
return o->contained; return o->contained;
} }
@ -1273,6 +1301,12 @@ evas_object_smart_cleanup(Evas_Object *eo_obj)
free(info); free(info);
} }
if (o->render_cache)
{
evas_render_object_render_cache_free(eo_obj, o->render_cache);
o->render_cache = NULL;
}
evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0); evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0);
evas_object_smart_data_set(eo_obj, NULL); evas_object_smart_data_set(eo_obj, NULL);
} }

View File

@ -346,11 +346,10 @@ evas_object_vg_render_pre(Evas_Object *eo_obj,
obj->cur->clipper->cur->cache.clip.w, obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h); obj->cur->clipper->cur->cache.clip.h);
} }
obj->layer->evas->engine.func->output_redraws_rect_del evas_render_update_del(obj->layer->evas,
(obj->layer->evas->engine.data.output, x + obj->layer->evas->framespace.x,
x + obj->layer->evas->framespace.x, y + obj->layer->evas->framespace.y,
y + obj->layer->evas->framespace.y, w, h);
w, h);
} }
done: done:
evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v); evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);

View File

@ -71,26 +71,26 @@ rend_dbg(const char *txt)
do \ do \
{ \ { \
eina_array_push(array, obj); \ eina_array_push(array, obj); \
efl_data_ref(obj->object, NULL); \ /*efl_data_ref(obj->object, NULL);*/ \
} while (0) } while (0)
#define OBJS_ARRAY_CLEAN(array) \ #define OBJS_ARRAY_CLEAN(array) \
{ \ { \
Evas_Object_Protected_Data *item; \ /*Evas_Object_Protected_Data *item;*/ \
Eina_Array_Iterator iterator; \ /*Eina_Array_Iterator iterator;*/ \
unsigned int idx; \ /*unsigned int idx;*/ \
EINA_ARRAY_ITER_NEXT(array, idx, item, iterator) \ /*EINA_ARRAY_ITER_NEXT(array, idx, item, iterator)*/ \
efl_data_unref(item->object, item); \ /*efl_data_unref(item->object, item);*/ \
eina_array_clean(array); \ eina_array_clean(array); \
} }
#define OBJS_ARRAY_FLUSH(array) \ #define OBJS_ARRAY_FLUSH(array) \
{ \ { \
Evas_Object_Protected_Data *item; \ /*Evas_Object_Protected_Data *item;*/ \
Eina_Array_Iterator iterator; \ /*Eina_Array_Iterator iterator;*/ \
unsigned int idx; \ /*unsigned int idx;*/ \
EINA_ARRAY_ITER_NEXT(array, idx, item, iterator) \ /*EINA_ARRAY_ITER_NEXT(array, idx, item, iterator)*/ \
efl_data_unref(item->object, item); \ /*efl_data_unref(item->object, item);*/ \
eina_array_flush(array); \ eina_array_flush(array); \
} }
@ -320,9 +320,7 @@ _evas_render_cur_clip_cache_del(Evas_Public_Data *e, Evas_Object_Protected_Data
obj->cur->clipper->cur->cache.clip.w, obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h); obj->cur->clipper->cur->cache.clip.h);
} }
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e, x + e->framespace.x, y + e->framespace.y, w, h);
x + e->framespace.x,
y + e->framespace.y, w, h);
} }
/* sets the redraw flag for all the proxies depending on this obj as a source */ /* sets the redraw flag for all the proxies depending on this obj as a source */
@ -599,17 +597,122 @@ _evas_render_object_map_change_update(Evas_Public_Data *e, Evas_Object *eo_obj E
*redraw_all = 1; *redraw_all = 1;
} }
////////////////////////////////////////////////////////////////////////////
//
// object render update phase 1 code -> figure out updates and built object
// render/active/delete etc. lists/arrays.
//
typedef struct
{
Eina_Array *active_objects;
Eina_Array *render_objects;
Eina_Array *snapshot_objects;
Eina_Inarray *update_del;
} Render_Cache;
void
evas_render_update_del(Evas_Public_Data *e, int x, int y, int w, int h)
{
if (EINA_LIKELY((e->update_del_redirect_array == NULL)))
{
e->engine.func->output_redraws_rect_del(e->engine.data.output,
x, y, w, h);
}
else
{
Eina_Rectangle r;
r.x = x; r.y = y; r.w = w; r.h = h;
eina_inarray_push(e->update_del_redirect_array, &r);
}
}
void
evas_render_object_render_cache_free(Evas_Object *eo_obj EINA_UNUSED,
void *data)
{
Render_Cache *rc;
if (!data) return;
rc = data;
OBJS_ARRAY_CLEAN(rc->active_objects);
OBJS_ARRAY_CLEAN(rc->render_objects);
OBJS_ARRAY_CLEAN(rc->snapshot_objects);
eina_array_free(rc->active_objects);
eina_array_free(rc->render_objects);
eina_array_free(rc->snapshot_objects);
free(rc);
}
static Render_Cache *
_evas_render_phase1_object_render_cache_new(void)
{
Render_Cache *rc;
rc = malloc(sizeof(Render_Cache));
rc->active_objects = eina_array_new(32);
rc->render_objects = eina_array_new(32);
rc->snapshot_objects = eina_array_new(32);
rc->update_del = eina_inarray_new(sizeof(Eina_Rectangle), 16);
return rc;
}
typedef struct typedef struct
{ {
Evas_Public_Data *e; Evas_Public_Data *e;
Eina_Array *active_objects; Eina_Array *active_objects;
Eina_Array *restack_objects;
Eina_Array *delete_objects;
Eina_Array *render_objects; Eina_Array *render_objects;
Eina_Array *snapshot_objects; Eina_Array *snapshot_objects;
Eina_Array *restack_objects;
Eina_Array *delete_objects;
int redraw_all; int redraw_all;
} Phase1_Context; } Phase1_Context;
static void
_evas_render_phase1_object_ctx_render_cache_fill(Phase1_Context *ctx,
Render_Cache *rc)
{
ctx->active_objects = rc->active_objects;
ctx->render_objects = rc->render_objects;
ctx->snapshot_objects = rc->snapshot_objects;
}
static void
_evas_render_phase1_object_ctx_render_cache_append(Phase1_Context *ctx,
Render_Cache *rc)
{
void *obj;
unsigned int i, c;
Eina_Rectangle *r;
#define ARR_APPEND(x) \
if (rc->x != ctx->x) { \
do { \
c = eina_array_count_get(rc->x); \
for (i = 0; i < c; i++) { \
obj = eina_array_data_get(rc->x, i); \
eina_array_push(ctx->x, obj); \
/*efl_data_ref(obj, NULL);*/ \
} \
} while (0); \
}
ARR_APPEND(active_objects);
ARR_APPEND(render_objects);
ARR_APPEND(snapshot_objects);
c = eina_inarray_count(rc->update_del);
for (i = 0; i < c; i++)
{
r = eina_inarray_nth(rc->update_del, i);
evas_render_update_del(ctx->e, r->x, r->y, r->w, r->h);
}
}
static Eina_Bool static Eina_Bool
_evas_render_phase1_object_process(Phase1_Context *p1ctx, _evas_render_phase1_object_process(Phase1_Context *p1ctx,
Evas_Object *eo_obj, Evas_Object *eo_obj,
@ -673,6 +776,7 @@ _evas_render_phase1_object_mapped(Phase1_Context *p1ctx,
_evas_render_prev_cur_clip_cache_add(p1ctx->e, obj); _evas_render_prev_cur_clip_cache_add(p1ctx->e, obj);
obj->render_pre = EINA_TRUE; obj->render_pre = EINA_TRUE;
if (!obj->is_smart) return; if (!obj->is_smart) return;
if (obj_changed) evas_object_smart_render_cache_clear(eo_obj);
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2) EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
{ {
_evas_render_phase1_object_process(p1ctx, obj2->object, obj->restack, _evas_render_phase1_object_process(p1ctx, obj2->object, obj->restack,
@ -708,16 +812,21 @@ _evas_render_phase1_object_mapped_had_restack(Phase1_Context *p1ctx,
evas_object_update_bounding_box(eo_obj, obj, NULL); evas_object_update_bounding_box(eo_obj, obj, NULL);
} }
#define RENDCACHE 1
static Eina_Bool static Eina_Bool
_evas_render_phase1_object_changed_smart(Phase1_Context *p1ctx, _evas_render_phase1_object_changed_smart(Phase1_Context *p1ctx,
Evas_Object *eo_obj, Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj, Evas_Object_Protected_Data *obj,
Eina_Bool mapped_parent, Eina_Bool mapped_parent,
Eina_Bool obj_changed,
Eina_Bool src_changed, Eina_Bool src_changed,
Eina_Bool is_active, Eina_Bool is_active,
int level) int level)
{ {
Evas_Object_Protected_Data *obj2; Evas_Object_Protected_Data *obj2;
Render_Cache *rc = NULL;
void *p_del_redir;
RD(level, " changed + smart - render ok\n"); RD(level, " changed + smart - render ok\n");
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj); OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
@ -725,11 +834,62 @@ _evas_render_phase1_object_changed_smart(Phase1_Context *p1ctx,
if (!is_active && obj->proxy->proxies) src_changed = EINA_TRUE; if (!is_active && obj->proxy->proxies) src_changed = EINA_TRUE;
obj->render_pre = EINA_TRUE; obj->render_pre = EINA_TRUE;
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2) if (obj_changed)
{ {
_evas_render_phase1_object_process(p1ctx, obj2->object, obj->restack, evas_object_smart_render_cache_clear(eo_obj);
mapped_parent, src_changed, EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
level + 1); {
_evas_render_phase1_object_process(p1ctx, obj2->object,
obj->restack,
mapped_parent, src_changed,
level + 1);
}
}
else
{
Phase1_Context *ctx = p1ctx;
Phase1_Context tmpctx;
#ifdef RENDCACHE
if (obj->no_change_render > 3)
{
rc = evas_object_smart_render_cache_get(eo_obj);
if (!rc)
{
rc = _evas_render_phase1_object_render_cache_new();
evas_object_smart_render_cache_set(eo_obj, rc);
ctx = &tmpctx;
*ctx = *p1ctx;
p_del_redir = p1ctx->e->update_del_redirect_array;
p1ctx->e->update_del_redirect_array = rc->update_del;
_evas_render_phase1_object_ctx_render_cache_fill(ctx, rc);
EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(eo_obj), obj2)
{
_evas_render_phase1_object_process(ctx, obj2->object,
obj->restack,
mapped_parent,
src_changed,
level + 1);
}
p1ctx->redraw_all = ctx->redraw_all;
p1ctx->e->update_del_redirect_array = p_del_redir;
}
_evas_render_phase1_object_ctx_render_cache_append(p1ctx, rc);
}
else
#endif
{
EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(eo_obj), obj2)
{
_evas_render_phase1_object_process(ctx, obj2->object,
obj->restack,
mapped_parent,
src_changed,
level + 1);
}
}
} }
return src_changed; return src_changed;
} }
@ -798,18 +958,55 @@ _evas_render_phase1_object_no_changed_smart(Phase1_Context *p1ctx,
int level) int level)
{ {
Evas_Object_Protected_Data *obj2; Evas_Object_Protected_Data *obj2;
Phase1_Context *ctx = p1ctx;
Phase1_Context tmpctx;
Render_Cache *rc = NULL;
void *p_del_redir;
RD(level, " smart + visible/was visible + not clip\n"); RD(level, " smart + visible/was visible + not clip\n");
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj); OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
obj->render_pre = EINA_TRUE; obj->render_pre = EINA_TRUE;
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2) #ifdef RENDCACHE
if (obj->no_change_render > 3)
{ {
_evas_render_phase1_object_process(p1ctx, rc = evas_object_smart_render_cache_get(eo_obj);
obj2->object, if (!rc)
restack, {
mapped_parent, rc = _evas_render_phase1_object_render_cache_new();
src_changed, evas_object_smart_render_cache_set(eo_obj, rc);
level + 1); ctx = &tmpctx;
*ctx = *p1ctx;
p_del_redir = p1ctx->e->update_del_redirect_array;
p1ctx->e->update_del_redirect_array = rc->update_del;
_evas_render_phase1_object_ctx_render_cache_fill(ctx, rc);
EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(eo_obj), obj2)
{
_evas_render_phase1_object_process(ctx,
obj2->object,
restack,
mapped_parent,
src_changed,
level + 1);
}
p1ctx->redraw_all = ctx->redraw_all;
p1ctx->e->update_del_redirect_array = p_del_redir;
}
_evas_render_phase1_object_ctx_render_cache_append(p1ctx, rc);
}
else
#endif
{
EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(eo_obj), obj2)
{
_evas_render_phase1_object_process(ctx,
obj2->object,
restack,
mapped_parent,
src_changed,
level + 1);
}
} }
} }
@ -860,14 +1057,17 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
if (obj->delete_me == 2) OBJ_ARRAY_PUSH(p1ctx->delete_objects, obj); if (obj->delete_me == 2) OBJ_ARRAY_PUSH(p1ctx->delete_objects, obj);
else if (obj->delete_me != 0) obj->delete_me++; else if (obj->delete_me != 0) obj->delete_me++;
/* If the object will be removed, we should not cache anything during this run. */ /* If the object will be removed, we should not cache anything during this run. */
if (obj->delete_me != 0) clean_them = EINA_TRUE; if (obj->delete_me != 0) clean_them = EINA_TRUE;
if (obj->is_static_clip) return clean_them; obj_changed = obj->changed;
if (obj->is_static_clip) goto done;
//Need pre render for the children of mapped object. //Need pre render for the children of mapped object.
//But only when they have changed. //But only when they have changed.
if (mapped_parent && (!obj->changed)) return clean_them; if (mapped_parent && (!obj->changed)) goto done;
/* build active object list */ /* build active object list */
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
@ -906,7 +1106,6 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
map = _evas_render_has_map(obj); map = _evas_render_has_map(obj);
hmap = _evas_render_had_map(obj); hmap = _evas_render_had_map(obj);
can_map = _evas_render_can_map(obj); can_map = _evas_render_can_map(obj);
obj_changed = obj->changed;
map_not_can_map = map & !can_map; map_not_can_map = map & !can_map;
if (EINA_UNLIKELY((restack && !map_not_can_map))) if (EINA_UNLIKELY((restack && !map_not_can_map)))
@ -921,7 +1120,7 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
_evas_render_phase1_object_mapped(p1ctx, eo_obj, obj, src_changed, _evas_render_phase1_object_mapped(p1ctx, eo_obj, obj, src_changed,
hmap, is_active, obj_changed, hmap, is_active, obj_changed,
level); level);
return clean_them; goto done;
} }
else if (EINA_UNLIKELY(hmap && !can_map)) else if (EINA_UNLIKELY(hmap && !can_map))
_evas_render_phase1_object_mapped_had_restack(p1ctx, eo_obj, obj, _evas_render_phase1_object_mapped_had_restack(p1ctx, eo_obj, obj,
@ -934,6 +1133,7 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
src_changed = src_changed =
_evas_render_phase1_object_changed_smart(p1ctx, eo_obj, obj, _evas_render_phase1_object_changed_smart(p1ctx, eo_obj, obj,
mapped_parent, mapped_parent,
obj_changed,
src_changed, is_active, src_changed, is_active,
level); level);
else /* non smart object */ else /* non smart object */
@ -974,9 +1174,26 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
} }
if (!is_active) obj->restack = EINA_FALSE; if (!is_active) obj->restack = EINA_FALSE;
RD(level, "---]\n"); RD(level, "---]\n");
done:
if (obj_changed) obj->no_change_render = 0;
else
{
if (obj->no_change_render < 255) obj->no_change_render++;
}
return clean_them; return clean_them;
} }
//
//
//
////////////////////////////////////////////////////////////////////////////
static Eina_Bool static Eina_Bool
_evas_render_phase1_process(Phase1_Context *p1ctx) _evas_render_phase1_process(Phase1_Context *p1ctx)
{ {
@ -2871,10 +3088,7 @@ evas_render_updates_internal(Evas *eo_e,
/* phase 5. add obscures */ /* phase 5. add obscures */
eina_evlog("+render_phase5", eo_e, 0.0, NULL); eina_evlog("+render_phase5", eo_e, 0.0, NULL);
EINA_LIST_FOREACH(e->obscures, ll, r) EINA_LIST_FOREACH(e->obscures, ll, r)
{ evas_render_update_del(e, r->x, r->y, r->w, r->h);
e->engine.func->output_redraws_rect_del(e->engine.data.output,
r->x, r->y, r->w, r->h);
}
static int prepare = -1; static int prepare = -1;
if (prepare == -1) if (prepare == -1)

View File

@ -211,8 +211,7 @@ _evas_render2_stage_explicit_updates(Evas_Public_Data *e)
} }
// remove obscures from rendering - we keep them around // remove obscures from rendering - we keep them around
EINA_LIST_FOREACH(e->obscures, l, r) EINA_LIST_FOREACH(e->obscures, l, r)
e->engine.func->output_redraws_rect_del(e->engine.data.output, evas_render_update_del(e, r->x, r->y, r->w, r->h);
r->x, r->y, r->w, r->h);
} }
static void static void

View File

@ -886,6 +886,8 @@ struct _Evas_Public_Data
Eina_List *font_path; Eina_List *font_path;
Eina_Inarray *update_del_redirect_array;
int in_smart_calc; int in_smart_calc;
int smart_calc_count; int smart_calc_count;
@ -1134,6 +1136,7 @@ struct _Evas_Object_Protected_Data
unsigned int animator_ref; unsigned int animator_ref;
uint64_t callback_mask; uint64_t callback_mask;
unsigned char no_change_render;
unsigned char delete_me; unsigned char delete_me;
Eina_Bool render_pre : 1; Eina_Bool render_pre : 1;
@ -1593,6 +1596,9 @@ void evas_debug_magic_null(void);
void evas_debug_magic_wrong(DATA32 expected, DATA32 supplied); void evas_debug_magic_wrong(DATA32 expected, DATA32 supplied);
void evas_debug_generic(const char *str); void evas_debug_generic(const char *str);
const char *evas_debug_magic_string_get(DATA32 magic); const char *evas_debug_magic_string_get(DATA32 magic);
void evas_render_update_del(Evas_Public_Data *e, int x, int y, int w, int h);
void evas_render_object_render_cache_free(Evas_Object *eo_obj, void *data);
void evas_object_smart_use(Evas_Smart *s); void evas_object_smart_use(Evas_Smart *s);
void evas_object_smart_unuse(Evas_Smart *s); void evas_object_smart_unuse(Evas_Smart *s);
void evas_smart_cb_descriptions_fix(Evas_Smart_Cb_Description_Array *a) EINA_ARG_NONNULL(1); void evas_smart_cb_descriptions_fix(Evas_Smart_Cb_Description_Array *a) EINA_ARG_NONNULL(1);
@ -1617,6 +1623,10 @@ void evas_object_smart_member_raise(Evas_Object *member);
void evas_object_smart_member_lower(Evas_Object *member); void evas_object_smart_member_lower(Evas_Object *member);
void evas_object_smart_member_stack_above(Evas_Object *member, Evas_Object *other); void evas_object_smart_member_stack_above(Evas_Object *member, Evas_Object *other);
void evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other); void evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other);
void evas_object_smart_render_cache_clear(Evas_Object *eo_obj);
void *evas_object_smart_render_cache_get(const Evas_Object *eo_obj);
void evas_object_smart_render_cache_set(Evas_Object *eo_obj, void *data);
const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj); const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
void _efl_canvas_group_group_members_all_del(Evas_Object *obj); void _efl_canvas_group_group_members_all_del(Evas_Object *obj);
void _evas_object_smart_xy_update(Eo *eo_obj, Evas_Coord *px, Evas_Coord *py, Evas_Coord x, Evas_Coord y); void _evas_object_smart_xy_update(Eo *eo_obj, Evas_Coord *px, Evas_Coord *py, Evas_Coord x, Evas_Coord y);