From 0c9499a88ecc7a963e2bea43144bd2bc4bb6445b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Sat, 23 May 2020 19:15:32 -0300 Subject: [PATCH] Implements small buffer optimization in font_driver_reshape_msg() Use a stack-allocated 64 bytes long buffer to avoid so many temp heap allocations when the menu is up. This size is more than enough store 75% of the return values from msg_hash_to_str and 50% of the returned values from msg_hash_get_help of any currently supported language (includes fallback to English). String size per type: count mean std ... 50% 75% max type ... msg_hash_get_help 83885.0 95.295476 106.331779 ... 54.0 103.0 842.0 msg_hash_to_str 83903.0 27.737959 33.389184 ... 19.0 31.0 440.0 string size per type and language: count mean std ... 50% 75% max type language ... msg_hash_get_help 0 4415.0 89.922310 96.873902 ... 55.0 101.0 590.0 1 4415.0 97.555606 118.031412 ... 55.0 101.0 842.0 2 4415.0 118.459570 127.811760 ... 75.0 131.0 774.0 3 4415.0 111.978256 112.702991 ... 68.0 125.0 651.0 4 4415.0 106.040544 111.360658 ... 62.0 124.0 776.0 5 4415.0 100.129105 114.437432 ... 62.0 103.0 688.0 6 4415.0 32.987769 31.047851 ... 28.0 28.0 595.0 7 4415.0 109.366025 124.717259 ... 71.0 121.0 720.0 8 4415.0 98.023783 105.149942 ... 62.0 105.0 610.0 9 4415.0 93.834428 104.433820 ... 55.0 101.0 637.0 10 4415.0 93.657984 96.884429 ... 55.0 101.0 594.0 11 4415.0 93.452775 104.040553 ... 48.0 100.0 583.0 12 4415.0 89.729558 104.062959 ... 50.0 100.0 550.0 13 4415.0 91.462514 95.968107 ... 55.0 101.0 590.0 14 4415.0 92.062741 97.959207 ... 55.0 101.0 611.0 15 4415.0 92.597055 97.190835 ... 56.0 101.0 600.0 16 4415.0 92.088109 98.110738 ... 55.0 101.0 608.0 17 4415.0 102.483126 106.379639 ... 65.0 110.0 652.0 18 4415.0 104.782786 114.025678 ... 65.0 112.0 646.0 msg_hash_to_str 0 4415.0 24.591619 29.148312 ... 18.0 28.0 346.0 1 4416.0 31.247736 36.302532 ... 21.0 36.0 352.0 2 4416.0 31.853714 39.332395 ... 21.0 36.0 418.0 3 4416.0 28.270833 33.300996 ... 21.0 32.0 429.0 4 4416.0 27.139040 31.905206 ... 19.0 31.0 346.0 5 4416.0 27.380435 32.314188 ... 19.0 31.0 346.0 6 4416.0 25.028080 29.188490 ... 19.0 28.0 346.0 7 4416.0 29.660553 35.283592 ... 21.0 33.0 393.0 8 4416.0 27.685915 32.707466 ... 20.0 31.0 346.0 9 4416.0 34.786685 43.587766 ... 21.0 39.0 414.0 10 4416.0 28.769928 34.428596 ... 20.0 32.0 440.0 11 4416.0 24.407609 28.690934 ... 18.0 27.0 346.0 12 4416.0 23.970788 27.075638 ... 18.0 28.0 346.0 13 4416.0 24.587636 29.146213 ... 18.0 28.0 346.0 14 4416.0 27.642889 33.300451 ... 20.0 31.0 346.0 15 4416.0 25.036005 29.159115 ... 18.0 28.0 346.0 16 4416.0 24.732111 29.134002 ... 18.0 28.0 346.0 17 4416.0 32.068161 38.807095 ... 21.0 36.0 407.0 18 4416.0 28.160779 34.013300 ... 20.0 31.0 432.0 --- gfx/font_driver.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/gfx/font_driver.c b/gfx/font_driver.c index f57d0a1f1d..dbd32d07f1 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -940,14 +940,22 @@ static INLINE unsigned font_get_replacement(const char* src, const char* start) return 0; } -static char* font_driver_reshape_msg(const char* msg) +static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, size_t buffer_size) { - /* worst case transformations are 2 bytes to 4 bytes */ - unsigned char* buffer = (unsigned char*)malloc((strlen(msg) * 2) + 1); + unsigned char* dst_buffer = buffer; const unsigned char* src = (const unsigned char*)msg; - unsigned char* dst = (unsigned char*)buffer; + unsigned char* dst; bool reverse = false; + /* fallback to heap allocated buffer if the buffer is too small */ + if (buffer_size < (strlen(msg) * 2) + 1) + { + /* worst case transformations are 2 bytes to 4 bytes -- aliaspider */ + dst_buffer = (unsigned char*)malloc((strlen(msg) * 2) + 1); + } + + dst = (unsigned char*)dst_buffer; + while (*src || reverse) { if (reverse) @@ -1025,7 +1033,7 @@ static char* font_driver_reshape_msg(const char* msg) end: *dst = '\0'; - return (char*)buffer; + return (char*)dst_buffer; } #endif @@ -1042,15 +1050,16 @@ void font_driver_render_msg( if (msg && *msg && font && font->renderer && font->renderer->render_msg) { #ifdef HAVE_LANGEXTRA - char *new_msg = font_driver_reshape_msg(msg); + unsigned char tmp_buffer[64]; + char *new_msg = font_driver_reshape_msg(msg, tmp_buffer, sizeof(tmp_buffer)); #else char *new_msg = (char*)msg; #endif - font->renderer->render_msg(data, font->renderer_data, new_msg, params); #ifdef HAVE_LANGEXTRA - free(new_msg); + if (new_msg != (char*)tmp_buffer) + free(new_msg); #endif } }