evas vg: Fixed possible crash in rendering vg object 86/257186/5
authorMichal Szczecinski <m.szczecinsk@partner.samsung.com>
Tue, 20 Apr 2021 12:36:02 +0000 (14:36 +0200)
committerChun <jykeon@samsung.com>
Tue, 27 Apr 2021 00:53:28 +0000 (00:53 +0000)
Current draw solution uses pixels buffer shared between thorVG.
If this buffer is released because of object invalidation and drawing
thread don't finishes his job released buffer pointer is used by thread.
This commit fixes this case.

Change-Id: I736116cbc5b9c61e8d3d45b1b04d8e9345ad10cf

src/lib/evas/canvas/efl_canvas_vg_object.c
src/lib/evas/canvas/evas_vg_private.h

index ea54052..46915ff 100644 (file)
@@ -376,12 +376,6 @@ _efl_canvas_vg_object_efl_object_invalidate(Eo *eo_obj, Efl_Canvas_Vg_Object_Dat
    evas_cache_vg_entry_del(pd->vg_entry);
 
 #ifdef HAVE_THORVG
-   if (pd->im)
-     {
-        ENFN->image_free(_evas_engine_context(obj->layer->evas), pd->im);
-        pd->im = NULL;
-     }
-
    if (pd->tvg_buffer)
      {
         free(pd->tvg_buffer);
@@ -467,18 +461,25 @@ _render_tvg_buffer_to_screen(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Obje
                              void *engine, void *output, void *context, void *surface,
                              void *buffer, int x, int y, int w, int h, Eina_Bool do_async)
 {
-   if (!buffer) return;
+   Eina_Bool async_unref = EINA_FALSE;
+   Image_Entry *image = NULL;
+
+   if (!buffer)
+     return;
+   
+   image = ENFN->image_new_from_copied_data(engine, w, h, buffer, 255, EVAS_COLORSPACE_ARGB8888);
 
-   //FIXE_TVG: Need to use the method original ector surface buffer (tbm or dynamic texture)
-   if (!pd->im) pd->im = ENFN->image_new_from_data(engine, w, h, buffer, 255, EVAS_COLORSPACE_ARGB8888);
-   else pd->im = ENFN->image_data_put(engine, pd->im, buffer);
+   async_unref = ENFN->image_draw(engine, output, context, surface,
+                                  image, 0, 0, w, h, x, y, w, h,
+                                  EINA_TRUE, do_async);
 
-   ENFN->image_dirty_region(engine, pd->im, 0, 0, w, h);
+   if (do_async && async_unref)
+     {
+        evas_cache_image_ref(image);
+        evas_unref_queue_image_put(obj->layer->evas, image);
+     }
 
-   //FIX_TVG: Check _render_buffer_to_screen(): async_unref variable.
-   ENFN->image_draw(engine, output, context, surface,
-                    pd->im, 0, 0, w, h, x, y, w, h,
-                    EINA_TRUE, do_async);
+   ENFN->image_free(engine, image);
 }
 
 #else
@@ -893,13 +894,6 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
         tvg_swcanvas_set_target(pd->tvg_canvas, pd->tvg_buffer,
                                 size.w, size.w, size.h,
                                 TVG_COLORSPACE_ARGB8888);
-
-        //if size is changed im handle also should be deleted
-        if (pd->im)
-          {
-             ENFN->image_free(engine, pd->im);
-             pd->im = NULL;
-          }
      }
 
    Vg_Cache_Entry *vg_entry = pd->vg_entry;
index 49f571a..6fa5a80 100644 (file)
@@ -73,7 +73,6 @@ struct _Efl_Canvas_Vg_Object_Data
    Tvg_Canvas *tvg_canvas;
    Eina_Size2D tvg_canvas_size;
    uint32_t   *tvg_buffer;
-   RGBA_Image *im;
 #endif
 };