raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=23e8715070bb9d75a02123c2ab5ba200699f63af

commit 23e8715070bb9d75a02123c2ab5ba200699f63af
Author: Ali Alzyod <[email protected]>
Date:   Fri May 29 10:10:28 2020 +0100

    evas_text: reduce Video Memory & RAM needed for text textures (Color Glyphs)
    
    Summary:
    Texture created for bitmap font glyph, with a fixed size in the font, this 
size could be much bigger than the needed size in application.
    Then a scale factor is applied to these textures when drawn.
    
    Now, instead, we will create smaller bitmaps and create texture from them 
with reduced texture size (that is not needed).
    
    ** This will affect both Video Memory and Ram needed to store glyphs**
    
    Open this file {F3883874} in terminology before and after applying the 
patch and notice the difference.
    
    Test Plan:
    **Notes**
    - You need to scroll down to make all glyphs visible, then notice Video/Ram 
memory
    
    |                      | Video | Ram
    |----------------------|-------|-----
    | Before (Font_size=50) |  360   |  300
    | After (Font_size=50) |  40   | 100
    | Ration After/before   |  11%  |  33%
    
    **I notice speed up in text rendering for small font size**
    
    ```
    #include <Elementary.h>
    
    typedef struct _APP
    {
      Evas_Object *tb1;
      Evas_Object *btnLoad;
    } APP;
    
    char *text = "<align=center><color=#4DE0FFFF underline=on 
underline_color=#4DE0FFFF><a 
href='tel:1234567890'>1234567890</a></color>๐Ÿ˜€๐Ÿ˜๐Ÿ˜‚๐Ÿคฃ๐Ÿ˜ƒ๐Ÿ˜„๐Ÿ˜…๐Ÿ˜†๐Ÿ˜‰๐Ÿ˜Š๐Ÿ˜‹๐Ÿ˜Ž๐Ÿ˜๐Ÿ˜˜๐Ÿ˜—๐Ÿ˜™๐Ÿ˜šโ˜บ๐Ÿ™‚๐Ÿค—๐Ÿค”๐Ÿ˜๐Ÿ˜‘๐Ÿ˜ถ๐Ÿ™„๐Ÿ˜๐Ÿ˜ฃ๐Ÿ˜ฅ๐Ÿ˜ฎ๐Ÿค๐Ÿ˜ฏ๐Ÿ˜ช๐Ÿ˜ซ๐Ÿ˜ด๐Ÿ˜Œ๐Ÿค“๐Ÿ˜›๐Ÿ˜œ๐Ÿ˜๐Ÿคค๐Ÿ˜’๐Ÿ˜“๐Ÿ˜”๐Ÿ˜•๐Ÿ™ƒ๐Ÿค‘๐Ÿ˜ฒโ˜น๐Ÿ™๐Ÿ˜–๐Ÿ˜ž๐Ÿ˜Ÿ๐Ÿ˜ค๐Ÿ˜ข๐Ÿ˜ญ๐Ÿ˜ฆ๐Ÿ˜ง๐Ÿ˜จ๐Ÿ˜ฉ๐Ÿ˜ฌ๐Ÿ˜ฐ๐Ÿ˜ฑ๐Ÿ˜ณ๐Ÿ˜ต๐Ÿ˜ก๐Ÿ˜ ๐Ÿ˜‡๐Ÿค ๐Ÿคก๐Ÿคฅ๐Ÿ˜ท๐Ÿค’๐Ÿค•๐Ÿคข๐Ÿคงโ˜ป๐Ÿ˜ˆ๐Ÿ‘ฟ๐Ÿ‘น๐Ÿ‘บ๐Ÿ’€โ˜ ๐Ÿ‘ป๐Ÿ‘ฝ๐Ÿ‘พ๐Ÿค–๐Ÿ’ฉ๐Ÿ˜บ๐Ÿ˜ธ๐Ÿ˜น๐Ÿ˜ป๐Ÿ˜ผ๐Ÿ˜ฝ๐Ÿ™€๐Ÿ˜ฟ๐Ÿ˜พ๐Ÿ™ˆ๐Ÿ™‰๐Ÿ™Š๐Ÿ‘ฆ๐Ÿ‘ง๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ต๐Ÿ‘ถ๐Ÿ‘ผ๐Ÿ‘จโ€โš•๏ธ๐Ÿ‘ฉโ€โš•๏ธ๐Ÿ‘จโ€๐ŸŽ“๐Ÿ‘ฉโ€๐ŸŽ“๐Ÿ‘จโ€๐Ÿซ๐Ÿ‘ฉโ€๐Ÿซ๐Ÿ‘จโ€โš–๐Ÿ‘ฉโ€โš–๐Ÿ‘จโ€๐ŸŒพ๐Ÿ‘ฉโ€๐ŸŒพ๐Ÿ‘จโ€๐Ÿณ๐Ÿ‘ฉโ€๐Ÿณ๐Ÿ‘จโ€๐Ÿ”ง๐Ÿ‘ฉโ€๐Ÿ”ง๐Ÿ‘จโ€๐Ÿญ๐Ÿ‘ฉโ€๐Ÿญ๐Ÿ‘จโ€๐Ÿ’ผ๐Ÿ‘ฉโ€๐Ÿ’ผ๐Ÿ‘จโ€๐Ÿ”ฌ๐Ÿ‘ฉโ€๐Ÿ”ฌ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐ŸŽค๐Ÿ‘ฉโ€๐ŸŽค๐Ÿ‘จโ€๐ŸŽจ๐Ÿ‘ฉโ€๐ŸŽจ๐Ÿ‘จโ€โœˆ๏ธ๐Ÿ‘ฉโ€โœˆ๏ธ๐Ÿ‘จโ€๐Ÿš€๐Ÿ‘ฉโ€๐Ÿš€๐Ÿ‘จโ€๐Ÿš’๐Ÿ‘ฉโ€๐Ÿš’๐Ÿ‘ฎโ€โ™‚๏ธ๐Ÿ‘ฎโ€โ™€๏ธ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ•ต๏ธโ€โ™€๏ธ๐Ÿ’‚โ€โ™‚๏ธ๐Ÿ’‚โ€โ™€๏ธ๐Ÿ‘ทโ€โ™‚๏ธ๐Ÿ‘ทโ€โ™€๏ธ๐Ÿ‘ณโ€โ™‚๏ธ๐Ÿ‘ณโ€โ™€๏ธ๐Ÿ‘ฑโ€โ™‚๏ธ๐Ÿ‘ฑโ€โ™€๏ธ๐ŸŽ…๐Ÿคถ๐Ÿ‘ธ๐Ÿคด๐Ÿ‘ฐ๐Ÿคต๐Ÿคฐ๐Ÿ‘ฒ๐Ÿ™โ€โ™‚๏ธ๐Ÿ™โ€โ™€๏ธ๐Ÿ™Žโ€โ™‚๏ธ๐Ÿ™Žโ€โ™€๏ธ๐Ÿ™…โ€โ™‚๏ธ๐Ÿ™…โ€โ™€๏ธ๐Ÿ™†โ€โ™‚๏ธ๐Ÿ™†โ€โ™€๏ธ๐Ÿ’โ€โ™‚๏ธ๐Ÿ’โ€โ™€๏ธ๐Ÿ™‹โ€โ™‚๏ธ๐Ÿ™‹โ€โ™€๏ธ๐Ÿ™‡โ€โ™‚๏ธ๐Ÿ™‡โ€โ™€๏ธ๐Ÿคฆโ€โ™‚๏ธ๐Ÿคฆโ€โ™€๏ธ๐Ÿคทโ€โ™‚๏ธ๐Ÿคทโ€โ™€๏ธ๐Ÿ’†โ€โ™‚๏ธ๐Ÿ’†โ€โ™€๏ธ๐Ÿ’‡โ€โ™‚๏ธ๐Ÿ’‡โ€โ™€๏ธ๐Ÿšถโ€โ™‚๏ธ๐Ÿšถโ€
 [...]
    
    int font_size = 100;
    void _button_clicked(void *data, Evas_Object *obj, void *event_info)
    {
       APP *app = data;
       font_size = font_size - font_size/5;
       char buffer[100] = {0};
       sprintf(buffer, "DEFAULT='font=NotoColorEmoji font_size=%i color=red 
ellipsis=-1.0 wrap=mixed'", font_size);
    
       Evas_Textblock_Style *style = evas_textblock_style_new();
       evas_textblock_style_set(style, buffer);
       evas_object_textblock_style_set(app->tb1, style);
       evas_textblock_style_free(style);
    
       sprintf(buffer, "font_size = %i",font_size);
       elm_object_text_set(app->btnLoad, buffer);
    
       style = NULL;
    }
    
    EAPI_MAIN int
    elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
    {
      APP *app = calloc(1, sizeof(APP));
      Evas_Object *win, *scroller1, *scroller2, *box;
    
      elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
    
      win = elm_win_util_standard_add("", "");
      elm_win_autodel_set(win, EINA_TRUE);
    
      box = elm_box_add(win);
      evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
      evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
      scroller1 = elm_scroller_add(win);
      evas_object_size_hint_weight_set(scroller1, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
      evas_object_size_hint_align_set(scroller1, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
    
      //evas_text_cache_policy_set(EVAS_TEXT_CACHE_POLICY_TEXTURE 
,EVAS_TEXT_CACHE_NONE);
    
      app->tb1 = evas_object_textblock_add(win);
      Evas_Textblock_Style *style = evas_textblock_style_new();
      char buffer[100] = {0};
      sprintf(buffer, "DEFAULT='font=NotoColorEmoji font_size=%i color=red 
ellipsis=-1.0 wrap=mixed'", font_size);
      evas_textblock_style_set(style, buffer);
      evas_object_textblock_style_set(app->tb1, style);
      evas_textblock_style_free(style);
      style = NULL;
    
      int w,h;
      evas_object_textblock_text_markup_set(app->tb1, "");
      evas_object_size_hint_min_set(app->tb1, 360, 720);
      elm_object_content_set(scroller1, app->tb1);
      elm_box_pack_end(box, scroller1);
      elm_object_content_set(win, box);
    
      app->btnLoad = elm_button_add(win);
      sprintf(buffer, "font_size = %i",font_size);
      elm_object_text_set(app->btnLoad, buffer);
      evas_object_smart_callback_add(app->btnLoad, "clicked", _button_clicked, 
app);
      evas_object_show(app->btnLoad);
      evas_object_move(app->btnLoad, 0, 20);
      evas_object_resize(app->btnLoad, 150, 20);
    
      evas_object_textblock_text_markup_set(app->tb1, text);
      evas_object_textblock_size_formatted_get(app->tb1, &w, &h);
      evas_object_size_hint_min_set(app->tb1, 800, w/800 + h + 150);
    
      evas_object_resize(win, 800, 800);
      evas_object_show(box);
      evas_object_show(scroller1);
      evas_object_show(scroller2);
      evas_object_show(win);
      elm_run();
    
      return 0;
    }
    ELM_MAIN()
    ```
    
    Reviewers: raster, woohyun, bu5hm4n, zmike, Hermet, segfaultxavi
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Maniphest Tasks: T8712
    
    Differential Revision: https://phab.enlightenment.org/D11814
