diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 77a5a05d9a..c2b923fd2a 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -51,6 +51,7 @@ static int evas_object_image_get_opaque_rect(Evas_Object *eo_obj, void *type_private_data, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); static int evas_object_image_can_map(Evas_Object *eo_obj); +static void evas_object_image_render_prepare(Evas_Object *obj, Evas_Object_Protected_Data *pd); static void evas_object_image_filled_resize_listener(void *data, Evas *eo_e, Evas_Object *eo_obj, void *einfo); @@ -78,6 +79,7 @@ static const Evas_Object_Func object_func = evas_object_image_has_opaque_rect, evas_object_image_get_opaque_rect, evas_object_image_can_map, + evas_object_image_render_prepare, // render_prepare NULL }; @@ -111,6 +113,20 @@ Eina_Cow *evas_object_image_load_opts_cow = NULL; Eina_Cow *evas_object_image_pixels_cow = NULL; Eina_Cow *evas_object_image_state_cow = NULL; +static void +evas_object_image_render_prepare(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) +{ + Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + + // if image data not loaded or in texture then upload + if ((o->cur->u.file) || (o->written) || (o->cur->frame != 0)) + { + if (o->engine_data) ENFN->image_prepare(ENDT, o->engine_data); + return; + } + // XXX: if image is a proxy, PREPEND to prerender list in evas canvas +} + void _evas_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o) { diff --git a/src/lib/evas/canvas/evas_object_line.c b/src/lib/evas/canvas/evas_object_line.c index 00d8076402..d5fc7b3a11 100644 --- a/src/lib/evas/canvas/evas_object_line.c +++ b/src/lib/evas/canvas/evas_object_line.c @@ -85,6 +85,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_polygon.c b/src/lib/evas/canvas/evas_object_polygon.c index 7ed779b208..355f6ea378 100644 --- a/src/lib/evas/canvas/evas_object_polygon.c +++ b/src/lib/evas/canvas/evas_object_polygon.c @@ -75,6 +75,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_rectangle.c b/src/lib/evas/canvas/evas_object_rectangle.c index 50a92481b6..6c0fe9e3f5 100644 --- a/src/lib/evas/canvas/evas_object_rectangle.c +++ b/src/lib/evas/canvas/evas_object_rectangle.c @@ -83,6 +83,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare evas_object_rectangle_render2_walk }; diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 46899510aa..51338c5ab6 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -119,6 +119,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c index 2e8c2f7d0d..fbd9b241b4 100644 --- a/src/lib/evas/canvas/evas_object_text.c +++ b/src/lib/evas/canvas/evas_object_text.c @@ -143,6 +143,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 29d8cb9ed7..6451d7ba02 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -622,6 +622,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c index 1942a4c570..e98be126ba 100644 --- a/src/lib/evas/canvas/evas_object_textgrid.c +++ b/src/lib/evas/canvas/evas_object_textgrid.c @@ -144,6 +144,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_object_vg.c b/src/lib/evas/canvas/evas_object_vg.c index 5617f9f5ad..ae89f1ac16 100644 --- a/src/lib/evas/canvas/evas_object_vg.c +++ b/src/lib/evas/canvas/evas_object_vg.c @@ -57,6 +57,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, // render_prepare NULL }; diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index e1542fac63..a807278e36 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -2725,7 +2725,16 @@ evas_render_updates_internal(Evas *eo_e, e->engine.func->output_redraws_rect_del(e->engine.data.output, r->x, r->y, r->w, r->h); } - /* build obscure objects list of active objects that obscure */ + + static int prepare = -1; + if (prepare == -1) + { + if (getenv("EVAS_PREPARE")) prepare = !!atoi(getenv("EVAS_PREPARE")); + else prepare = 1; + } + /* build obscure objects list of active objects that obscure as well + * as objects that may need data (image data loads, texture updates, + * pre-render buffers/fbo's etc.) that are not up to date yet */ for (i = 0; i < e->active_objects.count; ++i) { obj = eina_array_data_get(&e->active_objects, i); @@ -2742,6 +2751,11 @@ evas_render_updates_internal(Evas *eo_e, (!obj->is_smart))) /* obscuring_objects = eina_list_append(obscuring_objects, obj); */ OBJ_ARRAY_PUSH(&e->obscuring_objects, obj); + if (prepare) + { + if (obj->func->render_prepare) + obj->func->render_prepare(eo_obj, obj); + } } eina_evlog("-render_phase5", eo_e, 0.0, NULL); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 65e7023a2c..398109cfd9 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1289,6 +1289,10 @@ struct _Evas_Object_Func Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); int (*can_map) (Evas_Object *obj); +// new - add to prepare list during render if object needs some pre-render +// preparation - may include rendering content to buffer or loading data +// from disk or uploading to texture etc. + void (*render_prepare) (Evas_Object *obj, Evas_Object_Protected_Data *pd); // new render2 functions @@ -1384,6 +1388,8 @@ struct _Evas_Func /* new api for direct data set (not put) */ void *(*image_data_slice_add) (void *data, void *image, const Eina_Slice *slice, Eina_Bool copy, int w, int h, int stride, Evas_Colorspace space, int plane, Eina_Bool alpha); + void (*image_prepare) (void *data, void *image); + int (*image_native_init) (void *data, Evas_Native_Surface_Type type); void (*image_native_shutdown) (void *data, Evas_Native_Surface_Type type); void *(*image_native_set) (void *data, void *image, void *native); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 8cff9b926f..09cc24bc38 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -3089,6 +3089,16 @@ fail: return NULL; } +static void +eng_image_prepare(void *engdata EINA_UNUSED, void *image) +{ + Evas_GL_Image *im = image; + + if (!im) return; + evas_gl_common_image_update(im->gc, im); +} + + static int module_open(Evas_Module *em) { @@ -3174,6 +3184,8 @@ module_open(Evas_Module *em) ORD(image_data_maps_get); ORD(image_data_slice_add); + ORD(image_prepare); + ORD(font_cache_flush); ORD(font_cache_set); ORD(font_cache_get); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index baf3e46d8d..0ea4cf2a3e 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1937,6 +1937,14 @@ fail: return NULL; } +static void +eng_image_prepare(void *engdata EINA_UNUSED, void *image EINA_UNUSED) +{ + // software rendering doesnt want/need to prepare at this point + // XXX: though this could push along any loading threads or start + // some thread jobs for loading in the bg. +} + static void _image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih) @@ -4649,6 +4657,7 @@ static Evas_Func func = eng_image_data_unmap, eng_image_data_maps_get, eng_image_data_slice_add, + eng_image_prepare, eng_image_native_init, eng_image_native_shutdown, eng_image_native_set,