summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-10-22 11:27:11 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-10-22 13:00:20 +0900
commitb5ccb00ba79b7b03949b664e7e7ac0fa2eec9c53 (patch)
treec11d7f131313beef992f308c10ace6318e176ade
parent6935880171c4d5d75c5944ec2e85720939c1ad26 (diff)
downloadefl-b5ccb00ba79b7b03949b664e7e7ac0fa2eec9c53.tar.gz
Evas filters: Feed some cow to the image objects
Same as for the text objects. Fixes T1725. Cedric, please run again your memory test, please.
-rw-r--r--src/lib/evas/canvas/evas_object_image.c210
1 files changed, 109 insertions, 101 deletions
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 1ec2377311..fccf9ed498 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -86,15 +86,7 @@ struct _Evas_Object_Image_State
Evas_Colorspace cspace;
- struct {
- Eina_Stringshare *code;
- Evas_Filter_Program *chain;
- Eina_Hash *sources; // Evas_Filter_Proxy_Binding
- int sources_count;
- void *output;
- Eina_Bool changed : 1;
- Eina_Bool invalid : 1; // Code parse failed
- } filter;
+ const Evas_Object_Filter_Data *filter;
Eina_Bool smooth_scale : 1;
Eina_Bool has_alpha :1;
@@ -238,9 +230,7 @@ static const Evas_Object_Image_State default_state = {
0, //frame
EVAS_TEXTURE_REPEAT,
EVAS_COLORSPACE_ARGB8888,
-
- // filter
- { NULL, NULL, NULL, 0, NULL, EINA_FALSE, EINA_FALSE },
+ NULL, // filter
// flags
EINA_TRUE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
@@ -269,6 +259,12 @@ Eina_Cow *evas_object_image_state_cow = NULL;
# define EINA_COW_IMAGE_STATE_WRITE_END(Obj, Write) \
EINA_COW_WRITE_END(evas_object_image_state_cow, Obj->cur, Write)
+# define EINA_COW_IMAGE_FILTER_WRITE_BEGIN(State, Write) \
+ EINA_COW_WRITE_BEGIN(evas_object_filter_cow, State->filter, Evas_Object_Filter_Data, Write)
+
+# define EINA_COW_IMAGE_FILTER_WRITE_END(State, Write) \
+ EINA_COW_WRITE_END(evas_object_filter_cow, State->filter, Write)
+
# define EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(Obj) \
if ((!Obj->cur->mmaped_source && Obj->cur->u.file) || Obj->cur->key) \
{ \
@@ -3023,7 +3019,9 @@ _filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
ERR("Filter failed at runtime!");
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- state_write->filter.invalid = EINA_TRUE;
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ fcow->invalid = EINA_TRUE;
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
// Update object
@@ -3221,25 +3219,25 @@ start_draw:
* - If filled, then scale down the image to accomodate the whole filter's padding.
* - Otherwise, draw image in place and clip the filter's effects (eg. blur will be clipped out).
*/
- if (!o->cur->filter.invalid && o->cur->filter.code)
+ if (!o->cur->filter->invalid && o->cur->filter->code)
{
- Evas_Filter_Program *pgm = o->cur->filter.chain;;
- Eina_Bool redraw = (o->changed || o->cur->filter.changed);
+ Evas_Filter_Program *pgm = o->cur->filter->chain;
+ Eina_Bool redraw = (o->changed || o->cur->filter->changed);
Eina_Bool ok;
evas_filter_program_padding_get(pgm, &l, &r, &t, &b);
W = obj->cur->geometry.w;
H = obj->cur->geometry.h;
- if (!redraw && o->cur->filter.output)
+ if (!redraw && o->cur->filter->output)
{
- if (o->cur->filter.sources && o->cur->filter.sources_count > 0)
+ if (o->cur->filter->sources && o->cur->filter->sources_count > 0)
{
Evas_Filter_Proxy_Binding *pb;
Evas_Object_Protected_Data *prxsource;
Eina_Iterator *iter;
- iter = eina_hash_iterator_data_new(o->cur->filter.sources);
+ iter = eina_hash_iterator_data_new(o->cur->filter->sources);
EINA_ITERATOR_FOREACH(iter, pb)
{
prxsource = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
@@ -3256,7 +3254,7 @@ start_draw:
{
// Render this image only
obj->layer->evas->engine.func->image_draw(output, context,
- surface, o->cur->filter.output,
+ surface, o->cur->filter->output,
0, 0, W, H,
offx, offy, W, H,
EINA_TRUE,
@@ -3268,8 +3266,8 @@ start_draw:
if (!pgm)
{
pgm = evas_filter_program_new("Image", EINA_FALSE);
- evas_filter_program_source_set_all(pgm, o->cur->filter.sources);
- ok = evas_filter_program_parse(pgm, o->cur->filter.code);
+ evas_filter_program_source_set_all(pgm, o->cur->filter->sources);
+ ok = evas_filter_program_parse(pgm, o->cur->filter->code);
if (!ok) goto state_write;
}
@@ -3307,7 +3305,9 @@ state_write:
{
context = obj->layer->evas->engine.func->context_new(output);
clear = EINA_TRUE;
- state_write->filter.chain = pgm;
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ fcow->chain = pgm;
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
if (!o->filled)
{
offx = 0;
@@ -3324,8 +3324,10 @@ state_write:
ERR("Failed to apply this filter");
evas_filter_context_destroy(filter);
evas_filter_program_del(pgm);
- state_write->filter.invalid = EINA_TRUE;
- state_write->filter.chain = NULL;
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ fcow->invalid = EINA_TRUE;
+ fcow->chain = NULL;
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
l = r = t = b = 0;
filter = NULL;
}
@@ -3571,50 +3573,53 @@ state_write:
/* Evas filters wrap-up */
if (filter)
{
- Eina_Bool ok;
-
- void *outbuf = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
- if (outbuf != o->cur->filter.output)
- {
- evas_filter_buffer_backing_release(filter, o->cur->filter.output);
- EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- state_write->filter.output = outbuf;
- EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
- }
+ Eina_Bool ok = EINA_FALSE;
- if (!input_stolen)
- evas_filter_image_draw(filter, context, EVAS_FILTER_BUFFER_INPUT_ID, surface, do_async);
- else
- evas_filter_buffer_backing_release(filter, surface);
-
- evas_filter_target_set(filter, context_save, surface_save, obj->cur->geometry.x + x, obj->cur->geometry.y + y);
- evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
- ok = evas_filter_run(filter);
+ EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ {
- if (!input_stolen)
- obj->layer->evas->engine.func->image_map_surface_free(output, surface);
- obj->layer->evas->engine.func->context_free(output, context);
+ void *outbuf = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
+ if (outbuf != fcow->output)
+ {
+ evas_filter_buffer_backing_release(filter, fcow->output);
+ fcow->output = outbuf;
+ }
+
+ if (!input_stolen)
+ evas_filter_image_draw(filter, context, EVAS_FILTER_BUFFER_INPUT_ID, surface, do_async);
+ else
+ evas_filter_buffer_backing_release(filter, surface);
+
+ evas_filter_target_set(filter, context_save, surface_save, obj->cur->geometry.x + x, obj->cur->geometry.y + y);
+ evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
+ ok = evas_filter_run(filter);
+
+ if (!input_stolen)
+ obj->layer->evas->engine.func->image_map_surface_free(output, surface);
+ obj->layer->evas->engine.func->context_free(output, context);
+
+ if (!ok)
+ {
+ ERR("Rendering failed");
+ fcow->invalid = EINA_TRUE;
+ l = r = t = b = 0;
+ context = context_save;
+ surface = surface_save;
+ input_stolen = EINA_FALSE;
+ clear = EINA_FALSE;
+ filter = NULL;
+ }
+ else
+ {
+ fcow->changed = EINA_FALSE;
+ }
+ }
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
+ EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
if (!ok)
- {
- ERR("Rendering failed");
- EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- state_write->filter.invalid = EINA_TRUE;
- EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
- l = r = t = b = 0;
- context = context_save;
- surface = surface_save;
- input_stolen = EINA_FALSE;
- clear = EINA_FALSE;
- filter = NULL;
- goto start_draw;
- }
- else
- {
- EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- state_write->filter.changed = EINA_FALSE;
- EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
- }
+ goto start_draw;
}
}
}
@@ -3775,7 +3780,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done;
}
- if (o->cur->filter.changed)
+ if (o->cur->filter && o->cur->filter->changed)
{
evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
if (!o->pixels->pixel_updates) goto done;
@@ -4780,30 +4785,35 @@ _evas_image_filter_program_set(Eo *eo_obj, Evas_Image_Data *o, const char *arg)
Evas_Filter_Program *pgm = NULL;
if (!o) return;
- if (o->cur->filter.code == arg) return;
- if (o->cur->filter.code && arg && !strcmp(arg, o->cur->filter.code)) return;
-
- // Parse filter program
- evas_filter_program_del(o->cur->filter.chain);
- if (arg)
+ if (o->cur->filter)
{
- pgm = evas_filter_program_new("Evas_Text: Filter Program", EINA_FALSE);
- evas_filter_program_source_set_all(pgm, o->cur->filter.sources);
- if (!evas_filter_program_parse(pgm, arg))
- {
- ERR("Parsing failed!");
- evas_filter_program_del(pgm);
- pgm = NULL;
- }
+ if (o->cur->filter->code == arg) return;
+ if (o->cur->filter->code && arg && !strcmp(arg, o->cur->filter->code)) return;
}
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
{
- state_write->filter.chain = pgm;
- state_write->filter.changed = EINA_TRUE;
- state_write->filter.invalid = (pgm == NULL);
- eina_stringshare_replace(&state_write->filter.code, arg);
+ // Parse filter program
+ evas_filter_program_del(fcow->chain);
+ if (arg)
+ {
+ pgm = evas_filter_program_new("Evas_Text: Filter Program", EINA_FALSE);
+ evas_filter_program_source_set_all(pgm, fcow->sources);
+ if (!evas_filter_program_parse(pgm, arg))
+ {
+ ERR("Parsing failed!");
+ evas_filter_program_del(pgm);
+ pgm = NULL;
+ }
+ }
+
+ fcow->chain = pgm;
+ fcow->changed = EINA_TRUE;
+ fcow->invalid = (pgm == NULL);
+ eina_stringshare_replace(&fcow->code, arg);
}
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
// Update object
@@ -4835,10 +4845,12 @@ _filter_source_hash_free_cb(void *data)
if (o && proxy)
{
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- state_write->filter.sources_count--;
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ fcow->sources_count--;
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
- if (!o->cur->filter.sources_count)
+ if (!o->cur->filter->sources_count)
{
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
Evas_Object_Proxy_Data, proxy_write)
@@ -4857,19 +4869,18 @@ _evas_image_filter_source_set(Eo *eo_obj, Evas_Image_Data *o, const char *name,
{
Evas_Object_Protected_Data *obj;
- Evas_Filter_Program *pgm = o->cur->filter.chain;
+ Evas_Filter_Program *pgm = o->cur->filter->chain;
Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
Evas_Object_Protected_Data *source = NULL;
- Eina_Hash *sources = o->cur->filter.sources;
- int sources_count = o->cur->filter.sources_count;
+ Eina_Hash *sources = o->cur->filter->sources;
obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
if (eo_source) source = eo_data_scope_get(eo_source, EVAS_OBJECT_CLASS);
if (!name)
{
- if (!eo_source || !o->cur->filter.sources) return;
- if (eina_hash_del_by_data(o->cur->filter.sources, eo_source))
+ if (!eo_source || !o->cur->filter->sources) return;
+ if (eina_hash_del_by_data(o->cur->filter->sources, eo_source))
goto update;
return;
}
@@ -4915,18 +4926,15 @@ _evas_image_filter_source_set(Eo *eo_obj, Evas_Image_Data *o, const char *name,
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
eina_hash_add(sources, pb->name, pb);
- sources_count++;
-
evas_filter_program_source_set_all(pgm, sources);
update:
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
- {
- state_write->filter.changed = EINA_TRUE;
- state_write->filter.invalid = EINA_FALSE;
- state_write->filter.sources = sources;
- state_write->filter.sources_count = sources_count;
- }
+ EINA_COW_IMAGE_FILTER_WRITE_BEGIN(state_write, fcow)
+ fcow->changed = EINA_TRUE;
+ fcow->invalid = EINA_FALSE;
+ fcow->sources = sources;
+ EINA_COW_IMAGE_FILTER_WRITE_END(state_write, fcow)
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
// Update object
@@ -4941,13 +4949,13 @@ EOLIAN Eina_Bool
_evas_image_filter_padding_get(Eo *obj EINA_UNUSED, Evas_Image_Data *o,
int *l, int *r, int *t, int *b)
{
- Evas_Filter_Program *pgm = o->cur->filter.chain;
+ Evas_Filter_Program *pgm = o->cur->filter->chain;
int pl = 0, pr = 0, pt = 0, pb = 0;
Eina_Bool used = EINA_FALSE;
if (pgm)
{
- used = !o->cur->filter.invalid;
+ used = !o->cur->filter->invalid;
evas_filter_program_padding_get(pgm, &pl, &pr, &pt, &pb);
}