---
 src/lib/evas/common/evas_font.h      |  3 ++-
 src/lib/evas/common/evas_font_draw.c |  8 ++++++--
 src/lib/evas/common/evas_font_load.c |  9 +++++++--
 src/lib/evas/common/evas_font_main.c | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/lib/evas/common/evas_font.h b/src/lib/evas/common/evas_font.h
index e6f2bdebd5..8b97c19399 100644
--- a/src/lib/evas/common/evas_font.h
+++ b/src/lib/evas/common/evas_font.h
@@ -294,7 +294,8 @@ struct _RGBA_Font_Int
    Eina_Hash        *kerning;
    Fash_Glyph       *fash;
    unsigned int      size;
-   float             scale_factor;
+   double            scale_factor;
+   Eina_Bool         is_resized;
    int               real_size;
    int               max_h;
    int               references;
diff --git a/src/lib/evas/common/evas_font_draw.c 
b/src/lib/evas/common/evas_font_draw.c
index 3a8f633bfd..241f772f49 100644
--- a/src/lib/evas/common/evas_font_draw.c
+++ b/src/lib/evas/common/evas_font_draw.c
@@ -105,8 +105,12 @@ evas_common_font_rgba_draw(RGBA_Image *dst, 
RGBA_Draw_Context *dc, int x, int y,
              if ((fg->fi->bitmap_scalable & 
EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR) &&
                  FT_HAS_COLOR(fg->fi->src->ft.face))
                {
-                  w *= fg->fi->scale_factor;
-                  h *= fg->fi->scale_factor;
+                  if ( !fg->fi->is_resized )
+                    {
+                       w *= fg->fi->scale_factor;
+                       h *= fg->fi->scale_factor;
+                    }
+
                }
           }
 
