diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-03-22 16:55:26 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-04-14 11:26:44 +0900 |
commit | 1bf24f87626b438598936ad4f780f7877447f496 (patch) | |
tree | e6111138de96a1479054e1ab8649c00096273378 /src | |
parent | 7407a0d073a57e66f6ab68069780026b56bf7b39 (diff) |
evas filters: Refactor to support reuse of buffers
This will reuse existing buffers by resetting only the minimum
required in the filter context (also reused). Work in progress,
as the actual reuse is disabled for now.
Diffstat (limited to '')
-rw-r--r-- | src/bin/elementary/test_evas_snapshot.c | 1 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_filter_mixin.c | 109 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_main.c | 2 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_textblock.c | 4 | ||||
-rw-r--r-- | src/lib/evas/filters/evas_filter.c | 171 | ||||
-rw-r--r-- | src/lib/evas/filters/evas_filter_parser.c | 73 | ||||
-rw-r--r-- | src/lib/evas/filters/evas_filter_private.h | 8 | ||||
-rw-r--r-- | src/lib/evas/include/evas_filter.h | 10 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 3 |
9 files changed, 286 insertions, 95 deletions
diff --git a/src/bin/elementary/test_evas_snapshot.c b/src/bin/elementary/test_evas_snapshot.c index 94d6e160be..13e045804c 100644 --- a/src/bin/elementary/test_evas_snapshot.c +++ b/src/bin/elementary/test_evas_snapshot.c | |||
@@ -111,7 +111,6 @@ test_evas_snapshot(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e | |||
111 | efl_pack_grid(grid, efl_added, 1, 1, GRID_SIZE - 2, GRID_SIZE - 2), | 111 | efl_pack_grid(grid, efl_added, 1, 1, GRID_SIZE - 2, GRID_SIZE - 2), |
112 | efl_gfx_visible_set(efl_added, 1)); | 112 | efl_gfx_visible_set(efl_added, 1)); |
113 | 113 | ||
114 | |||
115 | // Objects above snapshot | 114 | // Objects above snapshot |
116 | // 1. Opaque rect, not changing | 115 | // 1. Opaque rect, not changing |
117 | o = evas_object_rectangle_add(win); | 116 | o = evas_object_rectangle_add(win); |
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c index 45db424c0a..fab03baa60 100644 --- a/src/lib/evas/canvas/evas_filter_mixin.c +++ b/src/lib/evas/canvas/evas_filter_mixin.c | |||
@@ -43,6 +43,8 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj, | |||
43 | Evas_Filter_Data *pd, Eina_Bool success) | 43 | Evas_Filter_Data *pd, Eina_Bool success) |
44 | { | 44 | { |
45 | void *previous = pd->data->output; | 45 | void *previous = pd->data->output; |
46 | Eina_Bool destroy = !pd->data->reuse; | ||
47 | Evas_Object_Filter_Data *fcow; | ||
46 | Eo *eo_obj = obj->object; | 48 | Eo *eo_obj = obj->object; |
47 | 49 | ||
48 | if (!success) | 50 | if (!success) |
@@ -50,10 +52,10 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj, | |||
50 | ERR("Filter failed at runtime!"); | 52 | ERR("Filter failed at runtime!"); |
51 | evas_filter_invalid_set(eo_obj, EINA_TRUE); | 53 | evas_filter_invalid_set(eo_obj, EINA_TRUE); |
52 | evas_filter_dirty(eo_obj); | 54 | evas_filter_dirty(eo_obj); |
55 | destroy = EINA_TRUE; | ||
53 | } | 56 | } |
54 | else | 57 | else |
55 | { | 58 | { |
56 | Evas_Object_Filter_Data *fcow; | ||
57 | void *output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE); | 59 | void *output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE); |
58 | 60 | ||
59 | fcow = FCOW_BEGIN(pd); | 61 | fcow = FCOW_BEGIN(pd); |
@@ -61,9 +63,29 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj, | |||
61 | FCOW_END(fcow, pd); | 63 | FCOW_END(fcow, pd); |
62 | } | 64 | } |
63 | 65 | ||
64 | // Destroy context as we won't reuse it. | 66 | if (EINA_UNLIKELY(ctx != pd->data->context)) |
65 | evas_filter_buffer_backing_release(ctx, previous); | 67 | { |
66 | evas_filter_context_destroy(ctx); | 68 | ERR("Filter context has changed! Destroying it now..."); |
69 | fcow = FCOW_BEGIN(pd); | ||
70 | evas_filter_context_destroy(fcow->context); | ||
71 | fcow->context = NULL; | ||
72 | FCOW_END(fcow, pd); | ||
73 | destroy = EINA_TRUE; | ||
74 | } | ||
75 | |||
76 | if (destroy) | ||
77 | { | ||
78 | evas_filter_buffer_backing_release(ctx, previous); | ||
79 | evas_filter_context_destroy(ctx); | ||
80 | ctx = NULL; | ||
81 | } | ||
82 | |||
83 | if (pd->data->context != ctx) | ||
84 | { | ||
85 | fcow = FCOW_BEGIN(pd); | ||
86 | fcow->context = ctx; | ||
87 | FCOW_END(fcow, pd); | ||
88 | } | ||
67 | } | 89 | } |
68 | 90 | ||
69 | static void | 91 | static void |
@@ -192,13 +214,6 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | |||
192 | Evas_Object_Filter_Data *fcow; | 214 | Evas_Object_Filter_Data *fcow; |
193 | Evas_Filter_Padding pad; | 215 | Evas_Filter_Padding pad; |
194 | 216 | ||
195 | /* NOTE: Filter rendering is now done ENTIRELY on CPU. | ||
196 | * So we rely on cache/cache2 to allocate a real image buffer, | ||
197 | * that we can draw to. The OpenGL texture will be created only | ||
198 | * after the rendering has been done, as we simply push the output | ||
199 | * image to GL. | ||
200 | */ | ||
201 | |||
202 | W = obj->cur->geometry.w; | 217 | W = obj->cur->geometry.w; |
203 | H = obj->cur->geometry.h; | 218 | H = obj->cur->geometry.h; |
204 | X = obj->cur->geometry.x; | 219 | X = obj->cur->geometry.x; |
@@ -217,7 +232,7 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | |||
217 | obj->cur->clipper->cur->cache.clip.b, | 232 | obj->cur->clipper->cur->cache.clip.b, |
218 | obj->cur->clipper->cur->cache.clip.a); | 233 | obj->cur->clipper->cur->cache.clip.a); |
219 | else | 234 | else |
220 | ENFN->context_multiplier_unset(output, context); | 235 | ENFN->context_multiplier_unset(output, context); |
221 | 236 | ||
222 | if (!pd->data->chain) | 237 | if (!pd->data->chain) |
223 | { | 238 | { |
@@ -295,22 +310,57 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | |||
295 | _evas_filter_state_set_internal(pd->data->chain, pd); | 310 | _evas_filter_state_set_internal(pd->data->chain, pd); |
296 | } | 311 | } |
297 | 312 | ||
298 | filter = evas_filter_context_new(obj->layer->evas, do_async, 0); | 313 | filter = pd->data->context; |
299 | 314 | if (filter) | |
300 | // Run script | ||
301 | ok = evas_filter_context_program_use(filter, pd->data->chain); | ||
302 | if (!filter || !ok) | ||
303 | { | 315 | { |
304 | ERR("Parsing failed?"); | 316 | int prev_w, prev_h; |
305 | evas_filter_context_destroy(filter); | 317 | Eina_Bool was_async; |
306 | 318 | ||
307 | if (!pd->data->invalid) | 319 | was_async = evas_filter_context_async_get(filter); |
320 | evas_filter_context_size_get(filter, &prev_w, &prev_h); | ||
321 | if ((!pd->data->reuse) || (was_async != do_async) || | ||
322 | (prev_w != W) || (prev_h != H)) | ||
308 | { | 323 | { |
309 | fcow = FCOW_BEGIN(pd); | 324 | fcow = FCOW_BEGIN(pd); |
310 | fcow->invalid = EINA_TRUE; | 325 | fcow->context = NULL; |
311 | FCOW_END(fcow, pd); | 326 | FCOW_END(fcow, pd); |
327 | evas_filter_context_destroy(filter); | ||
328 | filter = NULL; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | if (filter) | ||
333 | { | ||
334 | ok = evas_filter_context_program_reuse(filter, pd->data->chain); | ||
335 | if (!ok) | ||
336 | { | ||
337 | fcow = FCOW_BEGIN(pd); | ||
338 | fcow->context = NULL; | ||
339 | FCOW_END(fcow, pd); | ||
340 | evas_filter_context_destroy(filter); | ||
341 | filter = NULL; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | if (!filter) | ||
346 | { | ||
347 | filter = evas_filter_context_new(obj->layer->evas, do_async, 0); | ||
348 | |||
349 | // Run script | ||
350 | ok = evas_filter_context_program_use(filter, pd->data->chain, EINA_FALSE); | ||
351 | if (!filter || !ok) | ||
352 | { | ||
353 | ERR("Parsing failed?"); | ||
354 | evas_filter_context_destroy(filter); | ||
355 | |||
356 | if (!pd->data->invalid) | ||
357 | { | ||
358 | fcow = FCOW_BEGIN(pd); | ||
359 | fcow->invalid = EINA_TRUE; | ||
360 | FCOW_END(fcow, pd); | ||
361 | } | ||
362 | return EINA_FALSE; | ||
312 | } | 363 | } |
313 | return EINA_FALSE; | ||
314 | } | 364 | } |
315 | 365 | ||
316 | // Proxies | 366 | // Proxies |
@@ -336,15 +386,17 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | |||
336 | 386 | ||
337 | // Add post-run callback and run filter | 387 | // Add post-run callback and run filter |
338 | evas_filter_context_post_run_callback_set(filter, _filter_cb, pd); | 388 | evas_filter_context_post_run_callback_set(filter, _filter_cb, pd); |
339 | ok = evas_filter_run(filter); | ||
340 | 389 | ||
341 | fcow = FCOW_BEGIN(pd); | 390 | fcow = FCOW_BEGIN(pd); |
391 | fcow->context = filter; | ||
342 | fcow->changed = EINA_FALSE; | 392 | fcow->changed = EINA_FALSE; |
343 | fcow->async = do_async; | 393 | fcow->async = do_async; |
344 | fcow->prev_obscured = fcow->obscured; | 394 | fcow->prev_obscured = fcow->obscured; |
345 | fcow->invalid = !ok; | 395 | fcow->invalid = EINA_FALSE; |
346 | FCOW_END(fcow, pd); | 396 | FCOW_END(fcow, pd); |
347 | 397 | ||
398 | ok = evas_filter_context_run(filter); | ||
399 | |||
348 | if (ok) | 400 | if (ok) |
349 | { | 401 | { |
350 | DBG("Effect rendering done."); | 402 | DBG("Effect rendering done."); |
@@ -352,6 +404,9 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, | |||
352 | } | 404 | } |
353 | else | 405 | else |
354 | { | 406 | { |
407 | fcow = FCOW_BEGIN(pd); | ||
408 | fcow->invalid = EINA_TRUE; | ||
409 | FCOW_END(fcow, pd); | ||
355 | ERR("Rendering failed."); | 410 | ERR("Rendering failed."); |
356 | return EINA_FALSE; | 411 | return EINA_FALSE; |
357 | } | 412 | } |
@@ -377,6 +432,9 @@ _efl_canvas_filter_internal_efl_gfx_filter_filter_program_set(Eo *eo_obj, Evas_F | |||
377 | { | 432 | { |
378 | fcow->obj = obj; | 433 | fcow->obj = obj; |
379 | 434 | ||
435 | if (fcow->context) | ||
436 | evas_filter_context_destroy(fcow->context); | ||
437 | |||
380 | // Parse filter program | 438 | // Parse filter program |
381 | evas_filter_program_del(fcow->chain); | 439 | evas_filter_program_del(fcow->chain); |
382 | eina_stringshare_replace(&fcow->name, name); | 440 | eina_stringshare_replace(&fcow->name, name); |
@@ -613,6 +671,9 @@ _efl_canvas_filter_internal_efl_object_destructor(Eo *eo_obj, Evas_Filter_Data * | |||
613 | obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); | 671 | obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); |
614 | e = obj->layer->evas; | 672 | e = obj->layer->evas; |
615 | 673 | ||
674 | if (pd->data->context) | ||
675 | evas_filter_context_destroy(pd->data->context); | ||
676 | |||
616 | if (pd->data->output) | 677 | if (pd->data->output) |
617 | { | 678 | { |
618 | if (!pd->data->async) | 679 | if (!pd->data->async) |
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index cab4bd1731..b62ffe67c4 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c | |||
@@ -33,7 +33,7 @@ static const Evas_Object_Protected_State default_state = { | |||
33 | 1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE | 33 | 1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE |
34 | }; | 34 | }; |
35 | static const Evas_Object_Filter_Data default_filter = { | 35 | static const Evas_Object_Filter_Data default_filter = { |
36 | NULL, NULL, NULL, NULL, NULL, NULL, {}, {}, NULL, {}, EINA_FALSE, EINA_FALSE, EINA_TRUE | 36 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, {}, {}, NULL, {}, EINA_FALSE, EINA_FALSE, EINA_TRUE, EINA_TRUE |
37 | }; | 37 | }; |
38 | const void * const evas_object_filter_cow_default = &default_filter; | 38 | const void * const evas_object_filter_cow_default = &default_filter; |
39 | static const Evas_Object_Mask_Data default_mask = { | 39 | static const Evas_Object_Mask_Data default_mask = { |
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 05166b914a..8032abfc59 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c | |||
@@ -13476,7 +13476,7 @@ evas_object_textblock_render(Evas_Object *eo_obj EINA_UNUSED, | |||
13476 | ctx = evas_filter_context_new(obj->layer->evas, do_async, ti->gfx_filter); | 13476 | ctx = evas_filter_context_new(obj->layer->evas, do_async, ti->gfx_filter); |
13477 | evas_filter_state_prepare(eo_obj, &state, ti); | 13477 | evas_filter_state_prepare(eo_obj, &state, ti); |
13478 | evas_filter_program_state_set(pgm, &state); | 13478 | evas_filter_program_state_set(pgm, &state); |
13479 | ok = evas_filter_context_program_use(ctx, pgm); | 13479 | ok = evas_filter_context_program_use(ctx, pgm, EINA_FALSE); |
13480 | if (!ok) | 13480 | if (!ok) |
13481 | { | 13481 | { |
13482 | evas_filter_context_destroy(ctx); | 13482 | evas_filter_context_destroy(ctx); |
@@ -13790,7 +13790,7 @@ evas_object_textblock_render(Evas_Object *eo_obj EINA_UNUSED, | |||
13790 | else if (ctx) | 13790 | else if (ctx) |
13791 | { | 13791 | { |
13792 | evas_filter_context_post_run_callback_set(ctx, _filter_cb, obj->layer->evas); | 13792 | evas_filter_context_post_run_callback_set(ctx, _filter_cb, obj->layer->evas); |
13793 | evas_filter_run(ctx); | 13793 | evas_filter_context_run(ctx); |
13794 | } | 13794 | } |
13795 | } | 13795 | } |
13796 | } | 13796 | } |
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 3b4c7ff6a0..c0990a0ef7 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c | |||
@@ -30,6 +30,7 @@ | |||
30 | static void _buffer_free(Evas_Filter_Buffer *fb); | 30 | static void _buffer_free(Evas_Filter_Buffer *fb); |
31 | static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); | 31 | static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); |
32 | static Evas_Filter_Buffer *_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool render, Eina_Bool draw); | 32 | static Evas_Filter_Buffer *_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool render, Eina_Bool draw); |
33 | static void _filter_buffer_unlock_all(Evas_Filter_Context *ctx); | ||
33 | 34 | ||
34 | #define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0) | 35 | #define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0) |
35 | #define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0) | 36 | #define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0) |
@@ -72,24 +73,37 @@ evas_filter_context_async_get(Evas_Filter_Context *ctx) | |||
72 | return ctx->async; | 73 | return ctx->async; |
73 | } | 74 | } |
74 | 75 | ||
76 | void | ||
77 | evas_filter_context_size_get(Evas_Filter_Context *ctx, int *w, int *h) | ||
78 | { | ||
79 | if (w) *w = ctx->w; | ||
80 | if (h) *h = ctx->h; | ||
81 | } | ||
82 | |||
75 | /* Private function to reset the filter context. Used from parser.c */ | 83 | /* Private function to reset the filter context. Used from parser.c */ |
76 | void | 84 | void |
77 | evas_filter_context_clear(Evas_Filter_Context *ctx) | 85 | evas_filter_context_clear(Evas_Filter_Context *ctx, Eina_Bool keep_buffers) |
78 | { | 86 | { |
79 | Evas_Filter_Buffer *fb; | ||
80 | Evas_Filter_Command *cmd; | 87 | Evas_Filter_Command *cmd; |
88 | Evas_Filter_Buffer *fb; | ||
81 | 89 | ||
82 | if (!ctx) return; | 90 | if (!ctx) return; |
83 | 91 | ||
84 | EINA_LIST_FREE(ctx->buffers, fb) | 92 | if (ctx->target.surface) ENFN->image_free(ENDT, ctx->target.surface); |
85 | _buffer_free(fb); | 93 | if (ctx->target.mask) ENFN->image_free(ENDT, ctx->target.mask); |
86 | EINA_INLIST_FREE(ctx->commands, cmd) | 94 | ctx->target.surface = NULL; |
87 | _command_del(ctx, cmd); | 95 | ctx->target.mask = NULL; |
96 | |||
97 | if (!keep_buffers) | ||
98 | { | ||
99 | ctx->last_buffer_id = 0; | ||
100 | EINA_LIST_FREE(ctx->buffers, fb) | ||
101 | _buffer_free(fb); | ||
102 | } | ||
88 | 103 | ||
89 | ctx->buffers = NULL; | ||
90 | ctx->commands = NULL; | ||
91 | ctx->last_buffer_id = 0; | ||
92 | ctx->last_command_id = 0; | 104 | ctx->last_command_id = 0; |
105 | EINA_INLIST_FREE(ctx->commands, cmd) | ||
106 | _command_del(ctx, cmd); | ||
93 | 107 | ||
94 | // Note: don't reset post_run, as it it set by the client | 108 | // Note: don't reset post_run, as it it set by the client |
95 | } | 109 | } |
@@ -109,6 +123,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, | |||
109 | { | 123 | { |
110 | Evas_Object_Protected_Data *source; | 124 | Evas_Object_Protected_Data *source; |
111 | Evas_Object_Protected_Data *obj; | 125 | Evas_Object_Protected_Data *obj; |
126 | void *proxy_surface; | ||
112 | Evas_Filter_Buffer *fb; | 127 | Evas_Filter_Buffer *fb; |
113 | Eina_List *li; | 128 | Eina_List *li; |
114 | 129 | ||
@@ -122,6 +137,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, | |||
122 | source = efl_data_scope_get(fb->source, EFL_CANVAS_OBJECT_CLASS); | 137 | source = efl_data_scope_get(fb->source, EFL_CANVAS_OBJECT_CLASS); |
123 | _assert(fb->w == source->cur->geometry.w); | 138 | _assert(fb->w == source->cur->geometry.w); |
124 | _assert(fb->h == source->cur->geometry.h); | 139 | _assert(fb->h == source->cur->geometry.h); |
140 | proxy_surface = source->proxy->surface; | ||
125 | if (source->proxy->surface && !source->proxy->redraw) | 141 | if (source->proxy->surface && !source->proxy->redraw) |
126 | { | 142 | { |
127 | XDBG("Source already rendered: '%s' of type '%s'", | 143 | XDBG("Source already rendered: '%s' of type '%s'", |
@@ -134,33 +150,75 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, | |||
134 | source->proxy->redraw ? "redraw" : "no surface"); | 150 | source->proxy->redraw ? "redraw" : "no surface"); |
135 | evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, EINA_FALSE, do_async); | 151 | evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, EINA_FALSE, do_async); |
136 | } | 152 | } |
137 | _filter_buffer_backing_free(fb); | 153 | if (fb->buffer) |
154 | { | ||
155 | void *old_surface; | ||
156 | |||
157 | old_surface = evas_ector_buffer_drawable_image_get(fb->buffer); | ||
158 | if (old_surface && (old_surface != proxy_surface)) | ||
159 | _filter_buffer_backing_free(fb); | ||
160 | } | ||
138 | XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h); | 161 | XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h); |
139 | fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface); | 162 | if (!fb->buffer) fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface); |
140 | fb->alpha_only = EINA_FALSE; | 163 | fb->alpha_only = EINA_FALSE; |
141 | } | 164 | } |
142 | } | 165 | } |
143 | 166 | ||
144 | void | 167 | Eina_Bool |
145 | evas_filter_context_destroy(Evas_Filter_Context *ctx) | 168 | evas_filter_context_program_reuse(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm) |
146 | { | 169 | { |
147 | Evas_Filter_Buffer *fb; | 170 | Evas_Filter_Buffer *fb; |
148 | Evas_Filter_Command *cmd; | 171 | Eina_List *li; |
149 | 172 | ||
150 | if (!ctx) return; | 173 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); |
174 | EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE); | ||
151 | 175 | ||
152 | EINA_LIST_FREE(ctx->buffers, fb) | 176 | _filter_buffer_unlock_all(ctx); |
153 | _buffer_free(fb); | ||
154 | EINA_INLIST_FREE(ctx->commands, cmd) | ||
155 | _command_del(ctx, cmd); | ||
156 | 177 | ||
157 | if (ctx->target.mask) | 178 | EINA_LIST_FOREACH(ctx->buffers, li, fb) |
158 | ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask); | 179 | { |
180 | void *dc, *surface; | ||
181 | |||
182 | fb->used = EINA_FALSE; | ||
183 | fb->locked = EINA_FALSE; | ||
184 | |||
185 | if (!fb->is_render) continue; | ||
186 | if (fb->source) continue; | ||
187 | |||
188 | surface = evas_ector_buffer_render_image_get(fb->buffer); | ||
189 | if (!surface) continue; | ||
190 | |||
191 | dc = ENFN->context_new(ENDT); | ||
192 | ENFN->context_color_set(ENDT, dc, 0, 0, 0, 0); | ||
193 | ENFN->context_render_op_set(ENDT, dc, EVAS_RENDER_COPY); | ||
194 | ENFN->rectangle_draw(ENDT, dc, surface, 0, 0, fb->w, fb->h, ctx->async); | ||
195 | ENFN->context_free(ENDT, dc); | ||
196 | fb->dirty = EINA_FALSE; | ||
197 | } | ||
198 | |||
199 | return evas_filter_context_program_use(ctx, pgm, EINA_TRUE); | ||
200 | } | ||
201 | |||
202 | static void | ||
203 | _context_destroy(void *data) | ||
204 | { | ||
205 | Evas_Filter_Context *ctx = data; | ||
159 | 206 | ||
207 | evas_filter_context_clear(ctx, EINA_FALSE); | ||
160 | free(ctx); | 208 | free(ctx); |
161 | } | 209 | } |
162 | 210 | ||
163 | void | 211 | void |
212 | evas_filter_context_destroy(Evas_Filter_Context *ctx) | ||
213 | { | ||
214 | // FIXME: This is not locked... | ||
215 | if (ctx->running) | ||
216 | evas_post_render_job_add(ctx->evas, _context_destroy, ctx); | ||
217 | else | ||
218 | _context_destroy(ctx); | ||
219 | } | ||
220 | |||
221 | void | ||
164 | evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, | 222 | evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, |
165 | Evas_Filter_Cb cb, void *data) | 223 | Evas_Filter_Cb cb, void *data) |
166 | { | 224 | { |
@@ -213,6 +271,8 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
213 | Eina_List *li; | 271 | Eina_List *li; |
214 | unsigned w, h; | 272 | unsigned w, h; |
215 | 273 | ||
274 | if (ctx->run_count > 0) return EINA_TRUE; | ||
275 | |||
216 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); | 276 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); |
217 | w = ctx->w; | 277 | w = ctx->w; |
218 | h = ctx->h; | 278 | h = ctx->h; |
@@ -231,6 +291,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) | |||
231 | in->h = h; | 291 | in->h = h; |
232 | } | 292 | } |
233 | 293 | ||
294 | // FIXME: No need for stretch buffers with GL! | ||
234 | if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY) | 295 | if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY) |
235 | { | 296 | { |
236 | unsigned sw = w, sh = h; | 297 | unsigned sw = w, sh = h; |
@@ -322,15 +383,69 @@ alloc_fail: | |||
322 | } | 383 | } |
323 | 384 | ||
324 | int | 385 | int |
325 | evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only) | 386 | evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) |
326 | { | 387 | { |
327 | Evas_Filter_Buffer *fb; | 388 | Evas_Filter_Buffer *fb; |
389 | Eina_List *li; | ||
328 | 390 | ||
329 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); | 391 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); |
330 | 392 | ||
331 | fb = _buffer_empty_new(ctx, 0, 0, alpha_only, EINA_FALSE); | 393 | EINA_LIST_FOREACH(ctx->buffers, li, fb) |
394 | { | ||
395 | if ((fb->alpha_only == alpha_only) && | ||
396 | (fb->w == w) && (fb->h == h) && !fb->dirty && !fb->used) | ||
397 | { | ||
398 | fb->used = EINA_TRUE; | ||
399 | return fb->id; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | fb = _buffer_empty_new(ctx, w, h, alpha_only, EINA_FALSE); | ||
332 | if (!fb) return -1; | 404 | if (!fb) return -1; |
333 | 405 | ||
406 | fb->used = EINA_TRUE; | ||
407 | return fb->id; | ||
408 | } | ||
409 | |||
410 | int | ||
411 | evas_filter_buffer_proxy_new(Evas_Filter_Context *ctx, Evas_Filter_Proxy_Binding *pb, | ||
412 | int *w, int *h) | ||
413 | { | ||
414 | Evas_Object_Protected_Data *source; | ||
415 | Evas_Filter_Buffer *fb; | ||
416 | Eina_List *li; | ||
417 | |||
418 | EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); | ||
419 | EINA_SAFETY_ON_NULL_RETURN_VAL(pb, -1); | ||
420 | |||
421 | source = efl_data_scope_get(pb->eo_source, EFL_CANVAS_OBJECT_CLASS); | ||
422 | if (!source) return -1; | ||
423 | |||
424 | // FIXME: This is not true if the source is an evas image | ||
425 | *w = source->cur->geometry.w; | ||
426 | *h = source->cur->geometry.h; | ||
427 | |||
428 | EINA_LIST_FOREACH(ctx->buffers, li, fb) | ||
429 | { | ||
430 | if (pb->eo_source == fb->source) | ||
431 | { | ||
432 | if (fb->used) return -1; | ||
433 | if (fb->alpha_only) return -1; | ||
434 | if (!eina_streq(pb->name, fb->source_name)) return -1; | ||
435 | if ((*w != fb->w) || (*h != fb->h)) return -1; | ||
436 | |||
437 | fb->used = EINA_TRUE; | ||
438 | return fb->id; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | fb = _buffer_empty_new(ctx, *w, *h, EINA_FALSE, EINA_FALSE); | ||
443 | if (!fb) return -1; | ||
444 | |||
445 | fb->source = efl_ref(pb->eo_source); | ||
446 | fb->source_name = eina_stringshare_add(pb->name); | ||
447 | |||
448 | fb->used = EINA_TRUE; | ||
334 | return fb->id; | 449 | return fb->id; |
335 | } | 450 | } |
336 | 451 | ||
@@ -351,6 +466,7 @@ _buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, | |||
351 | fb->w = w; | 466 | fb->w = w; |
352 | fb->h = h; | 467 | fb->h = h; |
353 | fb->alpha_only = alpha_only; | 468 | fb->alpha_only = alpha_only; |
469 | fb->is_render = render; | ||
354 | fb->buffer = _ector_buffer_create(fb, render, draw); | 470 | fb->buffer = _ector_buffer_create(fb, render, draw); |
355 | if (!fb->buffer) | 471 | if (!fb->buffer) |
356 | { | 472 | { |
@@ -367,6 +483,8 @@ static void | |||
367 | _buffer_free(Evas_Filter_Buffer *fb) | 483 | _buffer_free(Evas_Filter_Buffer *fb) |
368 | { | 484 | { |
369 | _filter_buffer_backing_free(fb); | 485 | _filter_buffer_backing_free(fb); |
486 | eina_stringshare_del(fb->source_name); | ||
487 | efl_unref(fb->source); | ||
370 | free(fb); | 488 | free(fb); |
371 | } | 489 | } |
372 | 490 | ||
@@ -434,6 +552,7 @@ _command_new(Evas_Filter_Context *ctx, Evas_Filter_Mode mode, | |||
434 | if (output) | 552 | if (output) |
435 | { | 553 | { |
436 | cmd->draw.output_was_dirty = output->dirty; | 554 | cmd->draw.output_was_dirty = output->dirty; |
555 | output->is_render = EINA_TRUE; | ||
437 | output->dirty = EINA_TRUE; | 556 | output->dirty = EINA_TRUE; |
438 | } | 557 | } |
439 | 558 | ||
@@ -482,6 +601,7 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, | |||
482 | 601 | ||
483 | fb = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE); | 602 | fb = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE); |
484 | fb->locked = EINA_TRUE; | 603 | fb->locked = EINA_TRUE; |
604 | fb->is_render = EINA_TRUE; | ||
485 | XDBG("Created temporary buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba"); | 605 | XDBG("Created temporary buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba"); |
486 | 606 | ||
487 | return fb; | 607 | return fb; |
@@ -1564,7 +1684,6 @@ _filter_chain_run(Evas_Filter_Context *ctx) | |||
1564 | 1684 | ||
1565 | DEBUG_TIME_BEGIN(); | 1685 | DEBUG_TIME_BEGIN(); |
1566 | 1686 | ||
1567 | ctx->running = EINA_TRUE; | ||
1568 | EINA_INLIST_FOREACH(ctx->commands, cmd) | 1687 | EINA_INLIST_FOREACH(ctx->commands, cmd) |
1569 | { | 1688 | { |
1570 | ok = _filter_command_run(cmd); | 1689 | ok = _filter_command_run(cmd); |
@@ -1646,7 +1765,7 @@ _filter_obscured_region_calc(Evas_Filter_Context *ctx) | |||
1646 | } | 1765 | } |
1647 | 1766 | ||
1648 | Eina_Bool | 1767 | Eina_Bool |
1649 | evas_filter_run(Evas_Filter_Context *ctx) | 1768 | evas_filter_context_run(Evas_Filter_Context *ctx) |
1650 | { | 1769 | { |
1651 | Eina_Bool ret; | 1770 | Eina_Bool ret; |
1652 | 1771 | ||
@@ -1657,12 +1776,14 @@ evas_filter_run(Evas_Filter_Context *ctx) | |||
1657 | 1776 | ||
1658 | _filter_obscured_region_calc(ctx); | 1777 | _filter_obscured_region_calc(ctx); |
1659 | 1778 | ||
1779 | ctx->running = EINA_TRUE; | ||
1660 | if (ctx->async) | 1780 | if (ctx->async) |
1661 | { | 1781 | { |
1662 | evas_thread_queue_flush(_filter_thread_run_cb, ctx); | 1782 | evas_thread_queue_flush(_filter_thread_run_cb, ctx); |
1663 | return EINA_TRUE; | 1783 | return EINA_TRUE; |
1664 | } | 1784 | } |
1665 | 1785 | ||
1786 | ctx->run_count++; | ||
1666 | ret = _filter_chain_run(ctx); | 1787 | ret = _filter_chain_run(ctx); |
1667 | 1788 | ||
1668 | if (ctx->post_run.cb) | 1789 | if (ctx->post_run.cb) |
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index 9c14e5dc06..60a7ecb476 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c | |||
@@ -2834,48 +2834,49 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str) | |||
2834 | 2834 | ||
2835 | /** Run a program, must be already loaded */ | 2835 | /** Run a program, must be already loaded */ |
2836 | 2836 | ||
2837 | static void | 2837 | static Eina_Bool |
2838 | _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm) | 2838 | _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm) |
2839 | { | 2839 | { |
2840 | Evas_Object_Protected_Data *source; | ||
2841 | Evas_Filter_Proxy_Binding *pb; | 2840 | Evas_Filter_Proxy_Binding *pb; |
2842 | Evas_Filter_Buffer *fb; | ||
2843 | Buffer *buf; | 2841 | Buffer *buf; |
2842 | int w, h, id; | ||
2844 | 2843 | ||
2845 | EINA_INLIST_FOREACH(pgm->buffers, buf) | 2844 | EINA_INLIST_FOREACH(pgm->buffers, buf) |
2846 | { | 2845 | { |
2847 | if (buf->proxy) | 2846 | if (buf->proxy) |
2848 | { | 2847 | { |
2849 | pb = eina_hash_find(pgm->proxies, buf->proxy); | 2848 | pb = eina_hash_find(pgm->proxies, buf->proxy); |
2850 | if (!pb) continue; | 2849 | if (!pb) return EINA_FALSE; |
2851 | 2850 | ||
2852 | buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); | 2851 | ctx->has_proxies = EINA_TRUE; |
2853 | fb = _filter_buffer_get(ctx, buf->cid); | 2852 | id = evas_filter_buffer_proxy_new(ctx, pb, &w, &h); |
2854 | fb->source = pb->eo_source; | 2853 | if (id < 0) return EINA_FALSE; |
2855 | fb->source_name = eina_stringshare_ref(pb->name); | 2854 | |
2856 | fb->ctx->has_proxies = EINA_TRUE; | 2855 | buf->cid = id; |
2857 | 2856 | buf->w = w; | |
2858 | source = efl_data_scope_get(fb->source, EFL_CANVAS_OBJECT_CLASS); | 2857 | buf->h = h; |
2859 | if ((source->cur->geometry.w != buf->w) || | 2858 | |
2860 | (source->cur->geometry.h != buf->h)) | 2859 | XDBG("Created proxy buffer #%d %dx%d %s '%s'", buf->cid, |
2861 | pgm->changed = EINA_TRUE; | 2860 | w, h, buf->alpha ? "alpha" : "rgba", buf->name); |
2862 | buf->w = fb->w = source->cur->geometry.w; | ||
2863 | buf->h = fb->h = source->cur->geometry.h; | ||
2864 | XDBG("Created proxy buffer %d %s '%s'", fb->id, | ||
2865 | buf->alpha ? "alpha" : "rgba", buf->name); | ||
2866 | } | 2861 | } |
2867 | else | 2862 | else |
2868 | { | 2863 | { |
2869 | if ((buf->w != pgm->state.w) || (buf->h != pgm->state.h)) | 2864 | w = pgm->state.w; |
2870 | pgm->changed = EINA_TRUE; | 2865 | h = pgm->state.h; |
2871 | buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); | 2866 | |
2872 | fb = _filter_buffer_get(ctx, buf->cid); | 2867 | id = evas_filter_buffer_empty_new(ctx, w, h, buf->alpha); |
2873 | fb->w = buf->w = pgm->state.w; | 2868 | if (id < 0) return EINA_FALSE; |
2874 | fb->h = buf->h = pgm->state.h; | 2869 | |
2875 | XDBG("Created context buffer %d %s '%s'", fb->id, | 2870 | buf->cid = id; |
2876 | buf->alpha ? "alpha" : "rgba", buf->name); | 2871 | buf->w = w; |
2872 | buf->h = h; | ||
2873 | |||
2874 | XDBG("Created context buffer #%d %dx%d %s '%s'", buf->cid, | ||
2875 | w, h, buf->alpha ? "alpha" : "rgba", buf->name); | ||
2877 | } | 2876 | } |
2878 | } | 2877 | } |
2878 | |||
2879 | return EINA_TRUE; | ||
2879 | } | 2880 | } |
2880 | 2881 | ||
2881 | /** Evaluate required padding to correctly apply an effect */ | 2882 | /** Evaluate required padding to correctly apply an effect */ |
@@ -3401,11 +3402,8 @@ _command_from_instruction(Evas_Filter_Context *ctx, | |||
3401 | cmd = instr2cmd(ctx, instr, dc); | 3402 | cmd = instr2cmd(ctx, instr, dc); |
3402 | if (!cmd) return EINA_FALSE; | 3403 | if (!cmd) return EINA_FALSE; |
3403 | 3404 | ||
3404 | if (cmd->output && ctx->gl) | 3405 | if (cmd->output) |
3405 | { | 3406 | cmd->output->is_render = EINA_TRUE; |
3406 | if (ENFN->gfx_filter_supports(ENDT, cmd) == EVAS_FILTER_SUPPORT_GL) | ||
3407 | cmd->output->is_render = EINA_TRUE; | ||
3408 | } | ||
3409 | 3407 | ||
3410 | return EINA_TRUE; | 3408 | return EINA_TRUE; |
3411 | } | 3409 | } |
@@ -3475,7 +3473,8 @@ _instruction_dump(Evas_Filter_Instruction *instr) | |||
3475 | 3473 | ||
3476 | Eina_Bool | 3474 | Eina_Bool |
3477 | evas_filter_context_program_use(Evas_Filter_Context *ctx, | 3475 | evas_filter_context_program_use(Evas_Filter_Context *ctx, |
3478 | Evas_Filter_Program *pgm) | 3476 | Evas_Filter_Program *pgm, |
3477 | Eina_Bool reuse) | ||
3479 | { | 3478 | { |
3480 | Evas_Filter_Instruction *instr; | 3479 | Evas_Filter_Instruction *instr; |
3481 | Eina_Bool success = EINA_FALSE; | 3480 | Eina_Bool success = EINA_FALSE; |
@@ -3492,7 +3491,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, | |||
3492 | ctx->h = pgm->state.h; | 3491 | ctx->h = pgm->state.h; |
3493 | 3492 | ||
3494 | // Create empty context with all required buffers | 3493 | // Create empty context with all required buffers |
3495 | evas_filter_context_clear(ctx); | 3494 | evas_filter_context_clear(ctx, reuse); |
3496 | 3495 | ||
3497 | if (pgm->changed) | 3496 | if (pgm->changed) |
3498 | { | 3497 | { |
@@ -3508,7 +3507,9 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, | |||
3508 | goto end; | 3507 | goto end; |
3509 | } | 3508 | } |
3510 | } | 3509 | } |
3511 | _buffers_update(ctx, pgm); | 3510 | |
3511 | // Create or update all buffers | ||
3512 | if (!_buffers_update(ctx, pgm)) goto end; | ||
3512 | 3513 | ||
3513 | // Compute and save padding info | 3514 | // Compute and save padding info |
3514 | evas_filter_program_padding_get(pgm, &ctx->pad.final, &ctx->pad.calculated); | 3515 | evas_filter_program_padding_get(pgm, &ctx->pad.final, &ctx->pad.calculated); |
@@ -3528,7 +3529,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, | |||
3528 | pgm->changed = EINA_FALSE; | 3529 | pgm->changed = EINA_FALSE; |
3529 | 3530 | ||
3530 | end: | 3531 | end: |
3531 | if (!success) evas_filter_context_clear(ctx); | 3532 | if (!success) evas_filter_context_clear(ctx, EINA_FALSE); |
3532 | if (dc) ENFN->context_free(ENDT, dc); | 3533 | if (dc) ENFN->context_free(ENDT, dc); |
3533 | return success; | 3534 | return success; |
3534 | } | 3535 | } |
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index c62262a691..fb55aaf65e 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h | |||
@@ -157,10 +157,13 @@ struct _Evas_Filter_Context | |||
157 | Eina_Bool color_use : 1; | 157 | Eina_Bool color_use : 1; |
158 | } target; | 158 | } target; |
159 | 159 | ||
160 | volatile int running; | ||
161 | int run_count; | ||
162 | |||
160 | Eina_Bool async : 1; | 163 | Eina_Bool async : 1; |
161 | Eina_Bool running : 1; | ||
162 | Eina_Bool has_proxies : 1; | 164 | Eina_Bool has_proxies : 1; |
163 | Eina_Bool gl : 1; | 165 | Eina_Bool gl : 1; |
166 | |||
164 | }; | 167 | }; |
165 | 168 | ||
166 | struct _Evas_Filter_Command | 169 | struct _Evas_Filter_Command |
@@ -249,6 +252,7 @@ struct _Evas_Filter_Buffer | |||
249 | Ector_Buffer *buffer; | 252 | Ector_Buffer *buffer; |
250 | int w, h; | 253 | int w, h; |
251 | 254 | ||
255 | Eina_Bool used : 1; // This buffer is in use (useful for reuse of context) | ||
252 | Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) | 256 | Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) |
253 | Eina_Bool transient : 1; // temporary buffer (automatic allocation) | 257 | Eina_Bool transient : 1; // temporary buffer (automatic allocation) |
254 | Eina_Bool locked : 1; // internal flag | 258 | Eina_Bool locked : 1; // internal flag |
@@ -269,7 +273,7 @@ enum _Evas_Filter_Support | |||
269 | EVAS_FILTER_SUPPORT_GL | 273 | EVAS_FILTER_SUPPORT_GL |
270 | }; | 274 | }; |
271 | 275 | ||
272 | void evas_filter_context_clear(Evas_Filter_Context *ctx); | 276 | void evas_filter_context_clear(Evas_Filter_Context *ctx, Eina_Bool keep_buffers); |
273 | void evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name); | 277 | void evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name); |
274 | 278 | ||
275 | /* Utility functions */ | 279 | /* Utility functions */ |
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index c6854fd3c4..edb12cdcde 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h | |||
@@ -32,7 +32,6 @@ | |||
32 | # endif | 32 | # endif |
33 | #endif /* ! _WIN32 */ | 33 | #endif /* ! _WIN32 */ |
34 | 34 | ||
35 | typedef struct _Evas_Filter_Context Evas_Filter_Context; | ||
36 | typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction; | 35 | typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction; |
37 | typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer; | 36 | typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer; |
38 | typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding; | 37 | typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding; |
@@ -146,19 +145,22 @@ void evas_filter_program_data_set_all(Evas_Filter_Program *p | |||
146 | Evas_Filter_Context *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data); | 145 | Evas_Filter_Context *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data); |
147 | void *evas_filter_context_data_get(Evas_Filter_Context *ctx); | 146 | void *evas_filter_context_data_get(Evas_Filter_Context *ctx); |
148 | Eina_Bool evas_filter_context_async_get(Evas_Filter_Context *ctx); | 147 | Eina_Bool evas_filter_context_async_get(Evas_Filter_Context *ctx); |
148 | void evas_filter_context_size_get(Evas_Filter_Context *ctx, int *w, int *H); | ||
149 | void evas_filter_context_destroy(Evas_Filter_Context *ctx); | 149 | void evas_filter_context_destroy(Evas_Filter_Context *ctx); |
150 | Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm); | 150 | Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, Eina_Bool reuse); |
151 | Eina_Bool evas_filter_context_program_reuse(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm); | ||
151 | void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async); | 152 | void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async); |
152 | void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data); | 153 | void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data); |
153 | #define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx) | 154 | #define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx) |
154 | Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx); | 155 | Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx); |
155 | void evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect); | 156 | void evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect); |
156 | 157 | ||
157 | int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); | 158 | int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only); |
159 | int evas_filter_buffer_proxy_new(Evas_Filter_Context *ctx, Evas_Filter_Proxy_Binding *pb, int *w, int *h); | ||
158 | void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid, Eina_Bool render); | 160 | void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid, Eina_Bool render); |
159 | Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer); | 161 | Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer); |
160 | 162 | ||
161 | Eina_Bool evas_filter_run(Evas_Filter_Context *ctx); | 163 | Eina_Bool evas_filter_context_run(Evas_Filter_Context *ctx); |
162 | 164 | ||
163 | Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async); | 165 | Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async); |
164 | Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y); | 166 | Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y); |
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index cd5683817b..6a0c77686c 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h | |||
@@ -93,6 +93,7 @@ typedef struct _Evas_Object_Protected_Data Evas_Object_Protected_Data; | |||
93 | 93 | ||
94 | /* gfx filters typedef only */ | 94 | /* gfx filters typedef only */ |
95 | typedef struct _Evas_Filter_Program Evas_Filter_Program; | 95 | typedef struct _Evas_Filter_Program Evas_Filter_Program; |
96 | typedef struct _Evas_Filter_Context Evas_Filter_Context; | ||
96 | typedef struct _Evas_Object_Filter_Data Evas_Object_Filter_Data; | 97 | typedef struct _Evas_Object_Filter_Data Evas_Object_Filter_Data; |
97 | typedef struct _Evas_Filter_Data_Binding Evas_Filter_Data_Binding; | 98 | typedef struct _Evas_Filter_Data_Binding Evas_Filter_Data_Binding; |
98 | typedef struct _Evas_Pointer_Data Evas_Pointer_Data; | 99 | typedef struct _Evas_Pointer_Data Evas_Pointer_Data; |
@@ -1288,6 +1289,7 @@ struct _Evas_Object_Filter_Data | |||
1288 | Eina_Stringshare *name; | 1289 | Eina_Stringshare *name; |
1289 | Eina_Stringshare *code; | 1290 | Eina_Stringshare *code; |
1290 | Evas_Filter_Program *chain; | 1291 | Evas_Filter_Program *chain; |
1292 | Evas_Filter_Context *context; | ||
1291 | Eina_Hash *sources; // Evas_Filter_Proxy_Binding | 1293 | Eina_Hash *sources; // Evas_Filter_Proxy_Binding |
1292 | Eina_Inlist *data; // Evas_Filter_Data_Binding | 1294 | Eina_Inlist *data; // Evas_Filter_Data_Binding |
1293 | Eina_Rectangle prev_obscured, obscured; | 1295 | Eina_Rectangle prev_obscured, obscured; |
@@ -1306,6 +1308,7 @@ struct _Evas_Object_Filter_Data | |||
1306 | Eina_Bool changed : 1; | 1308 | Eina_Bool changed : 1; |
1307 | Eina_Bool invalid : 1; // Code parse failed | 1309 | Eina_Bool invalid : 1; // Code parse failed |
1308 | Eina_Bool async : 1; | 1310 | Eina_Bool async : 1; |
1311 | Eina_Bool reuse : 1; | ||
1309 | }; | 1312 | }; |
1310 | 1313 | ||
1311 | struct _Evas_Object_Func | 1314 | struct _Evas_Object_Func |