evas_render: simplify masking and clipping in general

Use context_dup to inherit from previous contexts in a clean
manner. This removes the need for restoring the previous
clip information.

Plus, this commit removes lines of code so it must be good, right?
This commit is contained in:
Jean-Philippe Andre 2015-09-03 14:06:36 +09:00
parent 3d003b52de
commit f654a3b300
2 changed files with 33 additions and 74 deletions

View File

@ -1250,13 +1250,10 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
Evas_Proxy_Render_Data *proxy_render_data, int level, Evas_Proxy_Render_Data *proxy_render_data, int level,
Eina_Bool use_mapped_ctx, Eina_Bool do_async) Eina_Bool use_mapped_ctx, Eina_Bool do_async)
{ {
void *ctx;
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;
Evas_Object_Protected_Data *obj2; Evas_Object_Protected_Data *obj2;
Eina_Bool clean_them = EINA_FALSE; Eina_Bool clean_them = EINA_FALSE;
Eina_Bool proxy_src_clip = EINA_TRUE; Eina_Bool proxy_src_clip = EINA_TRUE;
void *oldm_sfc = NULL; void *ctx;
//Don't Render if the source is invisible. //Don't Render if the source is invisible.
if (!proxy_render_data) if (!proxy_render_data)
@ -1493,7 +1490,11 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
} }
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write); EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
} }
ENFN->context_clip_unset(ENDT, context);
/* duplicate context and reset clip */
ctx = ENFN->context_dup(ENDT, context);
ENFN->context_clip_unset(ENDT, ctx);
if (obj->map->surface) if (obj->map->surface)
{ {
if (obj->cur->clipper) if (obj->cur->clipper)
@ -1508,7 +1509,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
} }
EINA_COW_STATE_WRITE_END(obj, state_write, cur); EINA_COW_STATE_WRITE_END(obj, state_write, cur);
} }
_evas_render_mapped_context_clip_set(evas, eo_obj, obj, context, _evas_render_mapped_context_clip_set(evas, eo_obj, obj, ctx,
proxy_render_data, off_x, proxy_render_data, off_x,
off_y); off_y);
@ -1525,45 +1526,27 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
if (mask->mask->surface) if (mask->mask->surface)
{ {
restore_image_clip = EINA_TRUE; ENFN->context_clip_image_set(ENDT, ctx, mask->mask->surface,
ENFN->context_clip_image_get mask->cur->geometry.x + off_x,
(ENDT, context, mask->cur->geometry.y + off_y,
&oldm_sfc, &oldm_x, &oldm_y); evas, do_async);
old_use_clip = ENFN->context_clip_get
(ENDT, context,
&ocx, &ocy, &ocw, &och);
ENFN->context_clip_image_set
(ENDT, context,
mask->mask->surface,
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y,
evas, do_async);
} }
} }
} }
} }
// if (surface == ENFN) //if (surface == ENFN)
ENFN->context_clip_clip(ENDT, context, ecx, ecy, ecw, ech); ENFN->context_clip_clip(ENDT, ctx, ecx, ecy, ecw, ech);
if (obj->cur->cache.clip.visible || !proxy_src_clip) if (obj->cur->cache.clip.visible || !proxy_src_clip)
{ {
ENFN->context_multiplier_unset(ENDT, context); ENFN->context_multiplier_unset(ENDT, ctx);
ENFN->context_render_op_set(ENDT, context, obj->cur->render_op); ENFN->context_render_op_set(ENDT, ctx, obj->cur->render_op);
evas_draw_image_map_async_check evas_draw_image_map_async_check
(obj, ENDT, ctx, surface, (obj, ENDT, ctx, surface,
obj->map->surface, obj->map->spans, obj->map->surface, obj->map->spans,
obj->map->cur.map->smooth, 0, do_async); obj->map->cur.map->smooth, 0, do_async);
} }
if (restore_image_clip) ENFN->context_free(ENDT, ctx);
{
if (old_use_clip)
ENFN->context_clip_set(ENDT, context, ocx, ocy, ocw, och);
else
ENFN->context_clip_unset(ENDT, context);
ENFN->context_clip_image_set(ENDT, context, oldm_sfc, oldm_x, oldm_y, evas, do_async);
/* unref image since clip_image_get refs it */
if (oldm_sfc) ENFN->image_free(ENDT, oldm_sfc);
}
// FIXME: needs to cache these maps and // FIXME: needs to cache these maps and
// keep them only rendering updates // keep them only rendering updates
@ -1586,7 +1569,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
RD(level, " draw child of mapped obj\n"); RD(level, " draw child of mapped obj\n");
if (use_mapped_ctx) if (use_mapped_ctx)
ctx = context; ctx = ENFN->context_dup(ENDT, context);
else else
ctx = ENFN->context_new(ENDT); ctx = ENFN->context_new(ENDT);
@ -1609,19 +1592,12 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
if (mask->mask->surface) if (mask->mask->surface)
{ {
restore_image_clip = EINA_TRUE; use_mapped_ctx = EINA_TRUE;
ENFN->context_clip_image_get ENFN->context_clip_image_set(ENDT, ctx,
(ENDT, ctx, mask->mask->surface,
&oldm_sfc, &oldm_x, &oldm_y); mask->cur->geometry.x + off_x,
old_use_clip = ENFN->context_clip_get mask->cur->geometry.y + off_y,
(ENDT, ctx, evas, do_async);
&ocx, &ocy, &ocw, &och);
ENFN->context_clip_image_set
(ENDT, ctx,
mask->mask->surface,
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y,
evas, do_async);
} }
} }
@ -1634,7 +1610,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
ecx, ecy, ecw, ech, ecx, ecy, ecw, ech,
proxy_render_data, proxy_render_data,
level + 1, level + 1,
restore_image_clip | use_mapped_ctx, use_mapped_ctx,
do_async); do_async);
/* We aren't sure this object will be rendered by /* We aren't sure this object will be rendered by
normal(not proxy) drawing after, we reset this normal(not proxy) drawing after, we reset this
@ -1669,19 +1645,11 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
if (mask->mask->surface) if (mask->mask->surface)
{ {
restore_image_clip = EINA_TRUE; ENFN->context_clip_image_set(ENDT, ctx,
ENFN->context_clip_image_get mask->mask->surface,
(ENDT, ctx, mask->cur->geometry.x + off_x,
&oldm_sfc, &oldm_x, &oldm_y); mask->cur->geometry.y + off_y,
old_use_clip = ENFN->context_clip_get evas, do_async);
(ENDT, ctx,
&ocx, &ocy, &ocw, &och);
ENFN->context_clip_image_set
(ENDT, ctx,
mask->mask->surface,
mask->cur->geometry.x + off_x,
mask->cur->geometry.y + off_y,
evas, do_async);
} }
} }
} }
@ -1689,21 +1657,12 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
obj->func->render(eo_obj, obj, obj->private_data, obj->func->render(eo_obj, obj, obj->private_data,
ENDT, ctx, surface, off_x, off_y, EINA_FALSE); ENDT, ctx, surface, off_x, off_y, EINA_FALSE);
} }
if (restore_image_clip)
{ ENFN->context_free(ENDT, ctx);
if (old_use_clip)
ENFN->context_clip_set(ENDT, ctx, ocx, ocy, ocw, och);
else
ENFN->context_clip_unset(ENDT, ctx);
ENFN->context_clip_image_set(ENDT, ctx, oldm_sfc, oldm_x, oldm_y, evas, do_async);
/* unref image since clip_image_get refs it */
if (oldm_sfc) ENFN->image_free(ENDT, oldm_sfc);
}
if (!use_mapped_ctx)
ENFN->context_free(ENDT, ctx);
} }
else else
{ {
/* in this case we keep the parent context */
if (obj->cur->clipper) if (obj->cur->clipper)
{ {
Evas_Object_Protected_Data *clipper = obj->cur->clipper; Evas_Object_Protected_Data *clipper = obj->cur->clipper;

View File

@ -739,7 +739,7 @@ struct _RGBA_Draw_Context
struct RGBA_Draw_Context_clip { struct RGBA_Draw_Context_clip {
int x, y, w, h; int x, y, w, h;
Evas_Public_Data *evas; // for async unref Evas_Public_Data *evas; // for async unref
void *mask; void *mask; // RGBA_Image (SW) or Evas_GL_Image (GL)
int mask_x, mask_y; int mask_x, mask_y;
Eina_Bool use : 1; Eina_Bool use : 1;
Eina_Bool async : 1; Eina_Bool async : 1;