evas: Pass obscuring region to the filters

This will be most useful in a special case, where a filter is
used in a window decoration, applied to a snapshot object.

Another optimization that might be wanted is passing a list
of update regions (from the proxy or snapshot).

The filters don't support the obscuring region yet, only some
of the high-level logic is implemented.
This commit is contained in:
Jean-Philippe Andre 2017-03-15 14:49:50 +09:00
parent a6951397f6
commit 9b1ea2fc6b
10 changed files with 254 additions and 71 deletions

View File

@ -1,4 +1,5 @@
// import efl_gfx_types -> need to add Efl.Gfx.Color
import eina_types;
/* Everything in this file is internal to Evas. It is not meant to be used
from outside EFL itself! */

View File

@ -157,6 +157,24 @@ _evas_filter_state_set_internal(Evas_Filter_Program *pgm, Evas_Filter_Data *pd)
return evas_filter_program_state_set(pgm, &state);
}
static inline Eina_Bool
_evas_filter_obscured_region_changed(Evas_Filter_Data *pd)
{
Eina_Rectangle inter;
inter = pd->data->prev_obscured;
if (eina_rectangle_is_empty(&pd->data->obscured) &&
eina_rectangle_is_empty(&inter))
return EINA_FALSE;
if (!eina_rectangle_intersection(&inter, &pd->data->obscured))
return EINA_TRUE;
if ((inter.w != pd->data->prev_obscured.w) ||
(inter.h != pd->data->prev_obscured.h))
return EINA_TRUE;
return EINA_FALSE;
}
Eina_Bool
evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
void *output, void *context, void *surface,
@ -166,12 +184,13 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
if (!pd->data->invalid && (pd->data->chain || pd->data->code))
{
int X, Y, W, H, l = 0, r = 0, t = 0, b = 0;
int X, Y, W, H;
Evas_Filter_Context *filter;
void *drawctx;
Eina_Bool ok;
void *previous = pd->data->output;
Evas_Object_Filter_Data *fcow;
Evas_Filter_Padding pad;
/* NOTE: Filter rendering is now done ENTIRELY on CPU.
* So we rely on cache/cache2 to allocate a real image buffer,
@ -229,17 +248,15 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
}
else if (previous && !pd->data->changed)
{
Eina_Bool redraw;
Eina_Bool redraw = EINA_TRUE;
redraw = _evas_filter_state_set_internal(pd->data->chain, pd);
if (redraw)
if (_evas_filter_state_set_internal(pd->data->chain, pd))
DBG("Filter redraw by state change!");
else if (obj->changed)
{
// FIXME: Check that something else than X,Y changed!
redraw = EINA_TRUE;
DBG("Filter redraw by object content change!");
}
DBG("Filter redraw by object content change!");
else if (_evas_filter_obscured_region_changed(pd))
DBG("Filter redraw by obscure regions change!");
else redraw = EINA_FALSE;
// Scan proxies to find if any changed
if (!redraw && pd->data->sources)
@ -303,13 +320,16 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
drawctx = ENFN->context_new(ENDT);
ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
// Set obscured region
evas_filter_context_obscured_region_set(filter, pd->data->obscured);
// Allocate all buffers now
evas_filter_context_buffers_allocate_all(filter);
evas_filter_target_set(filter, context, surface, X + x, Y + y);
// Request rendering from the object itself (child class)
evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
ok = evas_filter_input_render(eo_obj, filter, drawctx, NULL, l, r, t, b, 0, 0, do_async);
evas_filter_program_padding_get(pd->data->chain, &pad, NULL);
ok = evas_filter_input_render(eo_obj, filter, drawctx, NULL, pad.l, pad.r, pad.t, pad.b, 0, 0, do_async);
if (!ok) ERR("Filter input render failed.");
ENFN->context_free(ENDT, drawctx);
@ -321,7 +341,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
fcow = FCOW_BEGIN(pd);
fcow->changed = EINA_FALSE;
fcow->async = do_async;
if (!ok) fcow->invalid = EINA_TRUE;
fcow->prev_obscured = fcow->obscured;
fcow->invalid = !ok;
FCOW_END(fcow, pd);
if (ok)
@ -534,15 +555,15 @@ EOLIAN static void
_efl_canvas_filter_internal_efl_gfx_filter_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
int *l, int *r, int *t, int *b)
{
if (!pd->data->chain)
{
if (l) *l = 0;
if (r) *r = 0;
if (t) *t = 0;
if (b) *b = 0;
return;
}
evas_filter_program_padding_get(pd->data->chain, l, r, t, b);
Evas_Filter_Padding pad = { 0, 0, 0, 0 };
if (pd->data->chain)
evas_filter_program_padding_get(pd->data->chain, &pad, NULL);
if (l) *l = pad.l;
if (r) *r = pad.r;
if (t) *t = pad.t;
if (b) *b = pad.b;
}
EOLIAN static void
@ -697,4 +718,27 @@ _efl_canvas_filter_internal_filter_output_buffer_get(Eo *obj EINA_UNUSED, Evas_F
return pd->data->output;
}
void
_evas_filter_obscured_region_set(Evas_Object_Protected_Data *obj,
const Eina_Rectangle rect)
{
Evas_Filter_Data *pd;
Evas_Object_Filter_Data *fcow;
pd = efl_data_scope_get(obj->object, MY_CLASS);
if (!pd->data) return;
fcow = FCOW_BEGIN(pd);
if ((rect.w <= 0) || (rect.h <= 0))
memset(&fcow->obscured, 0, sizeof(fcow->obscured));
else
{
fcow->obscured.x = rect.x - obj->cur->geometry.x;
fcow->obscured.y = rect.y - obj->cur->geometry.y;
fcow->obscured.w = rect.w;
fcow->obscured.h = rect.h;
}
FCOW_END(fcow, pd);
}
#include "canvas/efl_canvas_filter_internal.eo.c"

View File

@ -33,7 +33,7 @@ static const Evas_Object_Protected_State default_state = {
1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
};
static const Evas_Object_Filter_Data default_filter = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, { { NULL, 0.0 }, { NULL, 0.0 }, 0.0 }, EINA_FALSE, EINA_FALSE, EINA_TRUE
NULL, NULL, NULL, NULL, NULL, NULL, {}, {}, NULL, {}, EINA_FALSE, EINA_FALSE, EINA_TRUE
};
const void * const evas_object_filter_cow_default = &default_filter;
static const Evas_Object_Mask_Data default_mask = {

View File

@ -478,9 +478,7 @@ struct _Efl_Canvas_Text_Filter
Evas_Object *eo_obj;
Evas_Public_Data *evas;
void *dc; /* draw context - no clip, white, no colmul... */
struct {
int l, r, t, b;
} pad;
Evas_Filter_Padding pad;
Eina_Bool invalid;
Eina_Bool redraw;
};
@ -4051,15 +4049,15 @@ _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti)
if (EINA_UNLIKELY(ti->parent.format->gfx_filter != NULL))
{
int l = 0, r = 0, t = 0, b = 0;
Evas_Filter_Padding pad = { 0, 0, 0, 0 };
Evas_Filter_Program *pgm;
pgm = _format_filter_program_get(c->o, ti->parent.format);
if (pgm)
{
evas_filter_program_padding_get(pgm, &l, &r, &t, &b);
evas_filter_program_padding_get(pgm, &pad, NULL);
ti->x_adjustment = r + l;
ti->x_adjustment = pad.r + pad.l;
ti->parent.w = tw + ti->x_adjustment; // FIXME: why add l+r here,
ti->parent.h = th; // but not t+b here?
ti->parent.adv = advw;
@ -4647,21 +4645,21 @@ _layout_do_format(const Evas_Object *obj, Ctxt *c,
}
{
Evas_Coord pad_l = 0, pad_r = 0, pad_t = 0, pad_b = 0;
Evas_Filter_Padding pad = { 0, 0, 0, 0 };
Evas_Filter_Program *pgm = NULL;
if (EINA_UNLIKELY(fmt->gfx_filter != NULL))
pgm = _format_filter_program_get(efl_data_scope_get(obj, MY_CLASS), fmt);
if (EINA_UNLIKELY(pgm != NULL))
evas_filter_program_padding_get(pgm, &pad_l, &pad_r, &pad_t, &pad_b);
evas_filter_program_padding_get(pgm, &pad, NULL);
else
evas_text_style_pad_get(fmt->style, &pad_l, &pad_r, &pad_t, &pad_b);
evas_text_style_pad_get(fmt->style, &pad.l, &pad.r, &pad.t, &pad.b);
if (pad_l > *style_pad_l) *style_pad_l = pad_l;
if (pad_r > *style_pad_r) *style_pad_r = pad_r;
if (pad_t > *style_pad_t) *style_pad_t = pad_t;
if (pad_b > *style_pad_b) *style_pad_b = pad_b;
if (pad.l > *style_pad_l) *style_pad_l = pad.l;
if (pad.r > *style_pad_r) *style_pad_r = pad.r;
if (pad.t > *style_pad_t) *style_pad_t = pad.t;
if (pad.b > *style_pad_b) *style_pad_b = pad.b;
}
if (fmt->underline2)
@ -13487,9 +13485,7 @@ evas_object_textblock_render(Evas_Object *eo_obj EINA_UNUSED,
}
// target position
evas_filter_program_padding_get(pgm,
&filter->pad.l, &filter->pad.r,
&filter->pad.t, &filter->pad.b);
evas_filter_program_padding_get(pgm, &filter->pad, NULL);
target = _filter_target_position_calc(obj, ti, x, y);
ENFN->context_color_set(ENDT, context, 255, 255, 255, 255);
ENFN->context_multiplier_set(ENDT, context,
@ -13828,7 +13824,7 @@ _efl_canvas_text_efl_canvas_filter_internal_filter_state_prepare(
Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_TEXT_CLASS);
Evas_Object_Textblock_Text_Item *ti = data;
Efl_Canvas_Text_Filter_Program *program;
int l = 0, r = 0, t = 0, b = 0;
Evas_Filter_Padding pad = {};
#define STATE_COLOR(dst, src) dst.r = src.r; dst.g = src.g; dst.b = src.b; dst.a = src.a
STATE_COLOR(state->color, ti->parent.format->color.normal);
@ -13839,9 +13835,9 @@ _efl_canvas_text_efl_canvas_filter_internal_filter_state_prepare(
#undef STATE_COLOR
program = _filter_program_find(o, ti->parent.format->gfx_filter->name);
if (program) evas_filter_program_padding_get(program->pgm, &l, &r, &t, &b);
if (program) evas_filter_program_padding_get(program->pgm, &pad, NULL);
state->w = ti->parent.w; // + l + r; (already included)
state->h = ti->parent.h + t + b;
state->h = ti->parent.h + pad.t + pad.b;
state->scale = obj->cur->scale;
}

View File

@ -12,6 +12,10 @@
#include "evas_render2.h"
// FIXME: Ugly!
#define EFL_CANVAS_FILTER_INTERNAL_PROTECTED
#include "efl_canvas_filter_internal.eo.h"
/* Enable this for extra verbose rendering debug logs */
//#define REND_DBG 1
#define STDOUT_DBG
@ -2737,29 +2741,78 @@ _is_obj_in_rect(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
}
#endif
static Eina_Bool
_snapshot_needs_redraw(Evas_Public_Data *evas, Evas_Object_Protected_Data *snap)
static inline Eina_Bool
_rectangle_inside(Eina_Rectangle *big, Eina_Rectangle *small)
{
Eina_Rectangle inter = *big;
if (!eina_rectangle_intersection(&inter, small))
return EINA_FALSE;
if ((inter.w == small->w) && (inter.h == small->h))
return EINA_TRUE;
return EINA_FALSE;
}
static Eina_Bool
_snapshot_needs_redraw(Evas_Public_Data *evas, Evas_Object_Protected_Data *snap,
Eina_Rectangle *opaque)
{
Eina_Bool above = EINA_FALSE, ret = EINA_FALSE;
const int x = snap->cur->geometry.x;
const int y = snap->cur->geometry.y;
const int w = snap->cur->geometry.w;
const int h = snap->cur->geometry.h;
Evas_Object_Protected_Data *obj;
Evas_Active_Entry *ent;
Eina_Rectangle snap_rect = { x, y, w, h };
void *surface;
surface = _evas_object_image_surface_get(snap, EINA_FALSE);
if (!surface) return EINA_TRUE;
if (!surface) ret = EINA_TRUE;
memset(opaque, 0, sizeof(*opaque));
EINA_INARRAY_FOREACH(&evas->active_objects, ent)
{
obj = ent->obj;
if (obj == snap) break;
if (!obj->is_smart && obj->changed &&
evas_object_is_in_output_rect(obj->object, obj, x, y, w, h))
return EINA_TRUE;
if (obj == snap)
{
above = EINA_TRUE;
continue;
}
if (!above)
{
if (ret) continue;
if (!obj->is_smart && obj->changed &&
evas_object_is_in_output_rect(obj->object, obj, x, y, w, h))
ret = EINA_TRUE;
}
else
{
if (!obj->is_smart && !obj->clip.clipees &&
evas_object_is_opaque(obj->object, obj))
{
Eina_Rectangle cur = {
obj->cur->geometry.x, obj->cur->geometry.y,
obj->cur->geometry.w, obj->cur->geometry.h
};
if (!eina_rectangles_intersect(&snap_rect, &cur))
continue;
if (!opaque->w || !opaque->h)
*opaque = cur;
else if (_rectangle_inside(&cur, opaque))
*opaque = cur;
else if (!_rectangle_inside(opaque, &cur))
{
*opaque = (Eina_Rectangle) { 0, 0, 0, 0 };
break;
}
}
}
}
return EINA_FALSE;
return ret;
}
static Eina_Bool
@ -3196,7 +3249,7 @@ evas_render_updates_internal(Evas *eo_e,
eina_evlog("+render_snapshots", eo_e, 0.0, NULL);
for (j = e->snapshot_objects.count - 1; j >= 0; j--)
{
Eina_Rectangle output, cr, ur;
Eina_Rectangle output, cr, ur, opaque;
obj = eina_array_data_get(&e->snapshot_objects, j);
@ -3208,7 +3261,7 @@ evas_render_updates_internal(Evas *eo_e,
EINA_RECTANGLE_SET(&ur, ux, uy, uw, uh);
if (eina_rectangle_intersection(&ur, &output) &&
_snapshot_needs_redraw(evas, obj))
_snapshot_needs_redraw(evas, obj, &opaque))
{
void *pseudo_canvas;
unsigned int restore_offset = offset;
@ -3219,6 +3272,10 @@ evas_render_updates_internal(Evas *eo_e,
pseudo_canvas = _evas_object_image_surface_get(obj, EINA_TRUE);
// TODO: List of canvas regions that need redraw
// Add obscure region (make it a list?)
_evas_filter_obscured_region_set(obj, opaque);
RD(0, " SNAPSHOT %s [sfc:%p ur:%d,%d %dx%d]\n", RDNAME(obj), pseudo_canvas, ur.x, ur.y, ur.w, ur.h);
ctx = ENFN->context_new(ENDT);
clean_them |= evas_render_updates_internal_loop(eo_e, e, pseudo_canvas, ctx,

View File

@ -1281,6 +1281,12 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
return cmd;
}
void
evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect)
{
ctx->obscured.real = rect;
}
/* Final target */
Eina_Bool
evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
@ -1601,6 +1607,55 @@ _filter_thread_run_cb(void *data)
ctx->post_run.cb(ctx, ctx->post_run.data, success);
}
static void
_filter_obscured_region_calc(Evas_Filter_Context *ctx)
{
Eina_Rectangle rect = ctx->obscured.real;
// left
if (rect.x > 0)
{
rect.x += ctx->pad.calculated.l;
rect.w -= ctx->pad.calculated.l;
}
else
{
rect.w -= (-rect.x);
rect.x = 0;
}
if (rect.w < 0) rect.w = 0;
// right
if ((rect.x + rect.w) <= ctx->w)
rect.w -= ctx->pad.calculated.r;
else
rect.w = ctx->w - rect.x;
// top
if (rect.y > 0)
{
rect.y += ctx->pad.calculated.t;
rect.h -= ctx->pad.calculated.t;
}
else
{
rect.h -= (-rect.y);
rect.y = 0;
}
if (rect.h < 0) rect.h = 0;
// bottom
if ((rect.y + rect.h) <= ctx->h)
rect.h -= ctx->pad.calculated.b;
else
rect.h = ctx->h - rect.y;
if ((rect.w <= 0) || (rect.h <= 0))
memset(&rect, 0, sizeof(rect));
ctx->obscured.effective = rect;
}
Eina_Bool
evas_filter_run(Evas_Filter_Context *ctx)
{
@ -1611,6 +1666,8 @@ evas_filter_run(Evas_Filter_Context *ctx)
if (!ctx->commands)
return EINA_TRUE;
_filter_obscured_region_calc(ctx);
if (ctx->async)
{
evas_thread_queue_flush(_filter_thread_run_cb, ctx);

View File

@ -324,7 +324,7 @@ struct _Evas_Filter_Program
Eina_Inlist /* Buffer */ *buffers;
struct {
// Note: padding can't be in the state as it's calculated after running Lua
int l, r, t, b;
Evas_Filter_Padding calculated, final;
} pad;
Efl_Canvas_Filter_State state;
Eina_Inlist *data; // Evas_Filter_Data_Binding
@ -2882,21 +2882,22 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
EAPI Eina_Bool
evas_filter_program_padding_get(Evas_Filter_Program *pgm,
int *l, int *r, int *t, int *b)
Evas_Filter_Padding *out_final,
Evas_Filter_Padding *out_calculated)
{
Evas_Filter_Instruction *instr;
int pl = 0, pr = 0, pt = 0, pb = 0;
int maxl = 0, maxr = 0, maxt = 0, maxb = 0;
int setl = 0, setr = 0, sett = 0, setb = 0;
Eina_Bool was_set = EINA_FALSE;
Buffer *buf;
EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
if (pgm->padding_calc || pgm->padding_set)
if (pgm->padding_calc)
{
if (l) *l = pgm->pad.l;
if (r) *r = pgm->pad.r;
if (t) *t = pgm->pad.t;
if (b) *b = pgm->pad.b;
if (out_final) *out_final = pgm->pad.final;
if (out_calculated) *out_calculated = pgm->pad.calculated;
return EINA_TRUE;
}
@ -2909,8 +2910,8 @@ evas_filter_program_padding_get(Evas_Filter_Program *pgm,
{
if (instr->type == EVAS_FILTER_MODE_PADDING_SET)
{
instr->pad.update(pgm, instr, &maxl, &maxr, &maxt, &maxb);
break;
instr->pad.update(pgm, instr, &setl, &setr, &sett, &setb);
was_set = EINA_TRUE;
}
else if (instr->pad.update)
{
@ -2922,16 +2923,23 @@ evas_filter_program_padding_get(Evas_Filter_Program *pgm,
}
}
pgm->pad.l = maxl;
pgm->pad.r = maxr;
pgm->pad.t = maxt;
pgm->pad.b = maxb;
pgm->pad.calculated.l = maxl;
pgm->pad.calculated.r = maxr;
pgm->pad.calculated.t = maxt;
pgm->pad.calculated.b = maxb;
if (!was_set)
pgm->pad.final = pgm->pad.calculated;
else
{
pgm->pad.final.l = setl;
pgm->pad.final.r = setr;
pgm->pad.final.t = sett;
pgm->pad.final.b = setb;
}
pgm->padding_calc = EINA_TRUE;
if (l) *l = maxl;
if (r) *r = maxr;
if (t) *t = maxt;
if (b) *b = maxb;
if (out_final) *out_final = pgm->pad.final;
if (out_calculated) *out_calculated = pgm->pad.calculated;
return EINA_TRUE;
}
@ -3503,7 +3511,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
_buffers_update(ctx, pgm);
// Compute and save padding info
evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb);
evas_filter_program_padding_get(pgm, &ctx->pad.final, &ctx->pad.calculated);
dc = ENFN->context_new(ENDT);
ENFN->context_color_set(ENDT, dc, 255, 255, 255, 255);

View File

@ -111,6 +111,7 @@ typedef enum _Evas_Filter_Interpolation_Mode Evas_Filter_Interpolation_Mode;
typedef Evas_Filter_Buffer * (*evas_filter_buffer_scaled_get_func)(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
struct _Evas_Filter_Context
{
Evas_Public_Data *evas;
@ -125,7 +126,16 @@ struct _Evas_Filter_Context
// Variables changing at each run
int w, h; // Dimensions of the input/output buffers
int padl, padt, padr, padb; // Padding in the current input/output buffers
struct {
// Padding in the current input/output buffers
Evas_Filter_Padding calculated, final;
} pad;
struct {
// Useless region: obscured by other objects
Eina_Rectangle real, effective;
} obscured;
struct
{

View File

@ -36,6 +36,7 @@ typedef struct _Evas_Filter_Context Evas_Filter_Context;
typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding;
typedef struct _Evas_Filter_Padding Evas_Filter_Padding;
typedef enum _Evas_Filter_Mode Evas_Filter_Mode;
typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type;
typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
@ -124,6 +125,12 @@ enum _Evas_Filter_Transform_Flags
EVAS_FILTER_TRANSFORM_VFLIP = 1
};
/** @internal */
struct _Evas_Filter_Padding
{
int l, r, t, b;
};
#define EFL_CANVAS_FILTER_STATE_DEFAULT { {}, { 255, 255, 255, 255 }, { "default", 0.0 }, {}, 0, 0, 1.0, 0.0 }
/* Parser stuff (high level API) */
@ -131,7 +138,7 @@ EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool in
EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, const Efl_Canvas_Filter_State *state);
EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
EAPI void evas_filter_program_del(Evas_Filter_Program *pgm);
EAPI Eina_Bool evas_filter_program_padding_get(Evas_Filter_Program *pgm, int *l, int *r, int *t, int *b);
EAPI Eina_Bool evas_filter_program_padding_get(Evas_Filter_Program *pgm, Evas_Filter_Padding *final, Evas_Filter_Padding *calc);
EAPI void evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash *sources);
void evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Inlist *data);
@ -145,6 +152,7 @@ void evas_filter_context_proxy_render_all(Evas_Filter_Contex
void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)
Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
void evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect);
int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);

View File

@ -1290,6 +1290,7 @@ struct _Evas_Object_Filter_Data
Evas_Filter_Program *chain;
Eina_Hash *sources; // Evas_Filter_Proxy_Binding
Eina_Inlist *data; // Evas_Filter_Data_Binding
Eina_Rectangle prev_obscured, obscured;
void *output;
struct {
struct {
@ -2034,6 +2035,7 @@ void *efl_input_hold_legacy_info_fill(Efl_Input_Hold *evt, Evas_Event_Flags **pf
Eina_Bool evas_vg_loader_svg(Evas_Object *vg, const Eina_File *f, const char *key EINA_UNUSED);
void *_evas_object_image_surface_get(Evas_Object_Protected_Data *obj, Eina_Bool create);
void _evas_filter_obscured_region_set(Evas_Object_Protected_Data *obj, const Eina_Rectangle rect);
Eina_Bool _evas_image_proxy_source_clip_get(const Eo *eo_obj);
void _evas_focus_dispatch_event(Evas_Object_Protected_Data *obj,