canvas vg: recover the origin code to allocate optimial canvas size while it keeps... 94/259794/8
authorHermet Park <chuneon.park@samsung.com>
Mon, 14 Jun 2021 10:28:45 +0000 (19:28 +0900)
committerHermet Park <chuneon.park@samsung.com>
Tue, 15 Jun 2021 07:52:18 +0000 (07:52 +0000)
Change-Id: I927a55aec6ca236bed8fbda5268ae4303c141707

src/lib/evas/canvas/efl_canvas_vg_object.c

index 761b7eb..eccd625 100644 (file)
@@ -429,7 +429,7 @@ _update_scene(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, Ef
 static void
 _render_tvg_buffer_to_screen(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
                              void *engine, void *output, void *context, void *surface,
-                             int x, int y, Eina_Bool do_async)
+                             int x, int y, int w, int h, Eina_Bool do_async)
 {
    Eina_Bool async_unref = EINA_FALSE;
    Image_Entry *image = NULL;
@@ -443,9 +443,8 @@ _render_tvg_buffer_to_screen(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Obje
                                             pd->tvg_buffer, 255,
                                             EVAS_COLORSPACE_ARGB8888);
 
-   async_unref = ENFN->image_draw(engine, output, context, surface, image, 0, 0,
-                                  pd->tvg_canvas_size.w, pd->tvg_canvas_size.h, x, y,
-                                  pd->tvg_canvas_size.w, pd->tvg_canvas_size.h,
+   async_unref = ENFN->image_draw(engine, output, context, surface, image,
+                                  0, 0, w, h, x, y, w, h,
                                   EINA_TRUE, do_async);
 
    if (do_async && async_unref)
@@ -465,6 +464,7 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
                              int x, int y, Eina_Bool do_async)
 {
    Efl_Canvas_Vg_Object_Data *pd = type_private_data;
+   Eina_Position2D offset = {0, 0};  //Offset after keeping aspect ratio.
    Eina_Bool updated = pd->changed;
 
    ENFN->context_color_set(engine, context, 255, 255, 255, 255);
@@ -476,42 +476,79 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
    ENFN->context_anti_alias_set(engine, context, obj->cur->anti_alias);
    ENFN->context_render_op_set(engine, context, obj->cur->render_op);
 
-   Eina_Size2D size;
+   int w = obj->cur->geometry.w;
+   int h = obj->cur->geometry.h;
+
+   Vg_Cache_Entry *vg_entry = pd->vg_entry;
 
-   size.w = obj->cur->geometry.w;
-   size.h = obj->cur->geometry.h;
+   //Update the size only when user entry is not valid.
+   if (!pd->user_entry && vg_entry)
+     {
+        evas_cache_vg_entry_value_provider_update(vg_entry, efl_key_data_get(obj->object, "_vg_value_providers"));
+
+        // if the size changed in between path set and the draw call;
+        if ((vg_entry->w != w) || (vg_entry->h != h))
+          {
+             Eina_Size2D size = evas_cache_vg_entry_default_size_get(vg_entry);
+
+             //adjust size for aspect ratio.
+             if (size.w > 0 && size.h > 0)
+               {
+                  float rw = (float) w / (float) size.w;
+                  float rh = (float) h / (float) size.h;
+
+                  if (rw < rh)
+                    {
+                       size.w = w;
+                       size.h = (int) ((float) size.h * rw);
+                    }
+                  else
+                    {
+                       size.w = (int) ((float) size.w * rh);
+                       size.h = h;
+                    }
+               }
+             else
+               {
+                  size.w = w;
+                  size.h = h;
+               }
+
+             //Size is changed, cached data is invalid.
+             if ((size.w != vg_entry->w) || (size.h != vg_entry->h))
+               {
+                  vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h);
+                  evas_cache_vg_entry_del(pd->vg_entry);
+                  pd->vg_entry = vg_entry;
+                  updated = EINA_TRUE;
+               }
+
+             //update for adjusted pos and size.
+             offset.x = w - size.w;
+             if (offset.x > 0) offset.x /= 2;
+             offset.y = h - size.h;
+             if (offset.y > 0) offset.y /= 2;
+             w = size.w;
+             h = size.h;
+          }
+     }
 
    //Reset canvas size
-   if (pd->tvg_canvas_size.w != size.w || pd->tvg_canvas_size.h != size.h)
+   if (pd->tvg_canvas_size.w != w || pd->tvg_canvas_size.h != h)
      {
-        pd->tvg_buffer = realloc(pd->tvg_buffer, size.w * size.h * sizeof(uint32_t));
-        pd->tvg_canvas_size.w = size.w;
-        pd->tvg_canvas_size.h = size.h;
+        pd->tvg_buffer = realloc(pd->tvg_buffer, w * h * sizeof(uint32_t));
+        pd->tvg_canvas_size.w = w;
+        pd->tvg_canvas_size.h = h;
 
         tvg_swcanvas_set_target(pd->tvg_canvas, pd->tvg_buffer,
-                                size.w, size.w, size.h,
-                                TVG_COLORSPACE_ARGB8888);
+                                w, w, h, TVG_COLORSPACE_ARGB8888);
         updated = EINA_TRUE;
      }
 
-   Vg_Cache_Entry *vg_entry = pd->vg_entry;
-   if (vg_entry)
+   if (pd->vg_entry && updated)
      {
-        evas_cache_vg_entry_value_provider_update(vg_entry, efl_key_data_get(obj->object, "_vg_value_providers"));
-
-        //FIX_TVG: see _cache_vg_entry_render() how it handles the aspect ratio for optimal buffer size
-        if ((size.w != vg_entry->w) || (size.h != vg_entry->h))
-          {
-              vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h);
-              evas_cache_vg_entry_del(pd->vg_entry);
-              pd->vg_entry = vg_entry;
-              updated = EINA_TRUE;
-          }
-
         Efl_VG *root = evas_cache_vg_tree_get(pd->vg_entry, pd->frame_idx);
-        if (!root) return;
-
-        if (updated) _update_scene(obj, pd, root);
+        if (root) _update_scene(obj, pd, root);
      }
 
    if (pd->user_entry && updated) _update_scene(obj, pd, pd->user_entry->root);
@@ -525,9 +562,9 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
      }
 
    _render_tvg_buffer_to_screen(obj, pd, engine, output, context, surface,
-                                obj->cur->geometry.x + x,
-                                obj->cur->geometry.y + y,
-                                do_async);
+                                obj->cur->geometry.x + x + offset.x,
+                                obj->cur->geometry.y + y + offset.y,
+                                w, h, do_async);
    pd->changed = EINA_FALSE;
 }