On Tue, 18 Jul 2017 21:57:23 -0700 Jean-Philippe ANDRÉ <j...@videolan.org> said:
After much bisecting late into the evening... this patch broke enlightenment and makes it reliably crash when you run virtualbox... in texture uploading a seemingly garbage pointer in the image data... at least for now this is a note to "look into this" ... filing > jpeg pushed a commit to branch master. > > http://git.enlightenment.org/core/efl.git/commit/?id=45c8e5e983d24b23b244513087799edcda862411 > > commit 45c8e5e983d24b23b244513087799edcda862411 > Author: Jean-Philippe Andre <jp.an...@samsung.com> > Date: Wed Jul 19 11:43:35 2017 +0900 > > evas: Fix support for image_data_get on snapshot > > evas_object_image_data_get() is a legacy API that I made work > with snapshot objects (evas_object_image_snapshot_set()). Some > changes in the engine broke the behaviour and this patch fixes > it. > > When getting the pixels from an FBO, in read-only mode, we need > to create a temporary image (pixels surface) that contains the > copy of the pixels we get from glReadPixels. This image needs > to be deleted afterwards. It is thus stored by the image object > and freed upon _image_data_set() (good) or object deletion (bad). > > FBO + read-write is not supported by this API (it is supported > through buffer_map as the filters had to use that). > > Fixes T5754 > --- > src/lib/evas/canvas/evas_image_legacy.c | 84 ++++++++++++++++++++++++++ > +----- src/lib/evas/canvas/evas_image_private.h | 1 + > src/lib/evas/canvas/evas_object_image.c | 7 +++ > 3 files changed, 79 insertions(+), 13 deletions(-) > > diff --git a/src/lib/evas/canvas/evas_image_legacy.c > b/src/lib/evas/canvas/evas_image_legacy.c index a8593db29b..3f69dca4e6 100644 > --- a/src/lib/evas/canvas/evas_image_legacy.c > +++ b/src/lib/evas/canvas/evas_image_legacy.c > @@ -14,6 +14,14 @@ > EVAS_IMAGE_API(_o, __VA_ARGS__); \ > } while (0) > > +typedef struct _Evas_Image_Legacy_Pixels_Entry > Evas_Image_Legacy_Pixels_Entry; + > +struct _Evas_Image_Legacy_Pixels_Entry > +{ > + Eo *object; > + void *image; > +}; > + > EAPI Evas_Object * > evas_object_image_add(Evas *eo_e) > { > @@ -552,7 +560,7 @@ evas_object_image_data_set(Eo *eo_obj, void *data) > > Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, > EFL_CANVAS_OBJECT_CLASS); Evas_Image_Data *o = efl_data_scope_get(eo_obj, > EFL_CANVAS_IMAGE_INTERNAL_CLASS); > - void *p_data; > + void *p_data, *pixels; > Eina_Bool resize_call = EINA_FALSE; > > > @@ -563,6 +571,13 @@ evas_object_image_data_set(Eo *eo_obj, void *data) > p_data = o->engine_data; > if (data) > { > + // r/o FBO data_get: only free the image, don't update pixels > + if ((pixels = eina_hash_find(o->pixels->images_to_free, data)) != > NULL) > + { > + eina_hash_del(o->pixels->images_to_free, data, pixels); > + return; > + } > + > if (o->engine_data) > { > o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, > data); @@ -640,14 +655,28 @@ evas_object_image_data_set(Eo *eo_obj, void > *data) if (resize_call) evas_object_inform_call_image_resize(eo_obj); > } > > +static void > +_image_to_free_del_cb(void *data) > +{ > + Evas_Image_Legacy_Pixels_Entry *px_entry = data; > + Evas_Object_Protected_Data *obj; > + > + obj = efl_data_scope_safe_get(px_entry->object, EFL_CANVAS_OBJECT_CLASS); > + EINA_SAFETY_ON_NULL_RETURN(obj); > + ENFN->image_free(ENDT, px_entry->image); > + free(px_entry); > +} > + > EAPI void* > evas_object_image_data_get(const Eo *eo_obj, Eina_Bool for_writing) > { > EVAS_IMAGE_API(eo_obj, NULL); > > Evas_Image_Data *o = efl_data_scope_get(eo_obj, > EFL_CANVAS_IMAGE_INTERNAL_CLASS); > + Evas_Image_Legacy_Pixels_Entry *px_entry = NULL; > + Eina_Bool tofree = 0; > + void *pixels = NULL; > int stride = 0; > - void *pixels; > DATA32 *data; > > if (!o->engine_data) return NULL; > @@ -662,25 +691,48 @@ evas_object_image_data_get(const Eo *eo_obj, Eina_Bool > for_writing) ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); > if (ENFN->image_content_hint_set) > ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); > - pixels = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, > &o->load_error, NULL); > + pixels = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, > &o->load_error, &tofree); > /* if we fail to get engine_data, we have to return NULL */ > if (!pixels) return NULL; > > - o->engine_data = pixels; > - if (ENFN->image_stride_get) > - ENFN->image_stride_get(ENDT, o->engine_data, &stride); > - else > - stride = o->cur->image.w * 4; > + if (!tofree) > + { > + o->engine_data = pixels; > + if (ENFN->image_stride_get) > + ENFN->image_stride_get(ENDT, o->engine_data, &stride); > + else > + stride = o->cur->image.w * 4; > > - if (o->cur->image.stride != stride) > + if (o->cur->image.stride != stride) > + { > + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) > + state_write->image.stride = stride; > + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); > + } > + > + o->pixels_checked_out++; > + } > + else > { > - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) > - state_write->image.stride = stride; > - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); > + Eina_Hash *hash = o->pixels->images_to_free; > + > + if (!hash) > + { > + hash = eina_hash_pointer_new(_image_to_free_del_cb); > + if (!hash) goto error; > + EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) > + pixi_write->images_to_free = hash; > + EINA_COW_PIXEL_WRITE_END(o, pixi_write); > + } > + > + px_entry = calloc(1, sizeof(*px_entry)); > + px_entry->object = (Eo *) eo_obj; > + px_entry->image = pixels; > + if (!eina_hash_add(hash, data, px_entry)) > + goto error; > } > > - o->pixels_checked_out++; > if (for_writing) > { > o->written = EINA_TRUE; > @@ -688,6 +740,12 @@ evas_object_image_data_get(const Eo *eo_obj, Eina_Bool > for_writing) } > > return data; > + > +error: > + free(px_entry); > + if (tofree && pixels) > + ENFN->image_free(ENDT, pixels); > + return NULL; > } > > EAPI void > diff --git a/src/lib/evas/canvas/evas_image_private.h > b/src/lib/evas/canvas/evas_image_private.h index 67cfee41d1..91c7e22af1 100644 > --- a/src/lib/evas/canvas/evas_image_private.h > +++ b/src/lib/evas/canvas/evas_image_private.h > @@ -61,6 +61,7 @@ struct _Evas_Object_Image_Pixels > Evas_Object_Image_Pixels_Get_Cb get_pixels; > void *get_pixels_data; > } func; > + Eina_Hash *images_to_free; /* pixel void* -> > Evas_Image_Legacy_Pixels_Entry */ > Evas_Video_Surface video; > unsigned int video_caps; > diff --git a/src/lib/evas/canvas/evas_object_image.c > b/src/lib/evas/canvas/evas_object_image.c index c522742d7a..5506290ba6 100644 > --- a/src/lib/evas/canvas/evas_object_image.c > +++ b/src/lib/evas/canvas/evas_object_image.c > @@ -1511,6 +1511,13 @@ evas_object_image_free(Evas_Object *eo_obj, > Evas_Object_Protected_Data *obj) efl_del(o->file_obj); > o->file_obj = NULL; > } > + if (o->pixels->images_to_free) > + { > + eina_hash_free(o->pixels->images_to_free); > + EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) > + pixi_write->images_to_free = NULL; > + EINA_COW_PIXEL_WRITE_END(o, pixi_write); > + } > if (o->pixels->pixel_updates) > { > EINA_COW_PIXEL_WRITE_BEGIN(o, pixi_write) > > -- > > -- ------------- Codito, ergo sum - "I code, therefore I am" -------------- The Rasterman (Carsten Haitzler) ras...@rasterman.com ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel