forked from enlightenment/efl
evas render and clip calc - move evas_object_clip_recalc out of inline
evas_object_clip_recalc is big. it's fat. it shouldnt be inline. so make it a real function. being inline just hurts performance by making our code bigger, hurting l1 instruction prefetch and cache performance. this function isn't small. it's huge and should not be inline basically because of that reason. also throw in some likely/unlikely hints etc. @optimize
This commit is contained in:
parent
e3489d5f89
commit
d7c6fca6c0
|
@ -134,6 +134,151 @@ typedef struct _Map_Same
|
|||
Eina_Bool b1;
|
||||
} Map_Same;
|
||||
|
||||
void
|
||||
evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
|
||||
{
|
||||
Evas_Object_Protected_Data *clipper = NULL;
|
||||
int cx, cy, cw, ch, cr, cg, cb, ca;
|
||||
int nx, ny, nw, nh, nr, ng, nb, na;
|
||||
Eina_Bool cvis, nvis;
|
||||
Evas_Object *eo_obj;
|
||||
|
||||
EVAS_OBJECT_DATA_ALIVE_CHECK(obj);
|
||||
|
||||
clipper = obj->cur->clipper;
|
||||
|
||||
if (EINA_LIKELY(((!obj->cur->cache.clip.dirty) &&
|
||||
!(!clipper || clipper->cur->cache.clip.dirty)))) return;
|
||||
|
||||
if (EINA_UNLIKELY(obj->layer->evas->is_frozen)) return;
|
||||
|
||||
eo_obj = obj->object;
|
||||
|
||||
evas_object_coords_recalc(eo_obj, obj);
|
||||
|
||||
if (EINA_UNLIKELY((obj->map->cur.map) && (obj->map->cur.usemap)))
|
||||
{
|
||||
cx = obj->map->cur.map->normal_geometry.x;
|
||||
cy = obj->map->cur.map->normal_geometry.y;
|
||||
cw = obj->map->cur.map->normal_geometry.w;
|
||||
ch = obj->map->cur.map->normal_geometry.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj->is_smart)
|
||||
{
|
||||
Evas_Coord_Rectangle bounding_box;
|
||||
|
||||
evas_object_smart_bounding_box_update(eo_obj, obj);
|
||||
evas_object_smart_bounding_box_get(eo_obj, &bounding_box, NULL);
|
||||
cx = bounding_box.x;
|
||||
cy = bounding_box.y;
|
||||
cw = bounding_box.w;
|
||||
ch = bounding_box.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
cx = obj->cur->geometry.x;
|
||||
cy = obj->cur->geometry.y;
|
||||
cw = obj->cur->geometry.w;
|
||||
ch = obj->cur->geometry.h;
|
||||
}
|
||||
}
|
||||
|
||||
if (EINA_UNLIKELY((obj->cur->color.a == 0) &&
|
||||
(obj->cur->render_op == EVAS_RENDER_BLEND)))
|
||||
cvis = EINA_FALSE;
|
||||
else cvis = obj->cur->visible;
|
||||
|
||||
cr = obj->cur->color.r; cg = obj->cur->color.g;
|
||||
cb = obj->cur->color.b; ca = obj->cur->color.a;
|
||||
|
||||
if (EVAS_OBJECT_DATA_VALID(clipper))
|
||||
{
|
||||
// this causes problems... hmmm ?????
|
||||
evas_object_clip_recalc(clipper);
|
||||
|
||||
// I don't know why this test was here in the first place. As I have
|
||||
// no issue showing up due to this, I keep it and move color out of it.
|
||||
// breaks cliping of mapped images!!!
|
||||
if (clipper->map->cur.map_parent == obj->map->cur.map_parent)
|
||||
{
|
||||
nx = clipper->cur->cache.clip.x;
|
||||
ny = clipper->cur->cache.clip.y;
|
||||
nw = clipper->cur->cache.clip.w;
|
||||
nh = clipper->cur->cache.clip.h;
|
||||
RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
|
||||
}
|
||||
|
||||
obj->clip.prev_mask = NULL;
|
||||
if (EINA_UNLIKELY(clipper->mask->is_mask))
|
||||
{
|
||||
// Set complex masks the object being clipped (parent)
|
||||
obj->clip.mask = clipper;
|
||||
|
||||
// Forward any mask from the parents
|
||||
if (EINA_LIKELY(obj->smart.parent != NULL))
|
||||
{
|
||||
Evas_Object_Protected_Data *parent =
|
||||
efl_data_scope_get(obj->smart.parent, EFL_CANVAS_OBJECT_CLASS);
|
||||
if (parent->clip.mask)
|
||||
{
|
||||
if (parent->clip.mask != obj->clip.mask)
|
||||
obj->clip.prev_mask = parent->clip.mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (EINA_UNLIKELY(clipper->clip.mask != NULL))
|
||||
{
|
||||
// Pass complex masks to children
|
||||
obj->clip.mask = clipper->clip.mask;
|
||||
}
|
||||
else obj->clip.mask = NULL;
|
||||
|
||||
nvis = clipper->cur->cache.clip.visible;
|
||||
nr = clipper->cur->cache.clip.r;
|
||||
ng = clipper->cur->cache.clip.g;
|
||||
nb = clipper->cur->cache.clip.b;
|
||||
na = clipper->cur->cache.clip.a;
|
||||
cvis = (cvis & nvis);
|
||||
cr = (cr * (nr + 1)) >> 8;
|
||||
cg = (cg * (ng + 1)) >> 8;
|
||||
cb = (cb * (nb + 1)) >> 8;
|
||||
ca = (ca * (na + 1)) >> 8;
|
||||
}
|
||||
|
||||
if (((ca == 0) && (obj->cur->render_op == EVAS_RENDER_BLEND)) ||
|
||||
(cw <= 0) || (ch <= 0))
|
||||
cvis = EINA_FALSE;
|
||||
|
||||
if ((obj->cur->cache.clip.dirty == EINA_FALSE) &&
|
||||
(obj->cur->cache.clip.visible == cvis) &&
|
||||
(obj->cur->cache.clip.x == cx) &&
|
||||
(obj->cur->cache.clip.y == cy) &&
|
||||
(obj->cur->cache.clip.w == cw) &&
|
||||
(obj->cur->cache.clip.h == ch) &&
|
||||
(obj->cur->cache.clip.r == cr) &&
|
||||
(obj->cur->cache.clip.g == cg) &&
|
||||
(obj->cur->cache.clip.b == cb) &&
|
||||
(obj->cur->cache.clip.a == ca))
|
||||
return;
|
||||
|
||||
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
||||
{
|
||||
state_write->cache.clip.x = cx;
|
||||
state_write->cache.clip.y = cy;
|
||||
state_write->cache.clip.w = cw;
|
||||
state_write->cache.clip.h = ch;
|
||||
state_write->cache.clip.visible = cvis;
|
||||
state_write->cache.clip.r = cr;
|
||||
state_write->cache.clip.g = cg;
|
||||
state_write->cache.clip.b = cb;
|
||||
state_write->cache.clip.a = ca;
|
||||
state_write->cache.clip.dirty = EINA_FALSE;
|
||||
}
|
||||
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_map_same(const void *map1, const void *map2)
|
||||
{
|
||||
|
|
|
@ -401,6 +401,7 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
|
|||
Evas_Active_Entry *ent = eina_inarray_nth(active_objects, i);
|
||||
Evas_Object_Protected_Data *obj = ent->obj;
|
||||
|
||||
EINA_PREFETCH(&(obj->cur->clipper));
|
||||
if (obj->changed) evas_object_clip_recalc(obj);
|
||||
|
||||
if (obj->proxy->proxies || obj->proxy->proxy_textures)
|
||||
|
@ -419,7 +420,7 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
|
|||
for (i = 0; i < render_objects->count; i++)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj =
|
||||
eina_array_data_get(render_objects, i);
|
||||
eina_array_data_get(render_objects, i);
|
||||
eo_obj = obj->object;
|
||||
|
||||
RD(0, " OBJ [%p", obj);
|
||||
|
@ -1024,6 +1025,8 @@ _evas_render_phase1_object_process(Phase1_Context *p1ctx,
|
|||
Eina_Bool map, hmap, can_map, map_not_can_map, obj_changed, is_active;
|
||||
Evas_Object *eo_obj = obj->object;
|
||||
|
||||
EINA_PREFETCH(&(obj->cur->clipper));
|
||||
|
||||
obj->rect_del = EINA_FALSE;
|
||||
obj->render_pre = EINA_FALSE;
|
||||
|
||||
|
@ -1213,9 +1216,13 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *eo_e EINA_
|
|||
|
||||
if (!obj->layer) goto clean_stuff;
|
||||
|
||||
//If the children are in active objects, They should be cleaned up.
|
||||
if (obj->changed_map && _evas_render_has_map(obj) && !_evas_render_can_map(obj))
|
||||
goto clean_stuff;
|
||||
EINA_PREFETCH(&(obj->cur->clipper));
|
||||
EINA_PREFETCH(&(obj->cur->cache.clip));
|
||||
//If the children are in active objects, They should be cleaned up.
|
||||
if (EINA_UNLIKELY((obj->changed_map) &&
|
||||
(_evas_render_has_map(obj)) &&
|
||||
(!_evas_render_can_map(obj))))
|
||||
goto clean_stuff;
|
||||
|
||||
evas_object_clip_recalc(obj);
|
||||
is_active = evas_object_is_active(eo_obj, obj);
|
||||
|
@ -1680,7 +1687,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
|
|||
evas_object_clip_recalc(obj);
|
||||
|
||||
/* leave early if clipper is not visible */
|
||||
if (obj->cur->clipper && !obj->cur->clipper->cur->visible)
|
||||
if ((obj->cur->clipper) && (!obj->cur->clipper->cur->visible))
|
||||
return clean_them;
|
||||
|
||||
eina_evlog("+render_object", eo_obj, 0.0, NULL);
|
||||
|
|
|
@ -267,148 +267,6 @@ evas_object_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
|||
//// obj->cur->cache.geometry.validity = obj->layer->evas->output_validity;
|
||||
}
|
||||
|
||||
static inline void
|
||||
evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
|
||||
{
|
||||
Evas_Object_Protected_Data *clipper = NULL;
|
||||
int cx, cy, cw, ch, cr, cg, cb, ca;
|
||||
int nx, ny, nw, nh, nr, ng, nb, na;
|
||||
Eina_Bool cvis, nvis;
|
||||
Evas_Object *eo_obj;
|
||||
|
||||
EVAS_OBJECT_DATA_ALIVE_CHECK(obj);
|
||||
|
||||
eo_obj = obj->object;
|
||||
clipper = obj->cur->clipper;
|
||||
|
||||
if ((!obj->cur->cache.clip.dirty) &&
|
||||
!(!clipper || clipper->cur->cache.clip.dirty)) return;
|
||||
|
||||
if (obj->layer->evas->is_frozen) return;
|
||||
|
||||
evas_object_coords_recalc(eo_obj, obj);
|
||||
|
||||
if ((obj->map->cur.map) && (obj->map->cur.usemap))
|
||||
{
|
||||
cx = obj->map->cur.map->normal_geometry.x;
|
||||
cy = obj->map->cur.map->normal_geometry.y;
|
||||
cw = obj->map->cur.map->normal_geometry.w;
|
||||
ch = obj->map->cur.map->normal_geometry.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj->is_smart)
|
||||
{
|
||||
Evas_Coord_Rectangle bounding_box = { 0, 0, 0, 0 };
|
||||
|
||||
evas_object_smart_bounding_box_update(eo_obj, obj);
|
||||
evas_object_smart_bounding_box_get(eo_obj, &bounding_box, NULL);
|
||||
cx = bounding_box.x;
|
||||
cy = bounding_box.y;
|
||||
cw = bounding_box.w;
|
||||
ch = bounding_box.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
cx = obj->cur->geometry.x;
|
||||
cy = obj->cur->geometry.y;
|
||||
cw = obj->cur->geometry.w;
|
||||
ch = obj->cur->geometry.h;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->cur->color.a == 0 && obj->cur->render_op == EVAS_RENDER_BLEND)
|
||||
cvis = EINA_FALSE;
|
||||
else cvis = obj->cur->visible;
|
||||
|
||||
cr = obj->cur->color.r; cg = obj->cur->color.g;
|
||||
cb = obj->cur->color.b; ca = obj->cur->color.a;
|
||||
|
||||
if (EVAS_OBJECT_DATA_VALID(clipper))
|
||||
{
|
||||
// this causes problems... hmmm ?????
|
||||
evas_object_clip_recalc(clipper);
|
||||
|
||||
// I don't know why this test was here in the first place. As I have
|
||||
// no issue showing up due to this, I keep it and move color out of it.
|
||||
// breaks cliping of mapped images!!!
|
||||
if (clipper->map->cur.map_parent == obj->map->cur.map_parent)
|
||||
{
|
||||
nx = clipper->cur->cache.clip.x;
|
||||
ny = clipper->cur->cache.clip.y;
|
||||
nw = clipper->cur->cache.clip.w;
|
||||
nh = clipper->cur->cache.clip.h;
|
||||
RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
|
||||
}
|
||||
|
||||
obj->clip.prev_mask = NULL;
|
||||
if (clipper->mask->is_mask)
|
||||
{
|
||||
// Set complex masks the object being clipped (parent)
|
||||
obj->clip.mask = clipper;
|
||||
|
||||
// Forward any mask from the parents
|
||||
if (EINA_LIKELY(obj->smart.parent != NULL))
|
||||
{
|
||||
Evas_Object_Protected_Data *parent =
|
||||
efl_data_scope_get(obj->smart.parent, EFL_CANVAS_OBJECT_CLASS);
|
||||
if (parent->clip.mask)
|
||||
{
|
||||
if (parent->clip.mask != obj->clip.mask)
|
||||
obj->clip.prev_mask = parent->clip.mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (clipper->clip.mask)
|
||||
{
|
||||
// Pass complex masks to children
|
||||
obj->clip.mask = clipper->clip.mask;
|
||||
}
|
||||
else obj->clip.mask = NULL;
|
||||
|
||||
nvis = clipper->cur->cache.clip.visible;
|
||||
nr = clipper->cur->cache.clip.r;
|
||||
ng = clipper->cur->cache.clip.g;
|
||||
nb = clipper->cur->cache.clip.b;
|
||||
na = clipper->cur->cache.clip.a;
|
||||
cvis = (cvis & nvis);
|
||||
cr = (cr * (nr + 1)) >> 8;
|
||||
cg = (cg * (ng + 1)) >> 8;
|
||||
cb = (cb * (nb + 1)) >> 8;
|
||||
ca = (ca * (na + 1)) >> 8;
|
||||
}
|
||||
|
||||
if ((ca == 0 && obj->cur->render_op == EVAS_RENDER_BLEND) ||
|
||||
(cw <= 0) || (ch <= 0)) cvis = EINA_FALSE;
|
||||
|
||||
if (obj->cur->cache.clip.x == cx &&
|
||||
obj->cur->cache.clip.y == cy &&
|
||||
obj->cur->cache.clip.w == cw &&
|
||||
obj->cur->cache.clip.h == ch &&
|
||||
obj->cur->cache.clip.visible == cvis &&
|
||||
obj->cur->cache.clip.r == cr &&
|
||||
obj->cur->cache.clip.g == cg &&
|
||||
obj->cur->cache.clip.b == cb &&
|
||||
obj->cur->cache.clip.a == ca &&
|
||||
obj->cur->cache.clip.dirty == EINA_FALSE)
|
||||
return ;
|
||||
|
||||
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
||||
{
|
||||
state_write->cache.clip.x = cx;
|
||||
state_write->cache.clip.y = cy;
|
||||
state_write->cache.clip.w = cw;
|
||||
state_write->cache.clip.h = ch;
|
||||
state_write->cache.clip.visible = cvis;
|
||||
state_write->cache.clip.r = cr;
|
||||
state_write->cache.clip.g = cg;
|
||||
state_write->cache.clip.b = cb;
|
||||
state_write->cache.clip.a = ca;
|
||||
state_write->cache.clip.dirty = EINA_FALSE;
|
||||
}
|
||||
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
||||
}
|
||||
|
||||
static inline void
|
||||
evas_object_async_block(Evas_Object_Protected_Data *obj)
|
||||
{
|
||||
|
|
|
@ -1562,6 +1562,7 @@ extern "C" {
|
|||
|
||||
Evas_Object *evas_object_new(Evas *e);
|
||||
void evas_object_change_reset(Evas_Object *obj);
|
||||
void evas_object_clip_recalc(Evas_Object_Protected_Data *obj);
|
||||
void evas_object_cur_prev(Evas_Object *obj);
|
||||
void evas_object_free(Evas_Object *obj, int clean_layer);
|
||||
void evas_object_update_bounding_box(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Smart_Data *s);
|
||||
|
|
Loading…
Reference in New Issue