evas/async_render: do not use async event to unref images

Patch by: Leandro Pereira <leandro@profusion.mobi>



SVN revision: 82661
This commit is contained in:
Leandro Pereira 2013-01-11 19:54:12 +00:00 committed by Ulisses Furquim
parent a868276f11
commit ed79c2182e
9 changed files with 91 additions and 46 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 :*/

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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