From f2936931f72122f6cd1e47b81f59d78ff32dfb08 Mon Sep 17 00:00:00 2001 From: philmoz Date: Wed, 17 May 2023 18:28:29 +1000 Subject: [PATCH] fix(color): Memory leaks when using USB mass storage connection (#3547) * Fix memory leaks when using 'USB Storage (SD)' connection. - Lua state 'cache' allocated to both lsScripts and lsWidgets; but only one was being released. - Default theme bitmaps being reloaded without releasing previously allocated memory. * Fix icons. --- radio/src/gui/colorlcd/themes/480_default.cpp | 75 +++++++++---------- radio/src/thirdparty/Lua/src/lstate.c | 14 ++-- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/radio/src/gui/colorlcd/themes/480_default.cpp b/radio/src/gui/colorlcd/themes/480_default.cpp index 48817627c..f38b4b122 100644 --- a/radio/src/gui/colorlcd/themes/480_default.cpp +++ b/radio/src/gui/colorlcd/themes/480_default.cpp @@ -77,53 +77,46 @@ class Theme480: public OpenTxTheme void loadMenuIcon(uint8_t index, const uint8_t * lbm, bool reload) const { - BitmapBuffer * mask; + BitmapBuffer * mask = BitmapBuffer::load8bitMaskLZ4(lbm); + + if (mask) { + iconMask[index] = mask; + menuIconNormal[index] = new BitmapBuffer(BMP_RGB565, mask->width(), mask->height()); + menuIconSelected[index] = new BitmapBuffer(BMP_RGB565, mask->width(), mask->height()); - if (reload) { - mask = BitmapBuffer::load8bitMaskLZ4(lbm); - if (mask) { - delete iconMask[index]; - iconMask[index] = mask; - - delete menuIconNormal[index]; - menuIconNormal[index] = new BitmapBuffer(BMP_RGB565, mask->width(), mask->height()); - - delete menuIconSelected[index]; - menuIconSelected[index] = new BitmapBuffer(BMP_RGB565, mask->width(), mask->height()); + if (menuIconNormal[index]) { + menuIconNormal[index]->clear(COLOR_THEME_SECONDARY1); + menuIconNormal[index]->drawMask(0, 0, mask, COLOR_THEME_PRIMARY2); } - } else - mask = iconMask[index]; - - if (menuIconNormal[index]) { - menuIconNormal[index]->clear(COLOR_THEME_SECONDARY1); - menuIconNormal[index]->drawMask(0, 0, mask, COLOR_THEME_PRIMARY2); - } - if (menuIconSelected[index]) { - menuIconSelected[index]->clear(COLOR_THEME_FOCUS); - menuIconSelected[index]->drawMask(0, 0, mask, COLOR_THEME_PRIMARY2); + if (menuIconSelected[index]) { + menuIconSelected[index]->clear(COLOR_THEME_FOCUS); + menuIconSelected[index]->drawMask(0, 0, mask, COLOR_THEME_PRIMARY2); + } } } - void loadIcons(bool reload) const + void loadIcons() const { + if (iconsLoaded) + return; + + iconsLoaded = true; + for (int id = ICON_OPENTX; id != MENUS_ICONS_COUNT; id++) { - MenuIcons icon_id = (MenuIcons)id; - loadMenuIcon(icon_id, getBuiltinIcon(icon_id), reload); + loadMenuIcon(id, getBuiltinIcon((MenuIcons)id), true); } - unique_ptr background(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_bg)); + // Get mask with max size unique_ptr shadow(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_shadow)); - unique_ptr dot(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_dot)); - unique_ptr topleft(BitmapBuffer::load8bitMaskLZ4(mask_topleft)); - if (!currentMenuBackground) { - // TODO: get rid of fixed size!!! - currentMenuBackground = new BitmapBuffer(BMP_RGB565, 36, 53); - } + currentMenuBackground = new BitmapBuffer(BMP_RGB565, shadow->width(), shadow->height()); if (currentMenuBackground) { + unique_ptr background(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_bg)); + unique_ptr dot(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_dot)); + currentMenuBackground->drawSolidFilledRect( 0, 0, currentMenuBackground->width(), MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY1); @@ -136,21 +129,21 @@ class Theme480: public OpenTxTheme 0, MENU_TITLE_TOP, currentMenuBackground->width(), currentMenuBackground->height() - MENU_TITLE_TOP, COLOR_THEME_SECONDARY1); - currentMenuBackground->drawMask(0, 0, background.get(), - COLOR_THEME_FOCUS); - + currentMenuBackground->drawMask(0, 0, background.get(), COLOR_THEME_FOCUS); currentMenuBackground->drawMask(0, 0, shadow.get(), COLOR_THEME_PRIMARY1); currentMenuBackground->drawMask(10, 39, dot.get(), COLOR_THEME_PRIMARY2); } - if (!topleftBitmap) { - topleftBitmap = new BitmapBuffer(BMP_RGB565, topleft->width(), topleft->height()); - } + unique_ptr topleft(BitmapBuffer::load8bitMaskLZ4(mask_topleft)); + + topleftBitmap = new BitmapBuffer(BMP_RGB565, topleft->width(), topleft->height()); if (topleftBitmap) { topleftBitmap->clear(COLOR_THEME_SECONDARY1); topleftBitmap->drawMask(0, 0, topleft.get(), COLOR_THEME_FOCUS); } + + loadBuiltinBitmaps(); } void setBackgroundImageFileName(const char *fileName) override @@ -175,8 +168,7 @@ class Theme480: public OpenTxTheme void update(bool reload = true) const override { - loadIcons(reload); - if (reload) loadBuiltinBitmaps(); + loadIcons(); initLvglTheme(); } @@ -272,6 +264,7 @@ class Theme480: public OpenTxTheme } protected: + static bool iconsLoaded; static const BitmapBuffer * backgroundBitmap; static BitmapBuffer * topleftBitmap; static BitmapBuffer * menuIconNormal[MENUS_ICONS_COUNT]; @@ -280,6 +273,8 @@ class Theme480: public OpenTxTheme static BitmapBuffer * currentMenuBackground; }; +bool Theme480::iconsLoaded = false; + const BitmapBuffer * Theme480::backgroundBitmap = nullptr; BitmapBuffer * Theme480::topleftBitmap = nullptr; BitmapBuffer * Theme480::iconMask[MENUS_ICONS_COUNT] = { nullptr }; diff --git a/radio/src/thirdparty/Lua/src/lstate.c b/radio/src/thirdparty/Lua/src/lstate.c index d9085d63e..3651d1c77 100644 --- a/radio/src/thirdparty/Lua/src/lstate.c +++ b/radio/src/thirdparty/Lua/src/lstate.c @@ -309,18 +309,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->gcpause = LUAI_GCPAUSE; g->gcmajorinc = LUAI_GCMAJOR; g->gcstepmul = LUAI_GCMUL; -#ifdef LUA_ENABLE_TEST if (L0) { /* This is a second state */ - g->cache=G(L0)->cache; + g->cache = G(L0)->cache; } else { -#endif - L0 = L; - g->cache = cast(KeyCacheLine *, - (*f)(ud, NULL, 0, KEYCACHE_N * sizeof(KeyCacheLine))); - memset(g->cache, 0, KEYCACHE_N * sizeof(KeyCacheLine)); -#ifdef LUA_ENABLE_TEST + L0 = L; + g->cache = cast(KeyCacheLine *, + (*f)(ud, NULL, 0, KEYCACHE_N * sizeof(KeyCacheLine))); + memset(g->cache, 0, KEYCACHE_N * sizeof(KeyCacheLine)); } -#endif for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { /* memory allocation error: free partial state */