forked from enlightenment/efl
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:
parent
a6951397f6
commit
9b1ea2fc6b
|
@ -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! */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue