summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/evas/canvas/evas_filter_mixin.c3
-rw-r--r--src/lib/evas/filters/evas_filter.c145
-rw-r--r--src/lib/evas/filters/evas_filter_private.h3
3 files changed, 36 insertions, 115 deletions
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c
index 46bf5fe2e1..2722a484d6 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -238,8 +238,7 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
238 238
239 // Steal output and release previous 239 // Steal output and release previous
240 filter_output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID); 240 filter_output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
241 if (filter_output != previous) 241 evas_filter_buffer_backing_release(filter, previous);
242 evas_filter_buffer_backing_release(filter, previous);
243 242
244 // Request rendering from the object itself (child class) 243 // Request rendering from the object itself (child class)
245 evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b); 244 evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index bd2ccfc946..484f44d65e 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -125,38 +125,21 @@ _filter_buffer_backing_free(Evas_Filter_Buffer *fb)
125{ 125{
126 if (!fb) return; 126 if (!fb) return;
127 127
128 if (!fb->stolen) 128 _backing_free(fb->ctx, fb->backing);
129 { 129 if (fb->glimage)
130 if (fb->allocated) 130 fb->ENFN->image_free(fb->ENDT, fb->glimage);
131 _backing_free(fb->ctx, fb->backing); 131 fb->backing = NULL;
132 if (fb->glimage && fb->allocated_gl) 132 fb->glimage = NULL;
133 fb->ENFN->image_free(fb->ENDT, fb->glimage);
134 fb->backing = NULL;
135 fb->glimage = NULL;
136 }
137 else
138 {
139 if (!fb->ctx->gl_engine)
140 {
141 fb->delete_me = fb->allocated;
142 }
143 else if (fb->glimage && fb->allocated)
144 {
145 _backing_free(fb->ctx, fb->backing);
146 fb->backing = NULL;
147 }
148 }
149} 133}
150 134
151/* GL engine stuff: read-back from texture */ 135/* GL engine stuff: read-back from texture */
152static Eina_Bool 136static Eina_Bool
153_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb) 137_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
154{ 138{
155 Eina_Bool ok; 139 Eina_Bool ok;
156 140
157 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 141 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
158 EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->ctx->gl_engine, EINA_FALSE); 142 EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->ctx->gl_engine, EINA_FALSE);
159 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->glimage, EINA_FALSE);
160 143
161 if (fb->backing) 144 if (fb->backing)
162 return EINA_TRUE; 145 return EINA_TRUE;
@@ -166,17 +149,16 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb)
166 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE); 149 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
167 150
168 fb->backing = _rgba_image_alloc(fb, NULL); 151 fb->backing = _rgba_image_alloc(fb, NULL);
169 fb->allocated = EINA_TRUE;
170 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE); 152 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE);
171 153
172 ok = fb->ENFN->gl_surface_lock(fb->ENDT, fb->glimage); 154 ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage);
173 if (!ok) 155 if (!ok)
174 { 156 {
175 ERR("Failed to lock the image pixels"); 157 ERR("Failed to lock the image pixels");
176 return EINA_FALSE; 158 return EINA_FALSE;
177 } 159 }
178 160
179 ok = fb->ENFN->gl_surface_read_pixels(fb->ENDT, fb->glimage, 161 ok = fb->ENFN->gl_surface_read_pixels(fb->ENDT, glimage,
180 0, 0, fb->w, fb->h, fb->alpha_only 162 0, 0, fb->w, fb->h, fb->alpha_only
181 ? EVAS_COLORSPACE_GRY8 163 ? EVAS_COLORSPACE_GRY8
182 : EVAS_COLORSPACE_ARGB8888, 164 : EVAS_COLORSPACE_ARGB8888,
@@ -184,7 +166,7 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb)
184 if (!ok) 166 if (!ok)
185 ERR("Could not read the image pixels!"); 167 ERR("Could not read the image pixels!");
186 168
187 ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, fb->glimage); 169 ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage);
188 return ok; 170 return ok;
189} 171}
190 172
@@ -212,19 +194,6 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
212 { 194 {
213 XDBG("Source already rendered: '%s' of type '%s'", 195 XDBG("Source already rendered: '%s' of type '%s'",
214 fb->source_name, eo_class_name_get(eo_class_get(fb->source))); 196 fb->source_name, eo_class_name_get(eo_class_get(fb->source)));
215 _filter_buffer_backing_free(fb);
216 if (!ctx->gl_engine)
217 {
218 fb->backing = source->proxy->surface;
219 fb->allocated = EINA_FALSE;
220 }
221 else
222 {
223 fb->glimage = source->proxy->surface;
224 fb->allocated_gl = EINA_FALSE;
225 _filter_buffer_glimage_pixels_read(fb);
226 }
227 fb->alpha_only = EINA_FALSE;
228 } 197 }
229 else 198 else
230 { 199 {
@@ -232,20 +201,16 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
232 fb->source_name, eo_class_name_get(eo_class_get(fb->source)), 201 fb->source_name, eo_class_name_get(eo_class_get(fb->source)),
233 source->proxy->redraw ? "redraw" : "no surface"); 202 source->proxy->redraw ? "redraw" : "no surface");
234 evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async); 203 evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
235 _filter_buffer_backing_free(fb);
236 if (!ctx->gl_engine)
237 {
238 fb->backing = source->proxy->surface;
239 fb->allocated = EINA_FALSE;
240 }
241 else
242 {
243 fb->glimage = source->proxy->surface;
244 fb->allocated_gl = EINA_FALSE;
245 _filter_buffer_glimage_pixels_read(fb);
246 }
247 fb->alpha_only = EINA_FALSE;
248 } 204 }
205 _filter_buffer_backing_free(fb);
206 if (!ctx->gl_engine)
207 fb->backing = ENFN->image_ref(ENDT, source->proxy->surface);
208 else
209 {
210 fb->glimage = ENFN->image_ref(ENDT, source->proxy->surface);
211 _filter_buffer_glimage_pixels_read(fb, fb->glimage);
212 }
213 fb->alpha_only = EINA_FALSE;
249 XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id); 214 XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
250 } 215 }
251} 216}
@@ -442,9 +407,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
442 407
443 EINA_LIST_FOREACH(ctx->buffers, li, fb) 408 EINA_LIST_FOREACH(ctx->buffers, li, fb)
444 { 409 {
445 RGBA_Image *im; 410 if (fb->backing || fb->source || fb->glimage)
446 im = fb->backing;
447 if (im || fb->source || fb->glimage)
448 continue; 411 continue;
449 412
450 if (!fb->w && !fb->h) 413 if (!fb->w && !fb->h)
@@ -454,11 +417,8 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
454 } 417 }
455 418
456 XDBG("Allocating buffer of size %ux%u %s", fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba"); 419 XDBG("Allocating buffer of size %ux%u %s", fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba");
457 im = _rgba_image_alloc(fb, NULL); 420 fb->backing = _rgba_image_alloc(fb, NULL);
458 if (!im) goto alloc_fail; 421 if (!fb->backing) goto alloc_fail;
459
460 fb->backing = im;
461 fb->allocated = (im != NULL);
462 } 422 }
463 423
464 return EINA_TRUE; 424 return EINA_TRUE;
@@ -506,8 +466,7 @@ _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
506 fb->h = h; 466 fb->h = h;
507 467
508 fb->backing = _rgba_image_alloc(fb, data); 468 fb->backing = _rgba_image_alloc(fb, data);
509 fb->allocated = (fb->backing != NULL); 469 return (fb->backing != NULL);
510 return fb->allocated;
511} 470}
512 471
513int 472int
@@ -516,6 +475,8 @@ evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
516 Evas_Filter_Buffer *fb; 475 Evas_Filter_Buffer *fb;
517 476
518 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 477 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
478
479 image = ENFN->image_ref(ENDT, image);
519 EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1); 480 EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
520 481
521 fb = calloc(1, sizeof(Evas_Filter_Buffer)); 482 fb = calloc(1, sizeof(Evas_Filter_Buffer));
@@ -523,16 +484,10 @@ evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
523 484
524 fb->id = ++(ctx->last_buffer_id); 485 fb->id = ++(ctx->last_buffer_id);
525 fb->ctx = ctx; 486 fb->ctx = ctx;
526 if (!fb->ctx->gl_engine) 487 if (!ctx->gl_engine)
527 { 488 fb->backing = image;
528 fb->backing = image;
529 fb->allocated = EINA_FALSE;
530 }
531 else 489 else
532 { 490 fb->glimage = image;
533 fb->glimage = image;
534 fb->allocated_gl = EINA_FALSE;
535 }
536 ENFN->image_size_get(ENDT, image, &fb->w, &fb->h); 491 ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
537 fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image) 492 fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
538 == EVAS_COLORSPACE_GRY8); 493 == EVAS_COLORSPACE_GRY8);
@@ -602,47 +557,26 @@ evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
602void * 557void *
603evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid) 558evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
604{ 559{
605 Evas_Filter_Buffer *buffer; 560 Evas_Filter_Buffer *fb;
606 561
607 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); 562 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
608 563
609 buffer = _filter_buffer_get(ctx, bufid); 564 fb = _filter_buffer_get(ctx, bufid);
610 if (!buffer) return NULL; 565 if (!fb) return NULL;
611
612 // we don't hold any reference on this buffer anymore
613 buffer->stolen = EINA_TRUE;
614 566
615 if (ctx->gl_engine) 567 if (ctx->gl_engine)
616 return buffer->glimage; 568 return fb->ENFN->image_ref(fb->ENDT, fb->glimage);
617 569 else
618 return buffer->backing; 570 return fb->ENFN->image_ref(fb->ENDT, fb->backing);
619} 571}
620 572
621Eina_Bool 573Eina_Bool
622evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, 574evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
623 void *stolen_buffer) 575 void *stolen_buffer)
624{ 576{
625 Evas_Filter_Buffer *fb;
626 Eina_List *li;
627
628 if (!stolen_buffer) return EINA_FALSE; 577 if (!stolen_buffer) return EINA_FALSE;
629 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 578 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
630 579
631 EINA_LIST_FOREACH(ctx->buffers, li, fb)
632 {
633 if ((fb->backing == stolen_buffer) || (fb->glimage == stolen_buffer))
634 {
635 fb->stolen = EINA_FALSE;
636 if (fb->delete_me)
637 {
638 ctx->buffers = eina_list_remove_list(ctx->buffers, li);
639 _buffer_free(fb);
640 return EINA_TRUE;
641 }
642 return EINA_TRUE;
643 }
644 }
645
646 if (ctx->async) 580 if (ctx->async)
647 evas_unref_queue_image_put(ctx->evas, stolen_buffer); 581 evas_unref_queue_image_put(ctx->evas, stolen_buffer);
648 else if (ctx->gl_engine) 582 else if (ctx->gl_engine)
@@ -1710,13 +1644,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1710 EINA_TRUE, do_async); 1644 EINA_TRUE, do_async);
1711 if (do_async && async_unref) 1645 if (do_async && async_unref)
1712 { 1646 {
1713#ifdef EVAS_CSERVE2 1647 ENFN->image_ref(ENDT, image);
1714 if (evas_cserve2_use_get())
1715 evas_cache2_image_ref((Image_Entry *)image);
1716 else
1717#endif
1718 evas_cache_image_ref((Image_Entry *)image);
1719
1720 evas_unref_queue_image_put(ctx->evas, image); 1648 evas_unref_queue_image_put(ctx->evas, image);
1721 } 1649 }
1722 } 1650 }
@@ -1726,10 +1654,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1726 1654
1727 fb = _filter_buffer_get(ctx, bufid); 1655 fb = _filter_buffer_get(ctx, bufid);
1728 _filter_buffer_backing_free(fb); 1656 _filter_buffer_backing_free(fb);
1729 fb->glimage = image; 1657 _filter_buffer_glimage_pixels_read(fb, image);
1730 fb->allocated_gl = EINA_FALSE;
1731 _filter_buffer_glimage_pixels_read(fb);
1732 fb->glimage = NULL;
1733 } 1658 }
1734 1659
1735 return EINA_TRUE; 1660 return EINA_TRUE;
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 683e35a8d0..5770972b6b 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -237,11 +237,8 @@ struct _Evas_Filter_Buffer
237 Evas_Object *proxy; 237 Evas_Object *proxy;
238 238
239 Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) 239 Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA)
240 Eina_Bool allocated : 1; // allocated on demand, belongs to this context
241 Eina_Bool allocated_gl : 1; // allocated on demand the glimage
242 Eina_Bool transient : 1; // temporary buffer (automatic allocation) 240 Eina_Bool transient : 1; // temporary buffer (automatic allocation)
243 Eina_Bool locked : 1; // internal flag 241 Eina_Bool locked : 1; // internal flag
244 Eina_Bool stolen : 1; // stolen by the client
245 Eina_Bool delete_me : 1; // request delete asap (after released by client) 242 Eina_Bool delete_me : 1; // request delete asap (after released by client)
246 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it 243 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it
247}; 244};