summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-11-27 12:02:12 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-11-27 12:10:12 +0900
commitd7c6fca6c00a0bfb05923b4da276ff290ca43f72 (patch)
tree2cbb89ff83013dfd91cf9d74342cf4fd269bec4d
parente3489d5f8916d63371e8a67252ddde7d3154f5ff (diff)
downloadefl-d7c6fca6c00a0bfb05923b4da276ff290ca43f72.tar.gz
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
-rw-r--r--src/lib/evas/canvas/evas_object_main.c145
-rw-r--r--src/lib/evas/canvas/evas_render.c17
-rw-r--r--src/lib/evas/include/evas_inline.x142
-rw-r--r--src/lib/evas/include/evas_private.h1
4 files changed, 158 insertions, 147 deletions
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index 8466babb9a..18df96d026 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -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)
{
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index 0b5d10b79d..c40a8648e3 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -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);
diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x
index 6939870053..d56d365374 100644
--- a/src/lib/evas/include/evas_inline.x
+++ b/src/lib/evas/include/evas_inline.x
@@ -268,148 +268,6 @@ evas_object_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
}
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)
{
if (EVAS_OBJECT_DATA_VALID(obj))
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 5f355cc4be..9d5b2e045d 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -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);