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; --
