summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-07-28 14:17:53 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-07-28 17:13:52 +0900
commit0058cd08f4adfc0db4d29355d055d1748d28b903 (patch)
tree5c8ea742a4fc389d3ce543b1ed43d1fcb6e0b5a4
parentf9c7d25b0845ab0c99cee402700d046ae318da39 (diff)
downloadefl-0058cd08f4adfc0db4d29355d055d1748d28b903.tar.gz
Evas filters: Fix COW usage in filter mixin
-rw-r--r--src/lib/evas/canvas/evas_filter_mixin.c141
1 files changed, 76 insertions, 65 deletions
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c
index ffc8dfa08f..934a8c6fb9 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -76,6 +76,9 @@ _filter_source_hash_free_cb(void *data)
free(pb);
}
+#define FCOW_BEGIN(_pd) eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data))
+#define FCOW_END(_fcow, _pd) eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data), _fcow, EINA_TRUE)
+
Eina_Bool
evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
void *output, void *context, void *surface,
@@ -90,8 +93,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
void *drawctx;
Eina_Bool ok;
void *previous = pd->data->output;
- Evas_Object_Filter_Data *fcow =
- eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data));
+ Evas_Object_Filter_Data *fcow;
+ void *filter_output;
/* NOTE: Filter rendering is now done ENTIRELY on CPU.
* So we rely on cache/cache2 to allocate a real image buffer,
@@ -120,37 +123,43 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
else
ENFN->context_multiplier_unset(output, context);
- if (!fcow->chain)
+ if (!pd->data->chain)
{
Evas_Filter_Program *pgm;
- pgm = evas_filter_program_new(fcow->name, alpha);
- evas_filter_program_source_set_all(pgm, fcow->sources);
- evas_filter_program_data_set_all(pgm, fcow->data);
+ 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_program_state_set(pgm, eo_obj, obj,
- fcow->state.cur.name, fcow->state.cur.value,
- fcow->state.next.name, fcow->state.next.value,
- fcow->state.pos);
- if (!evas_filter_program_parse(pgm, fcow->code))
+ pd->data->state.cur.name, pd->data->state.cur.value,
+ pd->data->state.next.name, pd->data->state.next.value,
+ pd->data->state.pos);
+ if (!evas_filter_program_parse(pgm, pd->data->code))
{
ERR("Filter program parsing failed");
evas_filter_program_del(pgm);
- fcow->invalid = EINA_TRUE;
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
- fcow, EINA_TRUE);
+ if (!pd->data->invalid)
+ {
+ fcow = FCOW_BEGIN(pd);
+ fcow->invalid = EINA_TRUE;
+ FCOW_END(fcow, pd);
+ }
+
return EINA_FALSE;
}
+ fcow = FCOW_BEGIN(pd);
fcow->chain = pgm;
fcow->invalid = EINA_FALSE;
+ FCOW_END(fcow, pd);
}
- else if (previous && !fcow->changed)
+ else if (previous && !pd->data->changed)
{
Eina_Bool redraw;
- redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj,
- fcow->state.cur.name, fcow->state.cur.value,
- fcow->state.next.name, fcow->state.next.value,
- fcow->state.pos);
+ redraw = evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
+ pd->data->state.cur.name, pd->data->state.cur.value,
+ pd->data->state.next.name, pd->data->state.next.value,
+ pd->data->state.pos);
if (redraw)
DBG("Filter redraw by state change!");
else if (obj->changed)
@@ -161,13 +170,13 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
}
// Scan proxies to find if any changed
- if (!redraw && fcow->sources)
+ if (!redraw && pd->data->sources)
{
Evas_Filter_Proxy_Binding *pb;
Evas_Object_Protected_Data *source;
Eina_Iterator *iter;
- iter = eina_hash_iterator_data_new(fcow->sources);
+ iter = eina_hash_iterator_data_new(pd->data->sources);
EINA_ITERATOR_FOREACH(iter, pb)
{
source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
@@ -189,29 +198,30 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
X + x, Y + y, W, H, // dst
EINA_FALSE, // smooth
do_async);
-
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
- fcow, EINA_TRUE);
return EINA_TRUE;
}
}
else
- evas_filter_program_state_set(fcow->chain, eo_obj, obj,
- fcow->state.cur.name, fcow->state.cur.value,
- fcow->state.next.name, fcow->state.next.value,
- fcow->state.pos);
+ evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
+ pd->data->state.cur.name, pd->data->state.cur.value,
+ pd->data->state.next.name, pd->data->state.next.value,
+ pd->data->state.pos);
filter = evas_filter_context_new(obj->layer->evas, do_async);
// Run script
- ok = evas_filter_context_program_use(filter, fcow->chain);
+ ok = evas_filter_context_program_use(filter, pd->data->chain);
if (!filter || !ok)
{
ERR("Parsing failed?");
evas_filter_context_destroy(filter);
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
- fcow, EINA_TRUE);
+ if (!pd->data->invalid)
+ {
+ fcow = FCOW_BEGIN(pd);
+ fcow->invalid = EINA_TRUE;
+ FCOW_END(fcow, pd);
+ }
return EINA_FALSE;
}
@@ -227,12 +237,12 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
evas_filter_target_set(filter, context, surface, X + x, Y + y);
// Steal output and release previous
- fcow->output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
- if (fcow->output != previous)
+ filter_output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
+ if (filter_output != previous)
evas_filter_buffer_backing_release(filter, previous);
// Request rendering from the object itself (child class)
- evas_filter_program_padding_get(fcow->chain, &l, &r, &t, &b);
+ evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
ENFN->context_free(ENDT, drawctx);
@@ -240,10 +250,12 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
// Add post-run callback and run filter
evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
ok = evas_filter_run(filter);
+
+ fcow = FCOW_BEGIN(pd);
+ fcow->output = filter_output;
fcow->changed = EINA_FALSE;
if (!ok) fcow->invalid = EINA_TRUE;
-
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data **) &(pd->data), fcow, EINA_TRUE);
+ FCOW_END(fcow, pd);
if (ok)
{
@@ -265,6 +277,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Filter_Program *pgm = NULL;
+ Evas_Object_Filter_Data *fcow;
Eina_Bool alpha;
if (!pd) return;
@@ -273,7 +286,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
pd->data->name && name && !strcmp(name, pd->data->name)) return;
evas_object_async_block(obj);
- EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
+ fcow = FCOW_BEGIN(pd);
{
// Parse filter program
evas_filter_program_del(fcow->chain);
@@ -300,7 +313,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
fcow->invalid = (pgm == NULL);
eina_stringshare_replace(&fcow->code, code);
}
- EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
+ FCOW_END(fcow, pd);
// Update object
eo_do(eo_obj, evas_filter_dirty());
@@ -347,8 +360,7 @@ _evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
if (pb_old && (pb_old->eo_source == eo_source)) return;
}
- fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data);
-
+ fcow = FCOW_BEGIN(pd);
if (!fcow->sources)
fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb));
else if (pb_old)
@@ -359,7 +371,7 @@ _evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
pb_old = eina_hash_find(fcow->sources, name);
if (!pb_old)
{
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
+ FCOW_END(fcow, pd);
return;
}
eina_hash_del_by_key(fcow->sources, name);
@@ -395,7 +407,7 @@ update:
{
fcow->changed = EINA_TRUE;
fcow->invalid = EINA_FALSE;
- eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
+ FCOW_END(fcow, pd);
}
eo_do(eo_obj, evas_filter_dirty());
@@ -426,24 +438,22 @@ _evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
(next_state != pd->data->state.next.name) || (next_val != pd->data->state.next.value) ||
(pos != pd->data->state.pos))
{
- EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
+ Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
+ fcow->changed = 1;
+ fcow->state.cur.name = cur_state;
+ fcow->state.cur.value = cur_val;
+ fcow->state.next.name = next_state;
+ fcow->state.next.value = next_val;
+ fcow->state.pos = pos;
+ FCOW_END(fcow, pd);
+
+ if (pd->data->chain)
{
- fcow->changed = 1;
- fcow->state.cur.name = cur_state;
- fcow->state.cur.value = cur_val;
- fcow->state.next.name = next_state;
- fcow->state.next.value = next_val;
- fcow->state.pos = pos;
-
- if (pd->data->chain)
- {
- evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
- fcow->state.cur.name, fcow->state.cur.value,
- fcow->state.next.name, fcow->state.next.value,
- fcow->state.pos);
- }
+ evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
+ pd->data->state.cur.name, pd->data->state.cur.value,
+ pd->data->state.next.name, pd->data->state.next.value,
+ pd->data->state.pos);
}
- EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
// Mark as changed
eo_do(eo_obj, evas_filter_dirty());
@@ -474,9 +484,9 @@ _evas_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool
{
if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val))
{
- EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
- fcow->changed = val;
- EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
+ Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
+ fcow->changed = val;
+ FCOW_END(fcow, pd);
}
}
@@ -485,9 +495,9 @@ _evas_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool
{
if (pd->data->invalid != val)
{
- EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
- fcow->invalid = val;
- EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
+ Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
+ fcow->invalid = val;
+ FCOW_END(fcow, pd);
}
}
@@ -527,6 +537,7 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
Eina_Bool execute)
{
Evas_Filter_Data_Binding *db, *found = NULL;
+ Evas_Object_Filter_Data *fcow;
EINA_SAFETY_ON_NULL_RETURN(pd->data);
EINA_SAFETY_ON_NULL_RETURN(name);
@@ -545,7 +556,7 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
}
}
- EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
+ fcow = FCOW_BEGIN(pd);
{
if (found)
{
@@ -564,7 +575,7 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
evas_filter_program_data_set_all(fcow->chain, fcow->data);
fcow->changed = 1;
}
- EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
+ FCOW_END(fcow, pd);
}
#include "evas_filter.eo.c"