diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-07-28 14:17:53 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-07-28 17:13:52 +0900 |
commit | 0058cd08f4adfc0db4d29355d055d1748d28b903 (patch) | |
tree | 5c8ea742a4fc389d3ce543b1ed43d1fcb6e0b5a4 /src/lib | |
parent | f9c7d25b0845ab0c99cee402700d046ae318da39 (diff) |
Evas filters: Fix COW usage in filter mixin
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/evas/canvas/evas_filter_mixin.c | 141 |
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 | |||
79 | Eina_Bool | 82 | Eina_Bool |
80 | evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | 83 | evas_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" |