diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 3991f93585..f7eba26042 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -1537,6 +1537,9 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, ctx->target.b == 255 && ctx->target.a == 255) ctx->target.color_use = EINA_FALSE; + ENFN->context_clip_image_get + (ENDT, draw_context, &ctx->target.mask, &ctx->target.mask_x, &ctx->target.mask_y); + if (ctx->gl_engine) { // Since GL has sync rendering, draw_context is safe to keep around @@ -1621,6 +1624,12 @@ _filter_target_render(Evas_Filter_Context *ctx) ENFN->context_multiplier_unset(ENDT, drawctx); } + if (ctx->target.mask) + ENFN->context_clip_image_set(ENDT, drawctx, + ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y); + else + ENFN->context_clip_image_unset(ENDT, drawctx); + ENFN->image_draw(ENDT, drawctx, surface, image, 0, 0, src->w, src->h, ctx->target.x, ctx->target.y, src->w, src->h, diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index 6e0a799162..c613be7980 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -101,6 +101,8 @@ struct _Evas_Filter_Context int x, y; int cx, cy, cw, ch; // clip int r, g, b, a; // clip color + void *mask; // mask + int mask_x, mask_y; // mask offset Eina_Bool clip_use : 1; Eina_Bool color_use : 1; } target; diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index af4a325a72..bd61ee452d 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1155,6 +1155,9 @@ struct _Evas_Func Eina_Bool (*canvas_alpha_get) (void *data, void *context); void (*context_free) (void *data, void *context); void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h); + void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y); + void (*context_clip_image_unset) (void *data, void *context); + void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h); void (*context_clip_unset) (void *data, void *context); int (*context_clip_get) (void *data, void *context, int *x, int *y, int *w, int *h); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 673924c50e..92272cd990 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -416,6 +416,60 @@ eng_context_clip_set(void *data EINA_UNUSED, void *context, int x, int y, int w, evas_common_draw_context_set_clip(context, x, y, w, h); } +static void +eng_context_clip_image_unset(void *data EINA_UNUSED, void *context) +{ + RGBA_Draw_Context *ctx = context; + + if (ctx->clip.mask) + { + Image_Entry *ie = ctx->clip.mask; +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_close(ie); + else +#endif + evas_cache_image_drop(ie); + // Is the above code safe? Hmmm... + //evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry); + ctx->clip.mask = NULL; + } +} + +static void +eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y) +{ + RGBA_Draw_Context *ctx = context; + + if (ctx->clip.mask && ctx->clip.mask != surface) + eng_context_clip_image_unset(data, context); + + ctx->clip.mask = surface; + ctx->clip.mask_x = x; + ctx->clip.mask_y = y; + + if (surface) + { + Image_Entry *ie = surface; +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_ref(ie); + else +#endif + evas_cache_image_ref(ie); + } +} + +static void +eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y) +{ + RGBA_Draw_Context *ctx = context; + + if (ie) *ie = ctx->clip.mask; + if (x) *x = ctx->clip.mask_x; + if (y) *y = ctx->clip.mask_y; +} + static void eng_context_clip_clip(void *data EINA_UNUSED, void *context, int x, int y, int w, int h) { @@ -1296,14 +1350,23 @@ _image_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, clip_h = dst->cache_entry.h; } + /* Set image mask, if any */ + cr->mask = dc->clip.mask; + cr->mask_x = dc->clip.mask_x; + cr->mask_y = dc->clip.mask_y; + if (cr->mask) + { + Image_Entry *im = cr->mask; + RECTS_CLIP_TO_RECT(clip_x, clip_y, clip_w, clip_h, + cr->mask_x, cr->mask_y, + im->w, im->h); + } + EINA_RECTANGLE_SET(&cr->clip, clip_x, clip_y, clip_w, clip_h); cr->mul_col = dc->mul.use ? dc->mul.col : 0xffffffff; cr->render_op = dc->render_op; cr->smooth = smooth; - cr->mask = dc->clip.mask; - cr->mask_x = dc->clip.mask_x; - cr->mask_y = dc->clip.mask_y; evas_thread_cmd_enqueue(_draw_thread_image_draw, cr); @@ -3010,6 +3073,9 @@ static Evas_Func func = eng_canvas_alpha_get, eng_context_free, eng_context_clip_set, + eng_context_clip_image_set, + eng_context_clip_image_unset, + eng_context_clip_image_get, eng_context_clip_clip, eng_context_clip_unset, eng_context_clip_get,