Evas masking: Fix some remaining issues with animations

Yeah, mixing maps and masks of masks in a genlist leads
to tons of amazing bugs :)

This commit removes x,y from the "mask" field in an object,
as they are duplicates of cur->geometry.{x,y} but were not
properly kept in sync.

This patch fixes a situation of:
- A genlist in a map
- Each item has an icon masked
- Scrolling the genlist
--> The masked items would not render properly before this
    patch.

Remaining known problem:
- Mask a genlist (big mask)
- Each item has an icon masked (small mask)
- Apply a map to the genlist
- Scrolling the genlist
--> The big mask still works but totally screws up the
    small icons with masks.

Note: These changes look scary just before the release
      but I would have to backport them to 1.13.x as they
      definitely are bug fixes. Also, they only concern
      code paths used exclusively by masking.
This commit is contained in:
Jean-Philippe Andre 2015-02-04 12:08:50 +09:00
parent fbacbf7350
commit a688ba45c8
4 changed files with 25 additions and 20 deletions

View File

@ -205,8 +205,6 @@ _evas_object_clip_mask_unset(Evas_Object_Protected_Data *obj)
(obj->layer->evas->engine.data.output, mask->surface);
mask->surface = NULL;
}
mask->x = 0;
mask->y = 0;
mask->w = 0;
mask->h = 0;
EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);

View File

@ -185,7 +185,7 @@ evas_object_free(Evas_Object *eo_obj, int clean_layer)
mask->is_mask = EINA_FALSE;
mask->redraw = EINA_FALSE;
mask->is_alpha = EINA_FALSE;
mask->x = mask->y = mask->w = mask->h = 0;
mask->w = mask->h = 0;
if (mask->surface)
{
obj->layer->evas->engine.func->image_map_surface_free
@ -1264,14 +1264,14 @@ _hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
if (obj->mask->is_mask)
{
if (obj->mask->surface ||
obj->mask->x || obj->mask->y || obj->mask->w || obj->mask->h ||
obj->mask->w || obj->mask->h ||
obj->mask->is_alpha || obj->mask->redraw)
{
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask,
Evas_Object_Mask_Data, mask)
mask->redraw = EINA_FALSE;
mask->is_alpha = EINA_FALSE;
mask->x = mask->y = mask->w = mask->h = 0;
mask->w = mask->h = 0;
if (mask->surface)
{
obj->layer->evas->engine.func->image_map_surface_free

View File

@ -1494,9 +1494,9 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
if (mapped)
{
Eina_Bool restore_image_clip = EINA_FALSE;
Eina_Bool restore_image_clip = EINA_FALSE, old_use_clip = EINA_FALSE;
int oldm_x = 0, oldm_y = 0, ocx = 0, ocy = 0, ocw = 0, och = 0;
void *oldm_sfc = NULL;
int oldm_x = 0, oldm_y = 0;
RDI(level);
RD(" draw child of mapped obj\n");
@ -1524,11 +1524,14 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
e->engine.func->context_clip_image_get
(e->engine.data.output, ctx,
&oldm_sfc, &oldm_x, &oldm_y);
old_use_clip = e->engine.func->context_clip_get
(e->engine.data.output, ctx,
&ocx, &ocy, &ocw, &och);
e->engine.func->context_clip_image_set
(e->engine.data.output, ctx,
mask->mask->surface,
mask->mask->x + off_x,
mask->mask->y + off_y);
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y);
}
}
@ -1579,11 +1582,14 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
e->engine.func->context_clip_image_get
(e->engine.data.output, ctx,
&oldm_sfc, &oldm_x, &oldm_y);
old_use_clip = e->engine.func->context_clip_get
(e->engine.data.output, ctx,
&ocx, &ocy, &ocw, &och);
e->engine.func->context_clip_image_set
(e->engine.data.output, ctx,
mask->mask->surface,
mask->mask->x + off_x,
mask->mask->y + off_y);
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y);
}
}
}
@ -1593,6 +1599,10 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
}
if (restore_image_clip)
{
if (old_use_clip)
e->engine.func->context_clip_set(e->engine.data.output, ctx, ocx, ocy, ocw, och);
else
e->engine.func->context_clip_unset(e->engine.data.output, ctx);
e->engine.func->context_clip_image_set
(e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y);
}
@ -1791,14 +1801,11 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
{
mdata->surface = ENFN->image_map_surface_new(ENDT, w, h, EINA_TRUE);
if (!mdata->surface) goto end;
mdata->is_alpha = EINA_FALSE;
mdata->w = w;
mdata->h = h;
}
mdata->x = x;
mdata->y = y;
mdata->is_alpha = EINA_FALSE;
/* Clear surface with transparency */
ctx = ENFN->context_new(ENDT);
ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
@ -1812,8 +1819,8 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
{
ENFN->context_clip_image_set(ENDT, ctx,
prev_mask->mask->surface,
prev_mask->mask->x - x,
prev_mask->mask->y - y);
prev_mask->cur->geometry.x - x,
prev_mask->cur->geometry.y - y);
}
evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
-x, -y, 1, 0, 0, evas->output.w, evas->output.h,
@ -2348,8 +2355,8 @@ evas_render_updates_internal(Evas *eo_e,
(e->engine.data.output,
e->engine.data.context,
mask->mask->surface,
mask->mask->x + off_x,
mask->mask->y + off_y);
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y);
}
}

View File

@ -895,7 +895,7 @@ struct _Evas_Object_3D_Data
struct _Evas_Object_Mask_Data
{
void *surface;
int x, y, w, h;
int w, h;
Eina_Bool is_mask : 1;
Eina_Bool redraw : 1;
Eina_Bool is_alpha : 1;