From b5a5f61cd6ea35f47b247542fece63463f21fad1 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 4 Apr 2017 10:25:05 +0900 Subject: [PATCH] evas filters: Prevent redraws when obscure changed If the obscured area in a snapshot object changes a lot, do not try to keep track of it forever. Instead, redraw the filter over the entire object region, without obscure. This fixes a performance issue when an opaque window is moved above a fixed transparent window (the latter has a snapshot with blur filter). --- src/lib/evas/canvas/evas_filter_mixin.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c index 1bae8c6..1ac5e1c 100644 --- a/src/lib/evas/canvas/evas_filter_mixin.c +++ b/src/lib/evas/canvas/evas_filter_mixin.c @@ -13,6 +13,12 @@ #define FCOW_BEGIN(_pd) ({ Evas_Object_Filter_Data *_fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data)); _state_check(_fcow); _fcow; }) #define FCOW_END(_fcow, _pd) eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data), _fcow, EINA_TRUE) +#define FCOW_WRITE(pd, name, value) do { \ + if (pd->data->name != (value)) { \ + fcow = FCOW_BEGIN(pd); \ + fcow->name = (value); \ + FCOW_END(fcow, pd); \ + }} while (0) typedef struct _Evas_Filter_Data Evas_Filter_Data; typedef struct _Evas_Filter_Post_Render_Data Evas_Filter_Post_Render_Data; @@ -40,6 +46,7 @@ struct _Evas_Object_Filter_Data } next; double pos; } state; + int obscured_changes; Eina_Bool changed : 1; Eina_Bool invalid : 1; // Code parse failed Eina_Bool async : 1; @@ -844,11 +851,12 @@ Eina_Bool _evas_filter_obscured_regions_set(Evas_Object_Protected_Data *obj, const Eina_Tiler *tiler) { Evas_Object_Filter_Data *fcow; - Eina_Rectangle prev, rect = {}, empty = {}; + Eina_Rectangle prev, rect = {}; Eina_Rectangle *r; Evas_Filter_Data *pd; Eina_Iterator *it; - Eina_Bool was_empty; + Eina_Bool was_empty, redraw = EINA_FALSE; + int obscured_changes = 0; int area = 0; // TODO: Can we handle more than one opaque region? @@ -870,15 +878,29 @@ _evas_filter_obscured_regions_set(Evas_Object_Protected_Data *obj, const Eina_Ti eina_iterator_free(it); prev = pd->data->prev_obscured; - if (!pd->data->changed && !memcmp(&prev, &empty, sizeof(prev))) - was_empty = EINA_TRUE; + if (!pd->data->changed && (!prev.w || !prev.h)) + { + was_empty = EINA_TRUE; + obscured_changes = 0; + } else if (memcmp(&rect, &prev, sizeof(rect))) { fcow = FCOW_BEGIN(pd); fcow->obscured = rect; + obscured_changes = fcow->obscured_changes + 1; + if (obscured_changes > 2) + { + // Reset obscure as it changes too much + memset(&fcow->obscured, 0, sizeof(fcow->obscured)); + obscured_changes = 0; + redraw = EINA_TRUE; + } FCOW_END(fcow, pd); } + FCOW_WRITE(pd, obscured_changes, obscured_changes); + if (redraw) return EINA_TRUE; + // 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) || @@ -887,7 +909,7 @@ _evas_filter_obscured_regions_set(Evas_Object_Protected_Data *obj, const Eina_Ti return EINA_TRUE; // Snapshot objects need to be redrawn if the obscured region has shrank - if (!was_empty && !_evas_eina_rectangle_inside(&prev, &pd->data->obscured)) + if (!was_empty && !_evas_eina_rectangle_inside(&pd->data->obscured, &prev)) return EINA_TRUE; return EINA_FALSE; -- 2.7.4