diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index e8f45ffcd2..7e838ba241 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -142,6 +142,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED) EVAS_ARRAY_SET(e, temporary_objects); EVAS_ARRAY_SET(e, calculate_objects); EVAS_ARRAY_SET(e, clip_changes); + EVAS_ARRAY_SET(e, image_unref_queue); #undef EVAS_ARRAY_SET } @@ -247,6 +248,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED) eina_array_flush(&e->temporary_objects); eina_array_flush(&e->calculate_objects); eina_array_flush(&e->clip_changes); + eina_array_flush(&e->image_unref_queue); EINA_LIST_FREE(e->touch_points, touch_point) free(touch_point); diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index a18bf5c119..655800014a 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -3137,6 +3137,33 @@ evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) eina_rectangle_free(r); } +static void +_draw_image(Evas_Object_Protected_Data *obj, + void *data, void *context, void *surface, void *image, + int src_x, int src_y, int src_w, int src_h, int dst_x, + int dst_y, int dst_w, int dst_h, int smooth, + Eina_Bool do_async) +{ + Eina_Bool async_unref; + + async_unref = obj->layer->evas->engine.func->image_draw(data, context, surface, + image, src_x, src_y, + src_w, src_h, dst_x, + dst_y, dst_w, dst_h, + smooth, do_async); + if (do_async && async_unref) + { +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_ref((Image_Entry *)image); + else +#endif + evas_cache_image_ref((Image_Entry *)image); + + evas_unref_queue_image_put(obj->layer->evas, image); + } +} + static void evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { @@ -3360,8 +3387,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v h = ih; } - obj->layer->evas->engine.func->image_draw - (output, context, surface, data, + _draw_image + (obj, output, context, surface, data, 0, 0, w, h, obj->cur.geometry.x + ix + x, @@ -3373,8 +3400,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v else #endif { - obj->layer->evas->engine.func->image_draw - (output, context, surface, pixels, + _draw_image + (obj, output, context, surface, pixels, 0, 0, imagew, imageh, obj->cur.geometry.x + ix + x, @@ -3435,28 +3462,28 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v inw = bl; inh = bt; outx = ox; outy = oy; outw = bsl; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .## // | inx = bl; iny = 0; inw = imw - bl - br; inh = bt; outx = ox + bsl; outy = oy; outw = iw - bsl - bsr; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // --# // | inx = imw - br; iny = 0; inw = br; inh = bt; outx = ox + iw - bsr; outy = oy; outw = bsr; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .-- // # inx = 0; iny = bt; inw = bl; inh = imh - bt - bb; outx = ox; outy = oy + bst; outw = bsl; outh = ih - bst - bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .--. // |##| if (o->cur.border.fill > EVAS_BORDER_FILL_NONE) @@ -3471,12 +3498,12 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v { obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_COPY); - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); obj->layer->evas->engine.func->context_render_op_set(output, context, obj->cur.render_op); } else - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); } // --. // # @@ -3484,28 +3511,28 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v inw = br; inh = imh - bt - bb; outx = ox + iw - bsr; outy = oy + bst; outw = bsr; outh = ih - bst - bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // #-- inx = 0; iny = imh - bb; inw = bl; inh = bb; outx = ox; outy = oy + ih - bsb; outw = bsl; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // .## inx = bl; iny = imh - bb; inw = imw - bl - br; inh = bb; outx = ox + bsl; outy = oy + ih - bsb; outw = iw - bsl - bsr; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // --# inx = imw - br; iny = imh - bb; inw = br; inh = bb; outx = ox + iw - bsr; outy = oy + ih - bsb; outw = bsr; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); + _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); } idy += idh; if (dobreak_h) break; diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 495caf79f9..a20e624048 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1306,6 +1306,19 @@ evas_render_rendering_wait(Evas_Public_Data *evas) while (evas->rendering) evas_async_events_process_blocking(); } +static Eina_Bool +_drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED) +{ +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_close((Image_Entry *)data); + else +#endif + evas_cache_image_drop((Image_Entry *)data); + + return EINA_TRUE; +} + static Eina_Bool evas_render_updates_internal(Evas *eo_e, unsigned char make_updates, @@ -1855,6 +1868,10 @@ evas_render_wakeup(Evas *eo_e) /* clear redraws */ e->engine.func->output_redraws_clear(e->engine.data.output); + /* unref queue */ + eina_array_foreach(&e->image_unref_queue, _drop_image_cache_ref, NULL); + eina_array_clean(&e->image_unref_queue); + evas_event_callback_call(eo_e, EVAS_CALLBACK_RENDER_POST, NULL); if (e->render.updates_cb) @@ -2126,4 +2143,10 @@ evas_render_object_recalc(Evas_Object *eo_obj) } } +void +evas_unref_queue_image_put(Evas_Public_Data *pd, void *image) +{ + eina_array_push(&pd->image_unref_queue, image); +} + /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 876401dc42..20aa6a4d92 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -386,6 +386,7 @@ struct _Evas_Public_Data Eina_Array temporary_objects; Eina_Array calculate_objects; Eina_Array clip_changes; + Eina_Array image_unref_queue; Eina_Clist calc_list; Eina_Clist calc_done; @@ -818,7 +819,7 @@ struct _Evas_Func int (*image_alpha_get) (void *data, void *image); void *(*image_border_set) (void *data, void *image, int l, int r, int t, int b); void (*image_border_get) (void *data, void *image, int *l, int *r, int *t, int *b); - void (*image_draw) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async); + Eina_Bool (*image_draw) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async); char *(*image_comment_get) (void *data, void *image, char *key); char *(*image_format_get) (void *data, void *image); void (*image_colorspace_set) (void *data, void *image, int cspace); @@ -1048,6 +1049,7 @@ void evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, void _evas_object_text_rehint(Evas_Object *obj); void _evas_object_textblock_rehint(Evas_Object *obj); +void evas_unref_queue_image_put(Evas_Public_Data *pd, void *image); void _freeze_events_set(Eo *obj, void *_pd, va_list *list); void _freeze_events_get(Eo *obj, void *_pd, va_list *list); diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.c b/src/modules/evas/engines/gl_cocoa/evas_engine.c index 9d07c7da60..be7c2da6fe 100644 --- a/src/modules/evas/engines/gl_cocoa/evas_engine.c +++ b/src/modules/evas/engines/gl_cocoa/evas_engine.c @@ -869,13 +869,13 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t evas_cache_image_preload_cancel(&im->cache_entry, target); } -static void +static Eina_Bool eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; re = (Render_Engine *)data; - if (!image) return; + if (!image) return EINA_FALSE; eng_window_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; @@ -883,6 +883,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, smooth); + return EINA_FALSE; } static void diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index 407d513321..ccdff062a5 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -808,19 +808,20 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t evas_cache_image_preload_cancel(&im->cache_entry, target); } -static void +static Eina_Bool eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; re = (Render_Engine *)data; - if (!image) return; + if (!image) return EINA_FALSE; evas_gl_common_context_target_surface_set(re->gl_context, surface); re->gl_context->dc = context; evas_gl_common_image_draw(re->gl_context, image, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, smooth); + return EINA_FALSE; } static void diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index e6e76b119e..1da81dd6b0 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -2433,7 +2433,7 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t evas_cache_image_preload_cancel(&im->cache_entry, target); } -static void +static Eina_Bool eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; @@ -2441,7 +2441,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, Evas_GL_Image *im = image; Native *n; - if (!im) return; + if (!im) return EINA_FALSE; n = im->native.data; if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) && @@ -2461,6 +2461,8 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, dst_x, dst_y, dst_w, dst_h, smooth); } + + return EINA_FALSE; } static void diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index e3671fd411..b2b5fa9f53 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1153,17 +1153,6 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t evas_cache_image_preload_cancel(&im->cache_entry, target); } -static void -_drop_cache_ref(void *target, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) -{ -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_close((Image_Entry *)target); - else -#endif - evas_cache_image_drop((Image_Entry *)target); -} - static void draw_thread_image_draw(void *data) { @@ -1184,7 +1173,6 @@ draw_thread_image_draw(void *data) image->src.x, image->src.y, image->src.w, image->src.h, image->dst.x, image->dst.y, image->dst.w, image->dst.h); - evas_async_events_put(image->image, 0, NULL, _drop_cache_ref); eina_mempool_free(_mp_command_image, image); } @@ -1198,15 +1186,8 @@ _image_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) return; -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_ref((Image_Entry *)src); - else -#endif - evas_cache_image_ref((Image_Entry *)src); - cr = eina_mempool_malloc(_mp_command_image, sizeof (Evas_Thread_Command_Image)); - if (!cr) return ; + if (!cr) return; cr->image = src; cr->surface = dst; @@ -1257,12 +1238,12 @@ _image_draw_thread_cmd_sample(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Contex 0); } -static void +static Eina_Bool eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async) { RGBA_Image *im; - if (!image) return; + if (!image) return EINA_FALSE; im = image; if (do_async) @@ -1276,7 +1257,7 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image #endif evas_cache_image_load_data(&im->cache_entry); - if (!im->cache_entry.flags.loaded) return; + if (!im->cache_entry.flags.loaded) return EINA_FALSE; } evas_common_image_colorspace_normalize(im); @@ -1293,6 +1274,8 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, _image_draw_thread_cmd_sample); + + return EINA_TRUE; } #ifdef BUILD_PIPE_RENDER else if ((cpunum > 1)) @@ -1361,6 +1344,8 @@ image_loaded: evas_common_cpu_end_opt(); } + + return EINA_FALSE; } static void diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 5b7887f958..e0209b4b37 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -1885,13 +1885,13 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t evas_cache_image_preload_cancel(&im->cache_entry, target); } -static void +static Eina_Bool eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; re = (Render_Engine *)data; - if (!image) return; + if (!image) return EINA_FALSE; if ((gl_direct_img_obj) && (gl_direct_enabled)) evas_object_image_pixels_dirty_set(gl_direct_img_obj, EINA_TRUE); @@ -1905,6 +1905,8 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, dst_x, dst_y, dst_w, dst_h, smooth); } + + return EINA_FALSE; } static void