From 312cbe33f320efe1a41c66fe2598a81578d8e186 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Sat, 21 Mar 2020 13:04:16 -0400 Subject: [PATCH] Leak checkers; and clean up offscreen caches In #1647 we had a report that the skin engine seemed to increase load time as the run went on, probably due to a leak. This change adds some leak checkers I can use, and also closes one leak in the CScalableBitmap offscreenCache which was never forgotten. Addresses #1647 --- src/common/gui/CScalableBitmap.cpp | 27 ++++++++++++++++++++++++++- src/common/gui/CScalableBitmap.h | 6 +++++- src/common/gui/SkinSupport.cpp | 8 ++++++-- src/common/gui/SkinSupport.h | 2 ++ src/common/gui/SurgeBitmaps.cpp | 7 +++++++ src/common/gui/SurgeBitmaps.h | 3 +++ 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/common/gui/CScalableBitmap.cpp b/src/common/gui/CScalableBitmap.cpp index 0cc517f583d..4d9b10ef621 100644 --- a/src/common/gui/CScalableBitmap.cpp +++ b/src/common/gui/CScalableBitmap.cpp @@ -31,6 +31,7 @@ #include "nanosvg.h" using namespace VSTGUI; +std::atomic CScalableBitmap::instances( 0 ); #if MAC static const std::string svgFullFileNameFromBundle(const std::string& filename) @@ -99,6 +100,10 @@ CScalableBitmap::CScalableBitmap(CResourceDescription desc, VSTGUI::CFrame* f) if(desc.type == CResourceDescription::kIntegerType) id = (int32_t)desc.u.id; + instances++; + //std::cout << " Construct CScalableBitmap. instances=" << instances << " id=" << id << std::endl; + + resourceID = id; std::stringstream filename; @@ -167,9 +172,14 @@ CScalableBitmap::CScalableBitmap(CResourceDescription desc, VSTGUI::CFrame* f) lastSeenZoom = -1; } -CScalableBitmap::CScalableBitmap(std::string fname, VSTGUI::CFrame* f) +CScalableBitmap::CScalableBitmap(std::string ifname, VSTGUI::CFrame* f) : CBitmap(CResourceDescription(0)), svgImage(nullptr), frame(f) { + fname = ifname; + + instances++; + //std::cout << " Construct CScalableBitmap. instances=" << instances << " fname=" << fname << std::endl; + int id = 0; resourceID = id; @@ -185,6 +195,21 @@ CScalableBitmap::CScalableBitmap(std::string fname, VSTGUI::CFrame* f) lastSeenZoom = -1; } +CScalableBitmap::~CScalableBitmap() +{ + for (auto const& pair : offscreenCache) + { + auto val = pair.second; + if (val) + val->forget(); + } + offscreenCache.clear(); + + instances--; + //std::cout << " Destroy CScalableBitmap. instances=" << instances << " id=" << resourceID << " fn=" << fname << std::endl; +} + + #define DUMPR(r) \ "(x=" << r.getTopLeft().x << ",y=" << r.getTopLeft().y << ")+(w=" << r.getWidth() \ << ",h=" << r.getHeight() << ")" diff --git a/src/common/gui/CScalableBitmap.h b/src/common/gui/CScalableBitmap.h index 1f4e80b4e46..0e33b21769d 100644 --- a/src/common/gui/CScalableBitmap.h +++ b/src/common/gui/CScalableBitmap.h @@ -9,6 +9,7 @@ #include #include +#include #include "nanosvg.h" @@ -17,6 +18,7 @@ class CScalableBitmap : public VSTGUI::CBitmap public: CScalableBitmap(VSTGUI::CResourceDescription d, VSTGUI::CFrame* f); CScalableBitmap(std::string fname, VSTGUI::CFrame* f); + ~CScalableBitmap(); virtual void draw(VSTGUI::CDrawContext* context, const VSTGUI::CRect& rect, @@ -60,10 +62,12 @@ class CScalableBitmap : public VSTGUI::CBitmap }; std::map offscreenCache; - + static std::atomic instances; + int lastSeenZoom, bestFitScaleGroup; int extraScaleFactor; int resourceID; + std::string fname; VSTGUI::CFrame* frame; diff --git a/src/common/gui/SkinSupport.cpp b/src/common/gui/SkinSupport.cpp index 5259db78f06..8d73b21f4bf 100644 --- a/src/common/gui/SkinSupport.cpp +++ b/src/common/gui/SkinSupport.cpp @@ -207,15 +207,19 @@ std::unordered_map createIdNameMap() return res; } +std::atomic Skin::instances( 0 ); + Skin::Skin(std::string root, std::string name) : root(root), name(name) { - std::cout << "Constructing a skin " << _D(root) << _D(name) << std::endl; + instances++; + std::cout << "Constructing a skin " << _D(root) << _D(name) << _D(instances) << std::endl; imageIds = createIdNameMap(); } Skin::~Skin() { - std::cout << "Destroying a skin" << std::endl; + instances--; + std::cout << "Destroying a skin " << _D(instances) << std::endl; } #if !defined(TINYXML_SAFE_TO_ELEMENT) diff --git a/src/common/gui/SkinSupport.h b/src/common/gui/SkinSupport.h index 083a38c7406..50986a961a5 100644 --- a/src/common/gui/SkinSupport.h +++ b/src/common/gui/SkinSupport.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "vstgui/lib/ccolor.h" @@ -82,6 +83,7 @@ class Skin std::unordered_set getQueriedColors() { return queried_colors; } private: + static std::atomic instances; std::vector> globals; std::unordered_map colors; diff --git a/src/common/gui/SurgeBitmaps.cpp b/src/common/gui/SurgeBitmaps.cpp index 35e8b712a7b..4b482515242 100644 --- a/src/common/gui/SurgeBitmaps.cpp +++ b/src/common/gui/SurgeBitmaps.cpp @@ -6,8 +6,11 @@ using namespace VSTGUI; +std::atomic SurgeBitmaps::instances( 0 ); SurgeBitmaps::SurgeBitmaps() { + instances++; + std::cout << "Constructing a SurgeBitmaps; Instances is " << instances << std::endl; } SurgeBitmaps::~SurgeBitmaps() @@ -25,6 +28,10 @@ SurgeBitmaps::~SurgeBitmaps() pair.second->forget(); } bitmap_registry.clear(); + bitmap_file_registry.clear(); + bitmap_stringid_registry.clear(); + instances --; + std::cout << "Destroying a SurgeBitmaps; Instances is " << instances << std::endl; } void SurgeBitmaps::setupBitmapsForFrame(VSTGUI::CFrame* f) diff --git a/src/common/gui/SurgeBitmaps.h b/src/common/gui/SurgeBitmaps.h index e80a4c2b5aa..b4ab34c8f1e 100644 --- a/src/common/gui/SurgeBitmaps.h +++ b/src/common/gui/SurgeBitmaps.h @@ -3,6 +3,7 @@ #include "resource.h" #include "vstgui/vstgui.h" #include +#include class CScalableBitmap; @@ -24,6 +25,8 @@ class SurgeBitmaps CScalableBitmap* loadBitmapByPathForStringID(std::string filename, std::string id); protected: + static std::atomic instances; + void addEntry(int id, VSTGUI::CFrame* f); std::map bitmap_registry; std::map bitmap_file_registry;