diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-05-26 16:12:00 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-06-25 14:36:08 +0900 |
commit | d148c0f0d233900061ba27691881af073b4f0f63 (patch) | |
tree | 01e9a8c5f67fe08418e6f9b24380badaa5a5944d | |
parent | ed09b3af6db3db98630b365fe557fa7235d2988d (diff) |
Evas filters: Fix runtime, allow state change on the fly
Now we're ready to implement runtime changes to the filters'
state (color classes, edje state, etc...), as the Lua function
will be run whenver required.
-rw-r--r-- | src/lib/evas/canvas/evas_object_text.c | 1 | ||||
-rw-r--r-- | src/lib/evas/filters/evas_filter.c | 12 | ||||
-rw-r--r-- | src/lib/evas/filters/evas_filter_parser.c | 93 | ||||
-rw-r--r-- | src/lib/evas/include/evas_filter.h | 1 |
4 files changed, 58 insertions, 49 deletions
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c index 42620cb347..ba63da4262 100644 --- a/src/lib/evas/canvas/evas_object_text.c +++ b/src/lib/evas/canvas/evas_object_text.c | |||
@@ -1836,7 +1836,6 @@ evas_object_text_render(Evas_Object *eo_obj, | |||
1836 | } | 1836 | } |
1837 | 1837 | ||
1838 | filter = evas_filter_context_new(obj->layer->evas, do_async); | 1838 | filter = evas_filter_context_new(obj->layer->evas, do_async); |
1839 | evas_filter_program_run(fcow->chain); | ||
1840 | ok = evas_filter_context_program_use(filter, fcow->chain); | 1839 | ok = evas_filter_context_program_use(filter, fcow->chain); |
1841 | if (!filter || !ok) | 1840 | if (!filter || !ok) |
1842 | { | 1841 | { |
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 295c2585f4..f8aebb86bb 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c | |||
@@ -364,7 +364,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
364 | 364 | ||
365 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); | 365 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); |
366 | w = ctx->w; | 366 | w = ctx->w; |
367 | h = ctx->w; | 367 | h = ctx->h; |
368 | 368 | ||
369 | //DBG("Allocating all buffers based on output size %ux%u", w, h); | 369 | //DBG("Allocating all buffers based on output size %ux%u", w, h); |
370 | 370 | ||
@@ -409,7 +409,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
409 | if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) | 409 | if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) |
410 | sh = h; | 410 | sh = h; |
411 | 411 | ||
412 | //DBG("Allocating temporary buffer of size %ux%u", sw, sh); | 412 | //DBG("Allocating temporary buffer of size %ux%u %s", sw, sh, in->alpha_only ? "alpha" : "rgba"); |
413 | fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); | 413 | fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); |
414 | if (!fb) goto alloc_fail; | 414 | if (!fb) goto alloc_fail; |
415 | fb->transient = EINA_TRUE; | 415 | fb->transient = EINA_TRUE; |
@@ -424,7 +424,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
424 | if (in->w) sw = in->w; | 424 | if (in->w) sw = in->w; |
425 | if (in->h) sh = in->h; | 425 | if (in->h) sh = in->h; |
426 | 426 | ||
427 | //DBG("Allocating temporary buffer of size %ux%u", sw, sh); | 427 | //DBG("Allocating temporary buffer of size %ux%u %s", sw, sh, in->alpha_only ? "alpha" : "rgba"); |
428 | fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); | 428 | fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); |
429 | if (!fb) goto alloc_fail; | 429 | if (!fb) goto alloc_fail; |
430 | fb->transient = EINA_TRUE; | 430 | fb->transient = EINA_TRUE; |
@@ -464,7 +464,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
464 | continue; | 464 | continue; |
465 | } | 465 | } |
466 | 466 | ||
467 | //DBG("Allocating buffer of size %ux%u alpha %d", fb->w, fb->h, fb->alpha_only); | 467 | //DBG("Allocating buffer of size %ux%u %s", fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba"); |
468 | im = _rgba_image_alloc(fb, NULL); | 468 | im = _rgba_image_alloc(fb, NULL); |
469 | if (!im) goto alloc_fail; | 469 | if (!im) goto alloc_fail; |
470 | 470 | ||
@@ -741,8 +741,12 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, | |||
741 | Evas_Filter_Buffer *buf = NULL; | 741 | Evas_Filter_Buffer *buf = NULL; |
742 | Eina_List *l; | 742 | Eina_List *l; |
743 | 743 | ||
744 | DBG("Want temp buffer: %dx%d %s", w, h, alpha_only ? "alpha" : "rgba"); | ||
744 | EINA_LIST_FOREACH(ctx->buffers, l, buf) | 745 | EINA_LIST_FOREACH(ctx->buffers, l, buf) |
745 | { | 746 | { |
747 | DBG("Try buffer #%d: temp:%d %dx%d %s (lock:%d)", | ||
748 | buf->id, buf->transient, | ||
749 | buf->w, buf->h, buf->alpha_only ? "alpha" : "rgba", buf->locked); | ||
746 | if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only)) | 750 | if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only)) |
747 | { | 751 | { |
748 | if ((!w || (w == buf->w)) | 752 | if ((!w || (w == buf->w)) |
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index 6b661aa3e4..426e31c195 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c | |||
@@ -332,6 +332,7 @@ struct _Evas_Filter_Program | |||
332 | } pad; | 332 | } pad; |
333 | int w, h; | 333 | int w, h; |
334 | lua_State *L; | 334 | lua_State *L; |
335 | int lua_func; | ||
335 | Eina_Bool valid : 1; | 336 | Eina_Bool valid : 1; |
336 | Eina_Bool padding_calc : 1; // Padding has been calculated | 337 | Eina_Bool padding_calc : 1; // Padding has been calculated |
337 | Eina_Bool padding_set : 1; // Padding has been forced | 338 | Eina_Bool padding_set : 1; // Padding has been forced |
@@ -2311,7 +2312,11 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str) | |||
2311 | #endif | 2312 | #endif |
2312 | 2313 | ||
2313 | if (ok) | 2314 | if (ok) |
2314 | ok = !lua_pcall(L, 0, LUA_MULTRET, 0); | 2315 | { |
2316 | pgm->lua_func = luaL_ref(L, LUA_REGISTRYINDEX); | ||
2317 | lua_rawgeti(L, LUA_REGISTRYINDEX, pgm->lua_func); | ||
2318 | ok = !lua_pcall(L, 0, LUA_MULTRET, 0); | ||
2319 | } | ||
2315 | 2320 | ||
2316 | if (!ok) | 2321 | if (!ok) |
2317 | { | 2322 | { |
@@ -2335,29 +2340,45 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str) | |||
2335 | 2340 | ||
2336 | /** Run a program, must be already loaded */ | 2341 | /** Run a program, must be already loaded */ |
2337 | 2342 | ||
2338 | EAPI Eina_Bool | 2343 | static void |
2339 | evas_filter_program_run(Evas_Filter_Program *pgm) | 2344 | _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm) |
2340 | { | 2345 | { |
2341 | Eina_Bool ok; | 2346 | Evas_Object_Protected_Data *source; |
2347 | Evas_Filter_Proxy_Binding *pb; | ||
2348 | Evas_Filter_Buffer *fb; | ||
2349 | Buffer *buf; | ||
2342 | 2350 | ||
2343 | EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE); | 2351 | EINA_INLIST_FOREACH(pgm->buffers, buf) |
2344 | if (!pgm->L) | ||
2345 | { | 2352 | { |
2346 | ERR("Lua state is not set. Something is wrong."); | 2353 | if (buf->proxy) |
2347 | return EINA_FALSE; | 2354 | { |
2348 | } | 2355 | pb = eina_hash_find(pgm->proxies, buf->proxy); |
2356 | if (!pb) continue; | ||
2349 | 2357 | ||
2350 | if (!pgm->changed) | 2358 | buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); |
2351 | return EINA_TRUE; | 2359 | fb = _filter_buffer_get(ctx, buf->cid); |
2360 | fb->proxy = pb->eo_proxy; | ||
2361 | fb->source = pb->eo_source; | ||
2362 | fb->source_name = eina_stringshare_ref(pb->name); | ||
2363 | fb->ctx->has_proxies = EINA_TRUE; | ||
2352 | 2364 | ||
2353 | ok = !lua_pcall(pgm->L, 0, LUA_MULTRET, 0); | 2365 | source = eo_data_scope_get(fb->source, EVAS_OBJECT_CLASS); |
2354 | if (!ok) | 2366 | if ((source->cur->geometry.w != buf->w) || |
2355 | { | 2367 | (source->cur->geometry.h != buf->h)) |
2356 | const char *msg = lua_tostring(pgm->L, -1); | 2368 | pgm->changed = EINA_TRUE; |
2357 | ERR("Lua execution failed: %s", msg); | 2369 | buf->w = fb->w = source->cur->geometry.w; |
2370 | buf->h = fb->h = source->cur->geometry.h; | ||
2371 | } | ||
2372 | else | ||
2373 | { | ||
2374 | if ((buf->w != pgm->w) || (buf->h != pgm->h)) | ||
2375 | pgm->changed = EINA_TRUE; | ||
2376 | buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); | ||
2377 | fb = _filter_buffer_get(ctx, buf->cid); | ||
2378 | fb->w = buf->w = pgm->w; | ||
2379 | fb->h = buf->h = pgm->h; | ||
2380 | } | ||
2358 | } | 2381 | } |
2359 | |||
2360 | return ok; | ||
2361 | } | 2382 | } |
2362 | 2383 | ||
2363 | /** Evaluate required padding to correctly apply an effect */ | 2384 | /** Evaluate required padding to correctly apply an effect */ |
@@ -2973,7 +2994,6 @@ Eina_Bool | |||
2973 | evas_filter_context_program_use(Evas_Filter_Context *ctx, | 2994 | evas_filter_context_program_use(Evas_Filter_Context *ctx, |
2974 | Evas_Filter_Program *pgm) | 2995 | Evas_Filter_Program *pgm) |
2975 | { | 2996 | { |
2976 | Buffer *buf; | ||
2977 | Evas_Filter_Instruction *instr; | 2997 | Evas_Filter_Instruction *instr; |
2978 | Eina_Bool success = EINA_FALSE; | 2998 | Eina_Bool success = EINA_FALSE; |
2979 | void *dc = NULL; | 2999 | void *dc = NULL; |
@@ -2991,34 +3011,20 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, | |||
2991 | 3011 | ||
2992 | // Create empty context with all required buffers | 3012 | // Create empty context with all required buffers |
2993 | evas_filter_context_clear(ctx); | 3013 | evas_filter_context_clear(ctx); |
2994 | EINA_INLIST_FOREACH(pgm->buffers, buf) | 3014 | _buffers_update(ctx, pgm); |
2995 | { | ||
2996 | buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); | ||
2997 | if (buf->proxy) | ||
2998 | { | ||
2999 | Evas_Object_Protected_Data *source; | ||
3000 | Evas_Filter_Proxy_Binding *pb; | ||
3001 | Evas_Filter_Buffer *fb; | ||
3002 | 3015 | ||
3003 | pb = eina_hash_find(pgm->proxies, buf->proxy); | 3016 | if (pgm->changed) |
3004 | if (!pb) continue; | 3017 | { |
3005 | 3018 | lua_rawgeti(pgm->L, LUA_REGISTRYINDEX, pgm->lua_func); | |
3006 | fb = _filter_buffer_get(ctx, buf->cid); | 3019 | success = !lua_pcall(pgm->L, 0, LUA_MULTRET, 0); |
3007 | fb->proxy = pb->eo_proxy; | 3020 | if (!success) |
3008 | fb->source = pb->eo_source; | ||
3009 | fb->source_name = eina_stringshare_ref(pb->name); | ||
3010 | fb->ctx->has_proxies = EINA_TRUE; | ||
3011 | |||
3012 | source = eo_data_scope_get(fb->source, EVAS_OBJECT_CLASS); | ||
3013 | fb->w = source->cur->geometry.w; | ||
3014 | fb->h = source->cur->geometry.h; | ||
3015 | } | ||
3016 | else | ||
3017 | { | 3021 | { |
3018 | buf->w = ctx->w; | 3022 | const char *msg = lua_tostring(pgm->L, -1); |
3019 | buf->h = ctx->h; | 3023 | ERR("Lua execution failed: %s", msg); |
3024 | goto end; | ||
3020 | } | 3025 | } |
3021 | } | 3026 | } |
3027 | pgm->changed = EINA_FALSE; | ||
3022 | 3028 | ||
3023 | // Compute and save padding info | 3029 | // Compute and save padding info |
3024 | evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb); | 3030 | evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb); |
@@ -3036,6 +3042,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, | |||
3036 | } | 3042 | } |
3037 | 3043 | ||
3038 | success = EINA_TRUE; | 3044 | success = EINA_TRUE; |
3045 | pgm->changed = EINA_FALSE; | ||
3039 | 3046 | ||
3040 | end: | 3047 | end: |
3041 | if (!success) evas_filter_context_clear(ctx); | 3048 | if (!success) evas_filter_context_clear(ctx); |
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index c537ae288c..d4f9f47b10 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h | |||
@@ -125,7 +125,6 @@ enum _Evas_Filter_Transform_Flags | |||
125 | 125 | ||
126 | /* Parser stuff (high level API) */ | 126 | /* Parser stuff (high level API) */ |
127 | EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha); | 127 | EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha); |
128 | EAPI Eina_Bool evas_filter_program_run(Evas_Filter_Program *pgm); | ||
129 | EAPI void evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h); | 128 | EAPI void evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h); |
130 | EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); | 129 | EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); |
131 | EAPI void evas_filter_program_del(Evas_Filter_Program *pgm); | 130 | EAPI void evas_filter_program_del(Evas_Filter_Program *pgm); |