diff --git a/src/lib/evas/common/evas_font_load.c 
b/src/lib/evas/common/evas_font_load.c
index 3aa2070499..4aa6901257 100644
--- a/src/lib/evas/common/evas_font_load.c
+++ b/src/lib/evas/common/evas_font_load.c
@@ -460,9 +460,14 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
                       fi->bitmap_scalable & 
EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR)
                     {
                        if (fi->real_size > 0)
-                         fi->scale_factor = (float)fi->size * 64.0 / 
(float)fi->real_size;
+                         {
+                           fi->scale_factor = (double)fi->size * 64.0 / 
(double)fi->real_size;
+                           fi->is_resized = EINA_FALSE;
+                           if ((fi->scale_factor <= 0.9) && (fi->scale_factor 
!= 0))
+                             fi->is_resized = EINA_TRUE;
+                         }
                        else
-                         fi->scale_factor = (float)64.0;
+                         fi->scale_factor = 64.0;
                     }
                }
           }
diff --git a/src/lib/evas/common/evas_font_main.c 
b/src/lib/evas/common/evas_font_main.c
index c41e350dcf..799f8a89d0 100644
--- a/src/lib/evas/common/evas_font_main.c
+++ b/src/lib/evas/common/evas_font_main.c
@@ -857,6 +857,41 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph 
*fg)
      {
         fg->glyph_out->rle = NULL;
         fg->glyph_out->bitmap.rle_alloc = EINA_FALSE;
+        if (fi->is_resized)
+          {
+             int w = fbg->bitmap.width;
+             int h = fbg->bitmap.rows;
+
+             RGBA_Image src = {0};
+             src.image.data = (DATA32 *) fbg->bitmap.buffer;
+             src.cache_entry.w = w;
+             src.cache_entry.h = h;
+             src.cache_entry.flags.alpha = 1;
+
+             RGBA_Image dst = {0};
+             dst.cache_entry.w = w * fi->scale_factor;
+             dst.cache_entry.h = h * fi->scale_factor;
+             dst.image.data = malloc(dst.cache_entry.w * dst.cache_entry.h * 
4);
+             dst.cache_entry.flags.alpha = 1;
+
+             evas_common_scale_rgba_smooth_draw(&src, &dst,
+                                        0, 0, src.cache_entry.w , 
src.cache_entry.h,
+                                        0xffffffff, EVAS_RENDER_COPY,
+                                        0, 0, src.cache_entry.w , 
src.cache_entry.h,
+                                        0, 0, dst.cache_entry.w, 
dst.cache_entry.h,
+                                        NULL, 0, 0);
+
+             fg->glyph_out->bitmap.rows = dst.cache_entry.h;
+             fg->glyph_out->bitmap.width = dst.cache_entry.w;
+             fg->glyph_out->bitmap.buffer = (unsigned char *) dst.image.data;
+             fg->glyph_out->bitmap.pitch = dst.cache_entry.w * 4;
+ 
+             fg->glyph_out->rle = NULL;
+             fg->glyph_out->bitmap.rle_alloc = EINA_TRUE;
+             // this may be technically incorrect as we go and free a bitmap 
buffer
+             // behind the ftglyph's back...
+             FT_Bitmap_Done(evas_ft_lib, &(fbg->bitmap));
+          }
      }
 
    return EINA_TRUE;

-- 


Reply via email to