evas image update calculation - account for clipped color changes

if clipped color changed and not object color on image objects, then
the updates could be missed. this also fixes some corner cases where
opaqueness should not count for update deletion too. this bug seems to
have been here a while unnoticed.

fixes T4246

@fix
This commit is contained in:
Carsten Haitzler 2016-08-11 23:18:15 +09:00
parent d126107782
commit aaf29b4dc4
1 changed files with 84 additions and 44 deletions

View File

@ -2188,7 +2188,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
if (is_v != was_v) if (is_v != was_v)
{ {
evas_object_render_pre_visible_change(&e->clip_changes, eo_obj, is_v, was_v); evas_object_render_pre_visible_change(&e->clip_changes, eo_obj, is_v, was_v);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (obj->changed_map || obj->changed_src_visible) if (obj->changed_map || obj->changed_src_visible)
{ {
@ -2204,28 +2204,32 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
if (obj->restack) if (obj->restack)
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
/* if it changed color */ /* if it changed color */
if ((obj->cur->color.r != obj->prev->color.r) || if ((obj->cur->color.r != obj->prev->color.r) ||
(obj->cur->color.g != obj->prev->color.g) || (obj->cur->color.g != obj->prev->color.g) ||
(obj->cur->color.b != obj->prev->color.b) || (obj->cur->color.b != obj->prev->color.b) ||
(obj->cur->color.a != obj->prev->color.a)) (obj->cur->color.a != obj->prev->color.a) ||
(obj->cur->cache.clip.r != obj->prev->cache.clip.r) ||
(obj->cur->cache.clip.g != obj->prev->cache.clip.g) ||
(obj->cur->cache.clip.b != obj->prev->cache.clip.b) ||
(obj->cur->cache.clip.a != obj->prev->cache.clip.a))
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
/* if it changed render op */ /* if it changed render op */
if (obj->cur->render_op != obj->prev->render_op) if (obj->cur->render_op != obj->prev->render_op)
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
/* if it changed anti_alias */ /* if it changed anti_alias */
if (obj->cur->anti_alias != obj->prev->anti_alias) if (obj->cur->anti_alias != obj->prev->anti_alias)
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (o->changed) if (o->changed)
{ {
@ -2236,7 +2240,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
) )
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if ((o->cur->image.w != o->prev->image.w) || if ((o->cur->image.w != o->prev->image.w) ||
(o->cur->image.h != o->prev->image.h) || (o->cur->image.h != o->prev->image.h) ||
@ -2245,7 +2249,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
(o->cur->smooth_scale != o->prev->smooth_scale)) (o->cur->smooth_scale != o->prev->smooth_scale))
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if ((o->cur->border.l != o->prev->border.l) || if ((o->cur->border.l != o->prev->border.l) ||
(o->cur->border.r != o->prev->border.r) || (o->cur->border.r != o->prev->border.r) ||
@ -2255,7 +2259,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
(o->cur->border.scale != o->prev->border.scale)) (o->cur->border.scale != o->prev->border.scale))
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (o->dirty_pixels && ENFN->image_native_get) if (o->dirty_pixels && ENFN->image_native_get)
{ {
@ -2267,18 +2271,18 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
if (ns && (ns->type == EVAS_NATIVE_SURFACE_EVASGL)) if (ns && (ns->type == EVAS_NATIVE_SURFACE_EVASGL))
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
} }
if (o->cur->frame != o->prev->frame) if (o->cur->frame != o->prev->frame)
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (o->cur->orient != o->prev->orient) if (o->cur->orient != o->prev->orient)
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
} }
@ -2289,7 +2293,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
) )
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (o->changed) if (o->changed)
{ {
@ -2299,7 +2303,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
(o->cur->fill.h != o->prev->fill.h)) (o->cur->fill.h != o->prev->fill.h))
{ {
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done; goto done;
} }
if (o->pixels->pixel_updates) if (o->pixels->pixel_updates)
{ {
@ -2313,7 +2317,9 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
{ {
Eina_Rectangle *rr; Eina_Rectangle *rr;
if (evas_object_is_opaque(eo_obj, obj)) if ((!o->cur->has_alpha) &&
(evas_object_is_opaque(eo_obj, obj)) &&
(obj->cur->color.a == 255))
{ {
Evas_Coord x, y, w, h; Evas_Coord x, y, w, h;
@ -2323,16 +2329,22 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
h = obj->cur->cache.clip.h; h = obj->cur->cache.clip.h;
if (obj->cur->clipper) if (obj->cur->clipper)
{ {
RECTS_CLIP_TO_RECT(x, y, w, h, if (obj->cur->clipper->cur->cache.clip.a != 255)
obj->cur->clipper->cur->cache.clip.x, w = 0;
obj->cur->clipper->cur->cache.clip.y, else
obj->cur->clipper->cur->cache.clip.w, {
obj->cur->clipper->cur->cache.clip.h); RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur->clipper->cur->cache.clip.x,
obj->cur->clipper->cur->cache.clip.y,
obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h);
}
} }
e->engine.func->output_redraws_rect_del(e->engine.data.output, if ((w > 0) && (h > 0))
x + e->framespace.x, e->engine.func->output_redraws_rect_del(e->engine.data.output,
y + e->framespace.y, x + e->framespace.x,
w, h); y + e->framespace.y,
w, h);
} }
EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write)
{ {
@ -2397,7 +2409,9 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
{ {
Eina_Rectangle *rr; Eina_Rectangle *rr;
if (evas_object_is_opaque(eo_obj, obj)) if ((!o->cur->has_alpha) &&
(evas_object_is_opaque(eo_obj, obj)) &&
(obj->cur->color.a == 255))
{ {
Evas_Coord x, y, w, h; Evas_Coord x, y, w, h;
@ -2407,18 +2421,25 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
h = obj->cur->cache.clip.h; h = obj->cur->cache.clip.h;
if (obj->cur->clipper) if (obj->cur->clipper)
{ {
RECTS_CLIP_TO_RECT(x, y, w, h, if (obj->cur->clipper->cur->cache.clip.a != 255)
obj->cur->clipper->cur->cache.clip.x, w = 0;
obj->cur->clipper->cur->cache.clip.y, else
obj->cur->clipper->cur->cache.clip.w, {
obj->cur->clipper->cur->cache.clip.h); RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur->clipper->cur->cache.clip.x,
obj->cur->clipper->cur->cache.clip.y,
obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h);
}
} }
e->engine.func->output_redraws_rect_del(e->engine.data.output, if ((w > 0) && (h > 0))
x + e->framespace.x, e->engine.func->output_redraws_rect_del(e->engine.data.output,
y + e->framespace.y, x + e->framespace.x,
w, h); y + e->framespace.y,
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))
{ {
Evas_Coord x, y, w, h; Evas_Coord x, y, w, h;
@ -2428,16 +2449,22 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
h = obj->cur->geometry.h - o->cur->border.t - o->cur->border.b; h = obj->cur->geometry.h - o->cur->border.t - o->cur->border.b;
if (obj->cur->clipper) if (obj->cur->clipper)
{ {
RECTS_CLIP_TO_RECT(x, y, w, h, if (obj->cur->clipper->cur->cache.clip.a != 255)
obj->cur->clipper->cur->cache.clip.x, w = 0;
obj->cur->clipper->cur->cache.clip.y, else
obj->cur->clipper->cur->cache.clip.w, {
obj->cur->clipper->cur->cache.clip.h); RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur->clipper->cur->cache.clip.x,
obj->cur->clipper->cur->cache.clip.y,
obj->cur->clipper->cur->cache.clip.w,
obj->cur->clipper->cur->cache.clip.h);
}
} }
e->engine.func->output_redraws_rect_del(e->engine.data.output, if ((w > 0) && (h > 0))
x + e->framespace.x, e->engine.func->output_redraws_rect_del(e->engine.data.output,
y + e->framespace.y, x + e->framespace.x,
w, h); y + e->framespace.y,
w, h);
} }
EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write)
{ {
@ -2506,6 +2533,19 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
} }
done: done:
evas_object_render_pre_effect_updates(&e->clip_changes, eo_obj, is_v, was_v); evas_object_render_pre_effect_updates(&e->clip_changes, eo_obj, is_v, was_v);
if (o->pixels->pixel_updates)
{
Eina_Rectangle *rr;
EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write)
{
EINA_LIST_FREE(pixi_write->pixel_updates, rr)
{
eina_rectangle_free(rr);
}
}
EINA_COW_PIXEL_WRITE_END(o, pixi_write);
}
} }
static void static void