Eina_Hash *sources; // Evas_Filter_Proxy_Binding
Eina_Inlist *data; // Evas_Filter_Data_Binding
Eina_Rectangle prev_obscured, obscured;
+ Evas_Filter_Padding prev_padding, padding;
void *output;
struct {
struct {
if (!pd->data->chain)
{
Evas_Filter_Program *pgm;
+ Eina_Bool invalid;
pgm = evas_filter_program_new(pd->data->name, alpha);
evas_filter_program_source_set_all(pgm, pd->data->sources);
evas_filter_program_data_set_all(pgm, pd->data->data);
_evas_filter_state_set_internal(pgm, pd);
- if (!evas_filter_program_parse(pgm, pd->data->code))
+ invalid = !evas_filter_program_parse(pgm, pd->data->code);
+ if (invalid)
{
ERR("Filter program parsing failed");
evas_filter_program_del(pgm);
-
- if (!pd->data->invalid)
- {
- fcow = FCOW_BEGIN(pd);
- fcow->invalid = EINA_TRUE;
- FCOW_END(fcow, pd);
- }
-
- return EINA_FALSE;
+ pgm = NULL;
}
fcow = FCOW_BEGIN(pd);
+ if (!invalid) evas_filter_program_padding_get(pgm, NULL, &fcow->padding);
fcow->chain = pgm;
- fcow->invalid = EINA_FALSE;
+ fcow->invalid = invalid;
FCOW_END(fcow, pd);
+ if (invalid) return EINA_FALSE;
}
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)
DBG("Filter redraw by object content change!");
fcow->changed = EINA_FALSE;
fcow->async = do_async;
fcow->prev_obscured = fcow->obscured;
+ fcow->prev_padding = fcow->padding;
+ fcow->padding = pad;
fcow->invalid = EINA_FALSE;
FCOW_END(fcow, pd);
Evas_Object_Protected_Data *obj;
Evas_Filter_Program *pgm = NULL;
Evas_Object_Filter_Data *fcow;
+ Eina_Bool invalid = pd->data->invalid;
Eina_Bool alpha;
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
evas_filter_program_source_set_all(pgm, fcow->sources);
evas_filter_program_data_set_all(pgm, fcow->data);
_evas_filter_state_set_internal(pgm, pd);
- if (!evas_filter_program_parse(pgm, code))
+ invalid = !evas_filter_program_parse(pgm, code);
+ if (invalid)
{
ERR("Parsing failed!");
evas_filter_program_del(pgm);
pgm = NULL;
}
+ else
+ {
+ evas_filter_program_padding_get(pgm, NULL, &fcow->padding);
+ }
}
fcow->chain = pgm;
fcow->changed = EINA_TRUE;
- fcow->invalid = (pgm == NULL);
+ fcow->invalid = invalid;
eina_stringshare_replace(&fcow->code, code);
}
FCOW_END(fcow, pd);
Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
Evas_Object_Protected_Data *source = NULL;
Evas_Object_Filter_Data *fcow = NULL;
+ Eina_Bool invalid = pd->data->invalid;
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
if (eo_source)
eina_hash_add(fcow->sources, pb->name, pb);
evas_filter_program_source_set_all(fcow->chain, fcow->sources);
evas_filter_program_data_set_all(fcow->chain, fcow->data);
- evas_filter_program_parse(fcow->chain, fcow->code);
+ invalid = !evas_filter_program_parse(fcow->chain, fcow->code);
+ if (!invalid) evas_filter_program_padding_get(fcow->chain, NULL, &fcow->padding);
// Update object
update:
if (fcow)
{
fcow->changed = EINA_TRUE;
- fcow->invalid = EINA_FALSE;
+ fcow->invalid = invalid;
FCOW_END(fcow, pd);
}
{
Evas_Filter_Data_Binding *db, *found = NULL;
Evas_Object_Filter_Data *fcow;
+ Eina_Bool invalid = pd->data->invalid;
EINA_SAFETY_ON_NULL_RETURN(pd->data);
EINA_SAFETY_ON_NULL_RETURN(name);
db->execute = execute;
fcow->data = eina_inlist_append(fcow->data, EINA_INLIST_GET(db));
}
- fcow->invalid = EINA_FALSE;
if (fcow->chain)
{
evas_filter_program_data_set_all(fcow->chain, fcow->data);
- evas_filter_program_parse(fcow->chain, fcow->code);
+ invalid = !evas_filter_program_parse(fcow->chain, fcow->code);
+ if (!invalid) evas_filter_program_padding_get(fcow->chain, NULL, &fcow->padding);
}
+ fcow->invalid = invalid;
fcow->changed = 1;
}
FCOW_END(fcow, pd);
return pd->data->output;
}
-void
+Eina_Bool
_evas_filter_obscured_region_set(Evas_Object_Protected_Data *obj,
const Eina_Rectangle rect)
{
- Evas_Filter_Data *pd;
Evas_Object_Filter_Data *fcow;
+ Evas_Filter_Data *pd;
+ Eina_Rectangle prev;
pd = efl_data_scope_get(obj->object, MY_CLASS);
- if (!pd->data) return;
+ if (!pd->data) return EINA_FALSE;
+
+ prev = pd->data->prev_obscured;
fcow = FCOW_BEGIN(pd);
if ((rect.w <= 0) || (rect.h <= 0))
fcow->obscured.h = rect.h;
}
FCOW_END(fcow, pd);
+
+ // Snapshot objects need to be redrawn if the padding has increased
+ if ((pd->data->prev_padding.l < pd->data->padding.l) ||
+ (pd->data->prev_padding.r < pd->data->padding.r) ||
+ (pd->data->prev_padding.t < pd->data->padding.t) ||
+ (pd->data->prev_padding.b < pd->data->padding.b))
+ return EINA_TRUE;
+
+ // Snapshot objects need to be redrawn if the obscured region has shrank
+ if (!_evas_eina_rectangle_inside(&prev, &pd->data->obscured))
+ return EINA_TRUE;
+
+ return EINA_FALSE;
}
void
}
#endif
-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 void
_snapshot_redraw_update(Evas_Public_Data *evas, Evas_Object_Protected_Data *snap)
{
const int h = snap->cur->geometry.h;
Evas_Object_Protected_Data *obj;
Evas_Active_Entry *ent;
- Eina_Rectangle snap_rect = { x, y, w, h };
+ Eina_Rectangle snap_clip, snap_rect = { x, y, w, h };
Eina_Rectangle opaque = {};
void *surface;
// FIXME: Use evas' standard rectangle logic instead of this bad algo
+ // FIXME: This walks ALL the objects in the canvas to find the opaque region
// TODO: Improve opaque region support, maybe have more than one
// TODO: Also list redraw regions (partial updates)
if (!evas_object_is_visible(snap->object, snap)) return;
+ evas_object_clip_recalc(snap);
+ snap_clip.x = snap->cur->cache.clip.x;
+ snap_clip.y = snap->cur->cache.clip.y;
+ snap_clip.w = snap->cur->cache.clip.w;
+ snap_clip.h = snap->cur->cache.clip.h;
+
surface = _evas_object_image_surface_get(snap, EINA_FALSE);
if (!surface) need_redraw = EINA_TRUE;
if (snap->changed) add_rect = EINA_TRUE;
obj = ent->obj;
if (obj == snap)
{
- if (!need_redraw) break;
above = EINA_TRUE;
continue;
}
};
if ((opaque.w * opaque.h) < (cur.w * cur.h))
- {
- opaque = cur;
- continue;
- }
-
- if (!eina_rectangles_intersect(&snap_rect, &cur))
+ opaque = cur;
+ else if (!eina_rectangles_intersect(&snap_rect, &cur))
continue;
-
- if (!opaque.w || !opaque.h)
+ else if (!opaque.w || !opaque.h)
opaque = cur;
- else if (_rectangle_inside(&cur, &opaque))
+ else if (_evas_eina_rectangle_inside(&cur, &opaque))
opaque = cur;
- //else if (!_rectangle_inside(&opaque, &cur))
+ //else if (!_evas_eina_rectangle_inside(&opaque, &cur))
+
+ if (_evas_eina_rectangle_inside(&opaque, &snap_clip))
+ return;
}
}
}
- _evas_filter_obscured_region_set(snap, opaque);
+ need_redraw |= _evas_filter_obscured_region_set(snap, opaque);
snap->snapshot_needs_redraw |= need_redraw;
if (add_rect || need_redraw)
{
- // FIXME: Only add necessary rects
- // Note that with filters this is extremely tricky: a simple color
- // change would mean redraw all. Also blurs, displace, etc... need
- // to expand by the cutout_margin (filter padding).
- ENFN->output_redraws_rect_add(ENDT,
- snap->cur->geometry.x, snap->cur->geometry.y,
- snap->cur->geometry.w, snap->cur->geometry.h);
+ // FIXME: Only add necessary rects (if object itself hasn't changed)
+ ENFN->output_redraws_rect_add(ENDT, x, y, w, h);
}
}