summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/evas/canvas/evas_filter_mixin.c31
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c1
-rw-r--r--src/lib/evas/filters/evas_filter.c71
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c2
-rw-r--r--src/lib/evas/filters/evas_filter_private.h2
-rw-r--r--src/lib/evas/include/evas_filter.h1
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c2
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c2
8 files changed, 70 insertions, 42 deletions
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c
index 31a7628241..742a9e8f43 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -65,7 +65,12 @@ struct _Evas_Filter_Post_Render_Data
65 Eina_Bool success; 65 Eina_Bool success;
66}; 66};
67 67
68static const Evas_Object_Filter_Data evas_filter_data_cow_default = {}; 68// FIXME: This should be enabled (with proper heuristics)
69#define FILTER_CONTEXT_REUSE EINA_FALSE
70
71static const Evas_Object_Filter_Data evas_filter_data_cow_default = {
72 .reuse = FILTER_CONTEXT_REUSE
73};
69Eina_Cow *evas_object_filter_cow = NULL; 74Eina_Cow *evas_object_filter_cow = NULL;
70 75
71void 76void
@@ -100,6 +105,7 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj,
100 Eina_Bool destroy = !pd->data->reuse; 105 Eina_Bool destroy = !pd->data->reuse;
101 Evas_Object_Filter_Data *fcow; 106 Evas_Object_Filter_Data *fcow;
102 Eo *eo_obj = obj->object; 107 Eo *eo_obj = obj->object;
108 void *output = NULL;
103 109
104 if (!success) 110 if (!success)
105 { 111 {
@@ -110,36 +116,25 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj,
110 } 116 }
111 else 117 else
112 { 118 {
113 void *output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE); 119 output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE);
114 120 FCOW_WRITE(pd, output, output);
115 fcow = FCOW_BEGIN(pd);
116 fcow->output = output;
117 FCOW_END(fcow, pd);
118 } 121 }
119 122
120 if (EINA_UNLIKELY(ctx != pd->data->context)) 123 if (EINA_UNLIKELY(ctx != pd->data->context))
121 { 124 {
122 ERR("Filter context has changed! Destroying it now..."); 125 ERR("Filter context has changed! Destroying it now...");
123 fcow = FCOW_BEGIN(pd); 126 evas_filter_context_destroy(pd->data->context);
124 evas_filter_context_destroy(fcow->context);
125 fcow->context = NULL;
126 FCOW_END(fcow, pd);
127 destroy = EINA_TRUE; 127 destroy = EINA_TRUE;
128 } 128 }
129 129
130 evas_filter_buffer_backing_release(ctx, previous);
130 if (destroy) 131 if (destroy)
131 { 132 {
132 evas_filter_buffer_backing_release(ctx, previous);
133 evas_filter_context_destroy(ctx); 133 evas_filter_context_destroy(ctx);
134 ctx = NULL; 134 ctx = NULL;
135 } 135 }
136 136
137 if (pd->data->context != ctx) 137 FCOW_WRITE(pd, context, ctx);
138 {
139 fcow = FCOW_BEGIN(pd);
140 fcow->context = ctx;
141 FCOW_END(fcow, pd);
142 }
143} 138}
144 139
145static void 140static void
@@ -401,7 +396,7 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
401 396
402 if (filter) 397 if (filter)
403 { 398 {
404 ok = evas_filter_context_program_reuse(filter, pd->data->chain, X, Y); 399 ok = evas_filter_context_program_use(filter, pd->data->chain, EINA_TRUE, X, Y);
405 if (!ok) 400 if (!ok)
406 { 401 {
407 fcow = FCOW_BEGIN(pd); 402 fcow = FCOW_BEGIN(pd);
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c
index abf076c609..2e93b11137 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -13002,6 +13002,7 @@ _filter_sync_end(Evas_Filter_Context *ctx, Eina_Bool success)
13002 13002
13003 if (filter->ti) 13003 if (filter->ti)
13004 { 13004 {
13005 // FIXME: LEAK HERE!
13005 filter->output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE); 13006 filter->output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE);
13006 if (filter->ti->parent.format->gfx_filter) 13007 if (filter->ti->parent.format->gfx_filter)
13007 filter->ti->parent.format->gfx_filter->invalid = !success; 13008 filter->ti->parent.format->gfx_filter->invalid = !success;
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 419c662dc2..988fbe5320 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -155,8 +155,12 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
155 void *old_surface; 155 void *old_surface;
156 156
157 old_surface = evas_ector_buffer_drawable_image_get(fb->buffer); 157 old_surface = evas_ector_buffer_drawable_image_get(fb->buffer);
158 if (old_surface && (old_surface != proxy_surface)) 158 if (old_surface)
159 _filter_buffer_backing_free(fb); 159 {
160 evas_ector_buffer_engine_image_release(fb->buffer, old_surface);
161 if (old_surface && (old_surface != proxy_surface))
162 _filter_buffer_backing_free(fb);
163 }
160 } 164 }
161 XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h); 165 XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h);
162 if (!fb->buffer) fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface); 166 if (!fb->buffer) fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface);
@@ -164,15 +168,12 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
164 } 168 }
165} 169}
166 170
167Eina_Bool 171void
168evas_filter_context_program_reuse(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, int x, int y) 172_evas_filter_context_program_reuse(Evas_Filter_Context *ctx)
169{ 173{
170 Evas_Filter_Buffer *fb; 174 Evas_Filter_Buffer *fb;
171 Eina_List *li; 175 Eina_List *li;
172 176
173 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
174 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
175
176 _filter_buffer_unlock_all(ctx); 177 _filter_buffer_unlock_all(ctx);
177 178
178 EINA_LIST_FOREACH(ctx->buffers, li, fb) 179 EINA_LIST_FOREACH(ctx->buffers, li, fb)
@@ -194,9 +195,9 @@ evas_filter_context_program_reuse(Evas_Filter_Context *ctx, Evas_Filter_Program
194 ENFN->rectangle_draw(ENDT, dc, surface, 0, 0, fb->w, fb->h, ctx->async); 195 ENFN->rectangle_draw(ENDT, dc, surface, 0, 0, fb->w, fb->h, ctx->async);
195 ENFN->context_free(ENDT, dc); 196 ENFN->context_free(ENDT, dc);
196 fb->dirty = EINA_FALSE; 197 fb->dirty = EINA_FALSE;
197 }
198 198
199 return evas_filter_context_program_use(ctx, pgm, EINA_TRUE, x, y); 199 evas_ector_buffer_engine_image_release(fb->buffer, surface);
200 }
200} 201}
201 202
202static void 203static void
@@ -268,29 +269,34 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
268{ 269{
269 Evas_Filter_Command *cmd; 270 Evas_Filter_Command *cmd;
270 Evas_Filter_Buffer *fb; 271 Evas_Filter_Buffer *fb;
271 Eina_List *li; 272 Eina_List *li, *li2;
272 unsigned w, h; 273 unsigned w, h;
273 274
274 if (ctx->run_count > 0) return EINA_TRUE;
275
276 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 275 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
277 w = ctx->w; 276 w = ctx->w;
278 h = ctx->h; 277 h = ctx->h;
279 278
280 XDBG("Allocating all buffers based on output size %ux%u", w, h); 279 XDBG("Allocating all buffers based on output size %ux%u", w, h);
281 280
281 EINA_LIST_FOREACH(ctx->buffers, li, fb)
282 fb->cleanup = EINA_TRUE;
283
282 EINA_INLIST_FOREACH(ctx->commands, cmd) 284 EINA_INLIST_FOREACH(ctx->commands, cmd)
283 { 285 {
284 Evas_Filter_Fill_Mode fillmode = cmd->draw.fillmode; 286 Evas_Filter_Fill_Mode fillmode = cmd->draw.fillmode;
285 Evas_Filter_Buffer *in, *out; 287 Evas_Filter_Buffer *in, *out;
286 288
287 in = cmd->input; 289 in = cmd->input;
290 in->cleanup = EINA_FALSE;
288 if (!in->w && !in->h) 291 if (!in->w && !in->h)
289 { 292 {
290 in->w = w; 293 in->w = w;
291 in->h = h; 294 in->h = h;
292 } 295 }
293 296
297 if (cmd->mask)
298 cmd->mask->cleanup = EINA_FALSE;
299
294 // FIXME: No need for stretch buffers with GL! 300 // FIXME: No need for stretch buffers with GL!
295 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY) 301 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)
296 { 302 {
@@ -326,6 +332,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
326 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); 332 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba");
327 if (!fb) goto alloc_fail; 333 if (!fb) goto alloc_fail;
328 fb->transient = EINA_TRUE; 334 fb->transient = EINA_TRUE;
335 fb->cleanup = EINA_FALSE;
329 } 336 }
330 } 337 }
331 338
@@ -342,9 +349,11 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
342 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); 349 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba");
343 if (!fb) goto alloc_fail; 350 if (!fb) goto alloc_fail;
344 fb->transient = EINA_TRUE; 351 fb->transient = EINA_TRUE;
352 fb->cleanup = EINA_FALSE;
345 } 353 }
346 354
347 out = cmd->output; 355 out = cmd->output;
356 out->cleanup = EINA_FALSE;
348 if (!out->w && !out->h) 357 if (!out->w && !out->h)
349 { 358 {
350 out->w = w; 359 out->w = w;
@@ -356,7 +365,12 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
356 { 365 {
357 Eina_Bool render = EINA_FALSE, draw = EINA_FALSE; 366 Eina_Bool render = EINA_FALSE, draw = EINA_FALSE;
358 367
359 if (fb->buffer || fb->source) 368 if (fb->source)
369 {
370 fb->cleanup = EINA_FALSE;
371 continue;
372 }
373 if (fb->buffer || fb->cleanup)
360 continue; 374 continue;
361 375
362 if (!fb->w && !fb->h) 376 if (!fb->w && !fb->h)
@@ -378,6 +392,16 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
378 if (!fb->buffer) goto alloc_fail; 392 if (!fb->buffer) goto alloc_fail;
379 } 393 }
380 394
395 EINA_LIST_FOREACH_SAFE(ctx->buffers, li, li2, fb)
396 {
397 if (fb->cleanup)
398 {
399 XDBG("Cleanup buffer #%d %dx%d %s", fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba");
400 ctx->buffers = eina_list_remove_list(ctx->buffers, li);
401 _buffer_free(fb);
402 }
403 }
404
381 return EINA_TRUE; 405 return EINA_TRUE;
382 406
383alloc_fail: 407alloc_fail:
@@ -527,25 +551,30 @@ evas_filter_buffer_backing_set(Evas_Filter_Context *ctx, int bufid,
527 void *engine_buffer) 551 void *engine_buffer)
528{ 552{
529 Evas_Filter_Buffer *fb; 553 Evas_Filter_Buffer *fb;
554 Eina_Bool ret = EINA_FALSE;
555 Eo *buffer = NULL;
530 556
531 fb = _filter_buffer_get(ctx, bufid); 557 fb = _filter_buffer_get(ctx, bufid);
532 if (!fb) return EINA_FALSE; 558 if (!fb) return EINA_FALSE;
533 559
534 EINA_SAFETY_ON_FALSE_RETURN_VAL(!fb->buffer, EINA_FALSE);
535
536 if (!engine_buffer) 560 if (!engine_buffer)
537 { 561 {
538 fb->buffer = _ector_buffer_create(fb, fb->is_render, EINA_FALSE); 562 buffer = _ector_buffer_create(fb, fb->is_render, EINA_FALSE);
539 XDBG("Allocated buffer #%d of size %ux%u %s: %p", 563 XDBG("Allocated buffer #%d of size %ux%u %s: %p",
540 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer); 564 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
541 return fb->buffer ? EINA_TRUE : EINA_FALSE; 565 ret = buffer ? EINA_TRUE : EINA_FALSE;
566 goto end;
542 } 567 }
543 568
544 if (fb->buffer) return EINA_FALSE; 569 if (fb->is_render) goto end;
545 if (fb->is_render) return EINA_FALSE;
546 570
547 fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, engine_buffer); 571 buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, engine_buffer);
548 return EINA_TRUE; 572 ret = EINA_TRUE;
573
574end:
575 if (fb->buffer != buffer) efl_unref(fb->buffer);
576 fb->buffer = buffer;
577 return ret;
549} 578}
550 579
551Eina_Bool 580Eina_Bool
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index ccf2806b6a..ce1e25ac9d 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -3486,6 +3486,8 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
3486 3486
3487 XDBG("Using program '%s' for context %p", pgm->name, ctx); 3487 XDBG("Using program '%s' for context %p", pgm->name, ctx);
3488 3488
3489 if (reuse) _evas_filter_context_program_reuse(ctx);
3490
3489 // Copy current state (size, edje state val, color class, etc...) 3491 // Copy current state (size, edje state val, color class, etc...)
3490 ctx->w = pgm->state.w; 3492 ctx->w = pgm->state.w;
3491 ctx->h = pgm->state.h; 3493 ctx->h = pgm->state.h;
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 576cef3cca..df02000cb8 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -265,6 +265,7 @@ struct _Evas_Filter_Buffer
265 Eina_Bool locked : 1; // internal flag 265 Eina_Bool locked : 1; // internal flag
266 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it 266 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it
267 Eina_Bool is_render : 1; // Is render target of a filter using engine functions (ie. needs FBO in GL) 267 Eina_Bool is_render : 1; // Is render target of a filter using engine functions (ie. needs FBO in GL)
268 Eina_Bool cleanup : 1; // Needs cleaning up if not allocated
268}; 269};
269 270
270enum _Evas_Filter_Interpolation_Mode 271enum _Evas_Filter_Interpolation_Mode
@@ -295,6 +296,7 @@ Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas
295Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode); 296Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode);
296int evas_filter_smallest_pow2_larger_than(int val); 297int evas_filter_smallest_pow2_larger_than(int val);
297 298
299void _evas_filter_context_program_reuse(Evas_Filter_Context *ctx);
298void evas_filter_parser_shutdown(void); 300void evas_filter_parser_shutdown(void);
299 301
300#define E_READ ECTOR_BUFFER_ACCESS_FLAG_READ 302#define E_READ ECTOR_BUFFER_ACCESS_FLAG_READ
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index ca79b36e1e..f273064ae6 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -148,7 +148,6 @@ Eina_Bool evas_filter_context_async_get(Evas_Filter_Context *ctx)
148void evas_filter_context_size_get(Evas_Filter_Context *ctx, int *w, int *H); 148void evas_filter_context_size_get(Evas_Filter_Context *ctx, int *w, int *H);
149void evas_filter_context_destroy(Evas_Filter_Context *ctx); 149void evas_filter_context_destroy(Evas_Filter_Context *ctx);
150Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, Eina_Bool reuse, int object_x, int object_y); 150Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, Eina_Bool reuse, int object_x, int object_y);
151Eina_Bool evas_filter_context_program_reuse(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, int x, int y);
152void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async); 151void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async);
153void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data); 152void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
154#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx) 153#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
index d948634bc6..108a1c9e8b 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
@@ -5,7 +5,6 @@
5#define ECTOR_GL_BUFFER_BASE_PROTECTED 5#define ECTOR_GL_BUFFER_BASE_PROTECTED
6 6
7#include "evas_common_private.h" 7#include "evas_common_private.h"
8#include "evas_gl_private.h"
9 8
10#include <gl/Ector_GL.h> 9#include <gl/Ector_GL.h>
11#include "gl/ector_gl_private.h" 10#include "gl/ector_gl_private.h"
@@ -17,6 +16,7 @@
17 16
18#include "evas_ector_buffer.eo.h" 17#include "evas_ector_buffer.eo.h"
19#include "evas_ector_gl_buffer.eo.h" 18#include "evas_ector_gl_buffer.eo.h"
19#include "evas_gl_private.h"
20 20
21#define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS 21#define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS
22 22
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
index 3d3bb2eb66..d6be151782 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
@@ -7,7 +7,6 @@
7#define ECTOR_GL_BUFFER_BASE_PROTECTED 7#define ECTOR_GL_BUFFER_BASE_PROTECTED
8 8
9#include "evas_common_private.h" 9#include "evas_common_private.h"
10#include "evas_gl_private.h"
11 10
12#include <gl/Ector_GL.h> 11#include <gl/Ector_GL.h>
13#include "gl/ector_gl_private.h" 12#include "gl/ector_gl_private.h"
@@ -20,6 +19,7 @@
20#include "evas_ector_buffer.eo.h" 19#include "evas_ector_buffer.eo.h"
21#include "evas_ector_gl_buffer.eo.h" 20#include "evas_ector_gl_buffer.eo.h"
22#include "evas_ector_gl_image_buffer.eo.h" 21#include "evas_ector_gl_image_buffer.eo.h"
22#include "evas_gl_private.h"
23 23
24#define MY_CLASS EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS 24#define MY_CLASS EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS
25 25