summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-05-18 17:35:49 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-06-25 14:36:08 +0900
commit2faaef966e41b35656fd77be94701009ad183c42 (patch)
tree542c31634a984e0534a8b92095899bfa32e0f610 /src
parent6db0ff42291ff4c44815df3a5f77c31ae1bad1ac (diff)
Evas filters: Add internal function _program_run
This will allow changing the state of the filter and re-run it without re-creating the Lua_State object. This is to handle size, color, animation state and scale changes (amongst other things).
Diffstat (limited to 'src')
-rw-r--r--src/lib/evas/canvas/evas_object_image.c2
-rw-r--r--src/lib/evas/canvas/evas_object_text.c8
-rw-r--r--src/lib/evas/filters/evas_filter.c16
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c76
-rw-r--r--src/lib/evas/include/evas_filter.h4
5 files changed, 86 insertions, 20 deletions
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index b2f8b95..a272206 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -3315,7 +3315,7 @@ start_draw:
3315 if (!ok) goto state_write; 3315 if (!ok) goto state_write;
3316 3316
3317 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE); 3317 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
3318 ok = evas_filter_context_buffers_allocate_all(filter, W, H); 3318 ok = evas_filter_context_buffers_allocate_all(filter);
3319 if (!ok) goto state_write; 3319 if (!ok) goto state_write;
3320 3320
3321 if (ENFN->gl_surface_read_pixels) 3321 if (ENFN->gl_surface_read_pixels)
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c
index d7ee55e..42620cb 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -1760,7 +1760,6 @@ evas_object_text_render(Evas_Object *eo_obj,
1760 * image to GL. 1760 * image to GL.
1761 */ 1761 */
1762 1762
1763
1764 W = obj->cur->geometry.w; 1763 W = obj->cur->geometry.w;
1765 H = obj->cur->geometry.h; 1764 H = obj->cur->geometry.h;
1766 X = obj->cur->geometry.x; 1765 X = obj->cur->geometry.x;
@@ -1837,6 +1836,7 @@ evas_object_text_render(Evas_Object *eo_obj,
1837 } 1836 }
1838 1837
1839 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); 1840 ok = evas_filter_context_program_use(filter, fcow->chain);
1841 if (!filter || !ok) 1841 if (!filter || !ok)
1842 { 1842 {
@@ -1856,7 +1856,7 @@ evas_object_text_render(Evas_Object *eo_obj,
1856 ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255); 1856 ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
1857 1857
1858 // Allocate all buffers now 1858 // Allocate all buffers now
1859 evas_filter_context_buffers_allocate_all(filter, W, H); 1859 evas_filter_context_buffers_allocate_all(filter);
1860 evas_filter_target_set(filter, context, surface, X + x, Y + y); 1860 evas_filter_target_set(filter, context, surface, X + x, Y + y);
1861 1861
1862 // Steal output and release previous 1862 // Steal output and release previous
@@ -2379,7 +2379,6 @@ EOLIAN static void
2379_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg) 2379_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
2380{ 2380{
2381 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); 2381 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
2382
2383 Evas_Filter_Program *pgm = NULL; 2382 Evas_Filter_Program *pgm = NULL;
2384 2383
2385 if (!o) return; 2384 if (!o) return;
@@ -2393,8 +2392,9 @@ _evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
2393 evas_filter_program_del(fcow->chain); 2392 evas_filter_program_del(fcow->chain);
2394 if (arg) 2393 if (arg)
2395 { 2394 {
2396 pgm = evas_filter_program_new("Evas_Text: Filter Program", EINA_TRUE); 2395 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
2397 evas_filter_program_source_set_all(pgm, fcow->sources); 2396 evas_filter_program_source_set_all(pgm, fcow->sources);
2397 evas_filter_program_state_set(pgm, obj->cur->geometry.w, obj->cur->geometry.h);
2398 if (!evas_filter_program_parse(pgm, arg)) 2398 if (!evas_filter_program_parse(pgm, arg))
2399 { 2399 {
2400 ERR("Parsing failed!"); 2400 ERR("Parsing failed!");
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 0f24870..523018f 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -22,6 +22,8 @@
22# include "evas_cs2_private.h" 22# include "evas_cs2_private.h"
23#endif 23#endif
24 24
25#define _assert(a) if (!(a)) CRI("Failed on %s", #a);
26
25static void _buffer_free(Evas_Filter_Buffer *fb); 27static void _buffer_free(Evas_Filter_Buffer *fb);
26static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); 28static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
27static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data); 29static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data);
@@ -205,13 +207,13 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
205 { 207 {
206 // TODO: Lock current object as proxyrendering (see image obj) 208 // TODO: Lock current object as proxyrendering (see image obj)
207 source = eo_data_scope_get(fb->source, EVAS_OBJECT_CLASS); 209 source = eo_data_scope_get(fb->source, EVAS_OBJECT_CLASS);
210 _assert(fb->w == source->cur->geometry.w);
211 _assert(fb->h == source->cur->geometry.h);
208 if (source->proxy->surface && !source->proxy->redraw) 212 if (source->proxy->surface && !source->proxy->redraw)
209 { 213 {
210 DBG("Source already rendered: '%s' of type '%s'", 214 DBG("Source already rendered: '%s' of type '%s'",
211 fb->source_name, eo_class_name_get(eo_class_get(fb->source))); 215 fb->source_name, eo_class_name_get(eo_class_get(fb->source)));
212 _filter_buffer_backing_free(fb); 216 _filter_buffer_backing_free(fb);
213 fb->w = source->cur->geometry.w;
214 fb->h = source->cur->geometry.h;
215 if (!ctx->gl_engine) 217 if (!ctx->gl_engine)
216 { 218 {
217 fb->backing = source->proxy->surface; 219 fb->backing = source->proxy->surface;
@@ -232,8 +234,6 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
232 source->proxy->redraw ? "redraw" : "no surface"); 234 source->proxy->redraw ? "redraw" : "no surface");
233 evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async); 235 evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
234 _filter_buffer_backing_free(fb); 236 _filter_buffer_backing_free(fb);
235 fb->w = source->cur->geometry.w;
236 fb->h = source->cur->geometry.h;
237 if (!ctx->gl_engine) 237 if (!ctx->gl_engine)
238 { 238 {
239 fb->backing = source->proxy->surface; 239 fb->backing = source->proxy->surface;
@@ -355,16 +355,16 @@ _rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
355} 355}
356 356
357Eina_Bool 357Eina_Bool
358evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, 358evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
359 unsigned w, unsigned h)
360{ 359{
361 Evas_Filter_Command *cmd; 360 Evas_Filter_Command *cmd;
362 Evas_Filter_Buffer *fb; 361 Evas_Filter_Buffer *fb;
363 Eina_List *li; 362 Eina_List *li;
363 unsigned w, h;
364 364
365 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 365 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
366 ctx->w = w; 366 w = ctx->w;
367 ctx->h = h; 367 h = ctx->w;
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
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index 692afc9..1f9f9d3 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -282,6 +282,7 @@ typedef struct _Buffer
282 struct { 282 struct {
283 int l, r, t, b; // Used for padding calculation. Can change over time. 283 int l, r, t, b; // Used for padding calculation. Can change over time.
284 } pad; 284 } pad;
285 int w, h;
285 Eina_Bool alpha : 1; 286 Eina_Bool alpha : 1;
286} Buffer; 287} Buffer;
287 288
@@ -320,9 +321,12 @@ struct _Evas_Filter_Program
320 struct { 321 struct {
321 int l, r, t, b; 322 int l, r, t, b;
322 } pad; 323 } pad;
324 int w, h;
325 lua_State *L;
323 Eina_Bool valid : 1; 326 Eina_Bool valid : 1;
324 Eina_Bool padding_calc : 1; // Padding has been calculated 327 Eina_Bool padding_calc : 1; // Padding has been calculated
325 Eina_Bool padding_set : 1; // Padding has been forced 328 Eina_Bool padding_set : 1; // Padding has been forced
329 Eina_Bool changed : 1; // State (w,h) changed, needs re-run of Lua
326}; 330};
327 331
328/* Instructions */ 332/* Instructions */
@@ -1568,6 +1572,9 @@ evas_filter_program_del(Evas_Filter_Program *pgm)
1568 1572
1569 if (!pgm) return; 1573 if (!pgm) return;
1570 1574
1575 if (pgm->L)
1576 lua_close(pgm->L);
1577
1571 EINA_INLIST_FREE(pgm->buffers, buf) 1578 EINA_INLIST_FREE(pgm->buffers, buf)
1572 { 1579 {
1573 pgm->buffers = eina_inlist_remove(pgm->buffers, EINA_INLIST_GET(buf)); 1580 pgm->buffers = eina_inlist_remove(pgm->buffers, EINA_INLIST_GET(buf));
@@ -1679,7 +1686,7 @@ fail:
1679} 1686}
1680 1687
1681static Instruction_Param * 1688static Instruction_Param *
1682_paramameter_get_by_id(Evas_Filter_Instruction *instr, int id) 1689_parameter_get_by_id(Evas_Filter_Instruction *instr, int id)
1683{ 1690{
1684 Instruction_Param *param; 1691 Instruction_Param *param;
1685 int i = 0; 1692 int i = 0;
@@ -1734,7 +1741,7 @@ _lua_instruction_run(lua_State *L, Evas_Filter_Instruction *instr)
1734 else if (lua_isnumber(L, -2)) 1741 else if (lua_isnumber(L, -2))
1735 { 1742 {
1736 int idx = (int) lua_tonumber(L, -2); 1743 int idx = (int) lua_tonumber(L, -2);
1737 param = _paramameter_get_by_id(instr, idx - 1); 1744 param = _parameter_get_by_id(instr, idx - 1);
1738 if (!param) 1745 if (!param)
1739 { 1746 {
1740 ERR("Too many parameters for the function %s", instr->name); 1747 ERR("Too many parameters for the function %s", instr->name);
@@ -2092,20 +2099,48 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str)
2092 2099
2093 if (ok) 2100 if (ok)
2094 ok = !lua_pcall(L, 0, LUA_MULTRET, 0); 2101 ok = !lua_pcall(L, 0, LUA_MULTRET, 0);
2095 else 2102
2103 if (!ok || !pgm->instructions)
2096 { 2104 {
2097 const char *msg = lua_tostring(L, -1); 2105 const char *msg = lua_tostring(L, -1);
2098 ERR("Lua parsing failed: %s", msg); 2106 ERR("Lua parsing failed: %s", msg);
2107 lua_close(L);
2099 } 2108 }
2100 lua_close(L); 2109 else
2101 2110 pgm->L = L;
2102 ok &= (pgm->instructions != NULL);
2103 pgm->valid = ok; 2111 pgm->valid = ok;
2104 pgm->padding_calc = EINA_FALSE; 2112 pgm->padding_calc = EINA_FALSE;
2105 2113
2106 return ok; 2114 return ok;
2107} 2115}
2108 2116
2117/** Run a program, must be already loaded */
2118
2119EAPI Eina_Bool
2120evas_filter_program_run(Evas_Filter_Program *pgm)
2121{
2122 Eina_Bool ok;
2123
2124 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
2125 if (!pgm->L)
2126 {
2127 ERR("Lua state is not set. Something is wrong.");
2128 return EINA_FALSE;
2129 }
2130
2131 if (!pgm->changed)
2132 return EINA_TRUE;
2133
2134 ok = !lua_pcall(pgm->L, 0, LUA_MULTRET, 0);
2135 if (!ok)
2136 {
2137 const char *msg = lua_tostring(pgm->L, -1);
2138 ERR("Lua execution failed: %s", msg);
2139 }
2140
2141 return ok;
2142}
2143
2109/** Evaluate required padding to correctly apply an effect */ 2144/** Evaluate required padding to correctly apply an effect */
2110 2145
2111EAPI Eina_Bool 2146EAPI Eina_Bool
@@ -2180,6 +2215,21 @@ evas_filter_program_new(const char *name, Eina_Bool input_alpha)
2180 return pgm; 2215 return pgm;
2181} 2216}
2182 2217
2218EAPI void
2219evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h)
2220{
2221 Eina_Bool changed = EINA_FALSE;
2222#define SET(a) do { if (pgm->a != a) { changed = 1; pgm->a = a; } } while (0)
2223
2224 EINA_SAFETY_ON_NULL_RETURN(pgm);
2225
2226 SET(w);
2227 SET(h);
2228 pgm->changed |= changed;
2229
2230#undef SET
2231}
2232
2183/** Bind objects for proxy rendering */ 2233/** Bind objects for proxy rendering */
2184EAPI void 2234EAPI void
2185evas_filter_program_source_set_all(Evas_Filter_Program *pgm, 2235evas_filter_program_source_set_all(Evas_Filter_Program *pgm,
@@ -2739,6 +2789,10 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
2739 2789
2740 DBG("Using program '%s' for context %p", pgm->name, ctx); 2790 DBG("Using program '%s' for context %p", pgm->name, ctx);
2741 2791
2792 // Copy current state (size, edje state val, color class, etc...)
2793 ctx->w = pgm->w;
2794 ctx->h = pgm->h;
2795
2742 // Create empty context with all required buffers 2796 // Create empty context with all required buffers
2743 evas_filter_context_clear(ctx); 2797 evas_filter_context_clear(ctx);
2744 EINA_INLIST_FOREACH(pgm->buffers, buf) 2798 EINA_INLIST_FOREACH(pgm->buffers, buf)
@@ -2746,6 +2800,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
2746 buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); 2800 buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha);
2747 if (buf->proxy) 2801 if (buf->proxy)
2748 { 2802 {
2803 Evas_Object_Protected_Data *source;
2749 Evas_Filter_Proxy_Binding *pb; 2804 Evas_Filter_Proxy_Binding *pb;
2750 Evas_Filter_Buffer *fb; 2805 Evas_Filter_Buffer *fb;
2751 2806
@@ -2757,6 +2812,15 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
2757 fb->source = pb->eo_source; 2812 fb->source = pb->eo_source;
2758 fb->source_name = eina_stringshare_ref(pb->name); 2813 fb->source_name = eina_stringshare_ref(pb->name);
2759 fb->ctx->has_proxies = EINA_TRUE; 2814 fb->ctx->has_proxies = EINA_TRUE;
2815
2816 source = eo_data_scope_get(fb->source, EVAS_OBJECT_CLASS);
2817 fb->w = source->cur->geometry.w;
2818 fb->h = source->cur->geometry.h;
2819 }
2820 else
2821 {
2822 buf->w = ctx->w;
2823 buf->h = ctx->h;
2760 } 2824 }
2761 } 2825 }
2762 2826
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index 2280441..b8b2361 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -118,6 +118,8 @@ enum _Evas_Filter_Transform_Flags
118 118
119/* Parser stuff (high level API) */ 119/* Parser stuff (high level API) */
120EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha); 120EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha);
121EAPI Eina_Bool evas_filter_program_run(Evas_Filter_Program *pgm);
122EAPI void evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h);
121EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); 123EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
122EAPI void evas_filter_program_del(Evas_Filter_Program *pgm); 124EAPI void evas_filter_program_del(Evas_Filter_Program *pgm);
123Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm); 125Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm);
@@ -130,7 +132,7 @@ Evas_Filter_Context *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bo
130void evas_filter_context_destroy(Evas_Filter_Context *ctx); 132void evas_filter_context_destroy(Evas_Filter_Context *ctx);
131void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data); 133void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
132#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx) 134#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)
133Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, unsigned w, unsigned h); 135Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
134 136
135int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); 137int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
136int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image); 138int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);