summaryrefslogtreecommitdiff
path: root/src/lib
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 /src/lib
parentf9c7d25b0845ab0c99cee402700d046ae318da39 (diff)
Evas filters: Fix COW usage in filter mixin
Diffstat (limited to 'src/lib')
-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 ffc8dfa..934a8c6 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)
76 free(pb); 76 free(pb);
77} 77}
78 78
79#define FCOW_BEGIN(_pd) eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data))
80#define FCOW_END(_fcow, _pd) eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(_pd->data), _fcow, EINA_TRUE)
81
79Eina_Bool 82Eina_Bool
80evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, 83evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
81 void *output, void *context, void *surface, 84 void *output, void *context, void *surface,
@@ -90,8 +93,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
90 void *drawctx; 93 void *drawctx;
91 Eina_Bool ok; 94 Eina_Bool ok;
92 void *previous = pd->data->output; 95 void *previous = pd->data->output;
93 Evas_Object_Filter_Data *fcow = 96 Evas_Object_Filter_Data *fcow;
94 eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data)); 97 void *filter_output;
95 98
96 /* NOTE: Filter rendering is now done ENTIRELY on CPU. 99 /* NOTE: Filter rendering is now done ENTIRELY on CPU.
97 * So we rely on cache/cache2 to allocate a real image buffer, 100 * 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,
120 else 123 else
121 ENFN->context_multiplier_unset(output, context); 124 ENFN->context_multiplier_unset(output, context);
122 125
123 if (!fcow->chain) 126 if (!pd->data->chain)
124 { 127 {
125 Evas_Filter_Program *pgm; 128 Evas_Filter_Program *pgm;
126 pgm = evas_filter_program_new(fcow->name, alpha); 129 pgm = evas_filter_program_new(pd->data->name, alpha);
127 evas_filter_program_source_set_all(pgm, fcow->sources); 130 evas_filter_program_source_set_all(pgm, pd->data->sources);
128 evas_filter_program_data_set_all(pgm, fcow->data); 131 evas_filter_program_data_set_all(pgm, pd->data->data);
129 evas_filter_program_state_set(pgm, eo_obj, obj, 132 evas_filter_program_state_set(pgm, eo_obj, obj,
130 fcow->state.cur.name, fcow->state.cur.value, 133 pd->data->state.cur.name, pd->data->state.cur.value,
131 fcow->state.next.name, fcow->state.next.value, 134 pd->data->state.next.name, pd->data->state.next.value,
132 fcow->state.pos); 135 pd->data->state.pos);
133 if (!evas_filter_program_parse(pgm, fcow->code)) 136 if (!evas_filter_program_parse(pgm, pd->data->code))
134 { 137 {
135 ERR("Filter program parsing failed"); 138 ERR("Filter program parsing failed");
136 evas_filter_program_del(pgm); 139 evas_filter_program_del(pgm);
137 fcow->invalid = EINA_TRUE;
138 140
139 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data), 141 if (!pd->data->invalid)
140 fcow, EINA_TRUE); 142 {
143 fcow = FCOW_BEGIN(pd);
144 fcow->invalid = EINA_TRUE;
145 FCOW_END(fcow, pd);
146 }
147
141 return EINA_FALSE; 148 return EINA_FALSE;
142 } 149 }
150 fcow = FCOW_BEGIN(pd);
143 fcow->chain = pgm; 151 fcow->chain = pgm;
144 fcow->invalid = EINA_FALSE; 152 fcow->invalid = EINA_FALSE;
153 FCOW_END(fcow, pd);
145 } 154 }
146 else if (previous && !fcow->changed) 155 else if (previous && !pd->data->changed)
147 { 156 {
148 Eina_Bool redraw; 157 Eina_Bool redraw;
149 158
150 redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj, 159 redraw = evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
151 fcow->state.cur.name, fcow->state.cur.value, 160 pd->data->state.cur.name, pd->data->state.cur.value,
152 fcow->state.next.name, fcow->state.next.value, 161 pd->data->state.next.name, pd->data->state.next.value,
153 fcow->state.pos); 162 pd->data->state.pos);
154 if (redraw) 163 if (redraw)
155 DBG("Filter redraw by state change!"); 164 DBG("Filter redraw by state change!");
156 else if (obj->changed) 165 else if (obj->changed)
@@ -161,13 +170,13 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
161 } 170 }
162 171
163 // Scan proxies to find if any changed 172 // Scan proxies to find if any changed
164 if (!redraw && fcow->sources) 173 if (!redraw && pd->data->sources)
165 { 174 {
166 Evas_Filter_Proxy_Binding *pb; 175 Evas_Filter_Proxy_Binding *pb;
167 Evas_Object_Protected_Data *source; 176 Evas_Object_Protected_Data *source;
168 Eina_Iterator *iter; 177 Eina_Iterator *iter;
169 178
170 iter = eina_hash_iterator_data_new(fcow->sources); 179 iter = eina_hash_iterator_data_new(pd->data->sources);
171 EINA_ITERATOR_FOREACH(iter, pb) 180 EINA_ITERATOR_FOREACH(iter, pb)
172 { 181 {
173 source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS); 182 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,
189 X + x, Y + y, W, H, // dst 198 X + x, Y + y, W, H, // dst
190 EINA_FALSE, // smooth 199 EINA_FALSE, // smooth
191 do_async); 200 do_async);
192
193 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
194 fcow, EINA_TRUE);
195 return EINA_TRUE; 201 return EINA_TRUE;
196 } 202 }
197 } 203 }
198 else 204 else
199 evas_filter_program_state_set(fcow->chain, eo_obj, obj, 205 evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
200 fcow->state.cur.name, fcow->state.cur.value, 206 pd->data->state.cur.name, pd->data->state.cur.value,
201 fcow->state.next.name, fcow->state.next.value, 207 pd->data->state.next.name, pd->data->state.next.value,
202 fcow->state.pos); 208 pd->data->state.pos);
203 209
204 filter = evas_filter_context_new(obj->layer->evas, do_async); 210 filter = evas_filter_context_new(obj->layer->evas, do_async);
205 211
206 // Run script 212 // Run script
207 ok = evas_filter_context_program_use(filter, fcow->chain); 213 ok = evas_filter_context_program_use(filter, pd->data->chain);
208 if (!filter || !ok) 214 if (!filter || !ok)
209 { 215 {
210 ERR("Parsing failed?"); 216 ERR("Parsing failed?");
211 evas_filter_context_destroy(filter); 217 evas_filter_context_destroy(filter);
212 218
213 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data), 219 if (!pd->data->invalid)
214 fcow, EINA_TRUE); 220 {
221 fcow = FCOW_BEGIN(pd);
222 fcow->invalid = EINA_TRUE;
223 FCOW_END(fcow, pd);
224 }
215 return EINA_FALSE; 225 return EINA_FALSE;
216 } 226 }
217 227
@@ -227,12 +237,12 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
227 evas_filter_target_set(filter, context, surface, X + x, Y + y); 237 evas_filter_target_set(filter, context, surface, X + x, Y + y);
228 238
229 // Steal output and release previous 239 // Steal output and release previous
230 fcow->output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID); 240 filter_output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
231 if (fcow->output != previous) 241 if (filter_output != previous)
232 evas_filter_buffer_backing_release(filter, previous); 242 evas_filter_buffer_backing_release(filter, previous);
233 243
234 // Request rendering from the object itself (child class) 244 // Request rendering from the object itself (child class)
235 evas_filter_program_padding_get(fcow->chain, &l, &r, &t, &b); 245 evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
236 eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async)); 246 eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
237 247
238 ENFN->context_free(ENDT, drawctx); 248 ENFN->context_free(ENDT, drawctx);
@@ -240,10 +250,12 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
240 // Add post-run callback and run filter 250 // Add post-run callback and run filter
241 evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj); 251 evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
242 ok = evas_filter_run(filter); 252 ok = evas_filter_run(filter);
253
254 fcow = FCOW_BEGIN(pd);
255 fcow->output = filter_output;
243 fcow->changed = EINA_FALSE; 256 fcow->changed = EINA_FALSE;
244 if (!ok) fcow->invalid = EINA_TRUE; 257 if (!ok) fcow->invalid = EINA_TRUE;
245 258 FCOW_END(fcow, pd);
246 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data **) &(pd->data), fcow, EINA_TRUE);
247 259
248 if (ok) 260 if (ok)
249 { 261 {
@@ -265,6 +277,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
265{ 277{
266 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); 278 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
267 Evas_Filter_Program *pgm = NULL; 279 Evas_Filter_Program *pgm = NULL;
280 Evas_Object_Filter_Data *fcow;
268 Eina_Bool alpha; 281 Eina_Bool alpha;
269 282
270 if (!pd) return; 283 if (!pd) return;
@@ -273,7 +286,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
273 pd->data->name && name && !strcmp(name, pd->data->name)) return; 286 pd->data->name && name && !strcmp(name, pd->data->name)) return;
274 287
275 evas_object_async_block(obj); 288 evas_object_async_block(obj);
276 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow) 289 fcow = FCOW_BEGIN(pd);
277 { 290 {
278 // Parse filter program 291 // Parse filter program
279 evas_filter_program_del(fcow->chain); 292 evas_filter_program_del(fcow->chain);
@@ -300,7 +313,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
300 fcow->invalid = (pgm == NULL); 313 fcow->invalid = (pgm == NULL);
301 eina_stringshare_replace(&fcow->code, code); 314 eina_stringshare_replace(&fcow->code, code);
302 } 315 }
303 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow); 316 FCOW_END(fcow, pd);
304 317
305 // Update object 318 // Update object
306 eo_do(eo_obj, evas_filter_dirty()); 319 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,
347 if (pb_old && (pb_old->eo_source == eo_source)) return; 360 if (pb_old && (pb_old->eo_source == eo_source)) return;
348 } 361 }
349 362
350 fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data); 363 fcow = FCOW_BEGIN(pd);
351
352 if (!fcow->sources) 364 if (!fcow->sources)
353 fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb)); 365 fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb));
354 else if (pb_old) 366 else if (pb_old)
@@ -359,7 +371,7 @@ _evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
359 pb_old = eina_hash_find(fcow->sources, name); 371 pb_old = eina_hash_find(fcow->sources, name);
360 if (!pb_old) 372 if (!pb_old)
361 { 373 {
362 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE); 374 FCOW_END(fcow, pd);
363 return; 375 return;
364 } 376 }
365 eina_hash_del_by_key(fcow->sources, name); 377 eina_hash_del_by_key(fcow->sources, name);
@@ -395,7 +407,7 @@ update:
395 { 407 {
396 fcow->changed = EINA_TRUE; 408 fcow->changed = EINA_TRUE;
397 fcow->invalid = EINA_FALSE; 409 fcow->invalid = EINA_FALSE;
398 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE); 410 FCOW_END(fcow, pd);
399 } 411 }
400 412
401 eo_do(eo_obj, evas_filter_dirty()); 413 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,
426 (next_state != pd->data->state.next.name) || (next_val != pd->data->state.next.value) || 438 (next_state != pd->data->state.next.name) || (next_val != pd->data->state.next.value) ||
427 (pos != pd->data->state.pos)) 439 (pos != pd->data->state.pos))
428 { 440 {
429 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow) 441 Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
442 fcow->changed = 1;
443 fcow->state.cur.name = cur_state;
444 fcow->state.cur.value = cur_val;
445 fcow->state.next.name = next_state;
446 fcow->state.next.value = next_val;
447 fcow->state.pos = pos;
448 FCOW_END(fcow, pd);
449
450 if (pd->data->chain)
430 { 451 {
431 fcow->changed = 1; 452 evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
432 fcow->state.cur.name = cur_state; 453 pd->data->state.cur.name, pd->data->state.cur.value,
433 fcow->state.cur.value = cur_val; 454 pd->data->state.next.name, pd->data->state.next.value,
434 fcow->state.next.name = next_state; 455 pd->data->state.pos);
435 fcow->state.next.value = next_val;
436 fcow->state.pos = pos;
437
438 if (pd->data->chain)
439 {
440 evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
441 fcow->state.cur.name, fcow->state.cur.value,
442 fcow->state.next.name, fcow->state.next.value,
443 fcow->state.pos);
444 }
445 } 456 }
446 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
447 457
448 // Mark as changed 458 // Mark as changed
449 eo_do(eo_obj, evas_filter_dirty()); 459 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
474{ 484{
475 if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val)) 485 if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val))
476 { 486 {
477 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow) 487 Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
478 fcow->changed = val; 488 fcow->changed = val;
479 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow); 489 FCOW_END(fcow, pd);
480 } 490 }
481} 491}
482 492
@@ -485,9 +495,9 @@ _evas_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool
485{ 495{
486 if (pd->data->invalid != val) 496 if (pd->data->invalid != val)
487 { 497 {
488 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow) 498 Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
489 fcow->invalid = val; 499 fcow->invalid = val;
490 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow); 500 FCOW_END(fcow, pd);
491 } 501 }
492} 502}
493 503
@@ -527,6 +537,7 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
527 Eina_Bool execute) 537 Eina_Bool execute)
528{ 538{
529 Evas_Filter_Data_Binding *db, *found = NULL; 539 Evas_Filter_Data_Binding *db, *found = NULL;
540 Evas_Object_Filter_Data *fcow;
530 541
531 EINA_SAFETY_ON_NULL_RETURN(pd->data); 542 EINA_SAFETY_ON_NULL_RETURN(pd->data);
532 EINA_SAFETY_ON_NULL_RETURN(name); 543 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,
545 } 556 }
546 } 557 }
547 558
548 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow) 559 fcow = FCOW_BEGIN(pd);
549 { 560 {
550 if (found) 561 if (found)
551 { 562 {
@@ -564,7 +575,7 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
564 evas_filter_program_data_set_all(fcow->chain, fcow->data); 575 evas_filter_program_data_set_all(fcow->chain, fcow->data);
565 fcow->changed = 1; 576 fcow->changed = 1;
566 } 577 }
567 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow); 578 FCOW_END(fcow, pd);
568} 579}
569 580
570#include "evas_filter.eo.c" 581#include "evas_filter.eo.c"