diff --git a/imgui.cpp b/imgui.cpp index dd6b939e5..7821841d4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3942,6 +3942,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) Font = NULL; FontSize = FontBaseSize = FontScale = CurrentDpiScale = 0.0f; IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); + IO.Fonts->RefCount++; Time = 0.0f; FrameCount = 0; FrameCountEnded = FrameCountRendered = -1; @@ -4212,12 +4213,15 @@ void ImGui::Shutdown() IM_ASSERT_USER_ERROR(g.IO.BackendRendererUserData == NULL, "Forgot to shutdown Renderer backend?"); // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) - if (g.IO.Fonts) - ImFontAtlasRemoveDrawListSharedData(g.IO.Fonts, &g.DrawListSharedData); - if (g.IO.Fonts && g.FontAtlasOwnedByContext) + if (ImFontAtlas* atlas = g.IO.Fonts) { - g.IO.Fonts->Locked = false; - IM_DELETE(g.IO.Fonts); + ImFontAtlasRemoveDrawListSharedData(atlas, &g.DrawListSharedData); + atlas->RefCount--; + if (g.FontAtlasOwnedByContext) + { + atlas->Locked = false; + IM_DELETE(atlas); + } } g.IO.Fonts = NULL; g.DrawListSharedData.TempBuffer.clear(); @@ -5192,7 +5196,12 @@ static void ImGui::UpdateTexturesEndFrame() g.PlatformIO.Textures.resize(0); g.PlatformIO.Textures.reserve(atlas->TexList.Size); for (ImTextureData* tex : atlas->TexList) + { + // We provide this information so backends can decide whether to destroy textures. + // This means in practice that if N imgui contexts are created with a shared atlas, we assume all of them have a backend initialized. + tex->RefCount = (unsigned short)atlas->RefCount; g.PlatformIO.Textures.push_back(tex); + } } // Called once a frame. Followed by SetCurrentFont() which sets up the remaining data. diff --git a/imgui.h b/imgui.h index 936c177fe..b9e8f93bc 100644 --- a/imgui.h +++ b/imgui.h @@ -3379,6 +3379,7 @@ struct IMGUI_API ImTextureData ImTextureRect UpdateRect; // Bounding box encompassing all individual updates. ImVector Updates; // Array of individual updates. int UnusedFrames; // In order to facilitate handling Status==WantDestroy in some backend: this is a count successive frames where the texture was not used. Always >0 when Status==WantDestroy. + unsigned short RefCount; // Number of contexts using this texture. bool UseColors; // Tell whether our texture data is known to use colors (rather than just white + alpha). bool WantDestroyNextFrame; // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame. @@ -3591,13 +3592,12 @@ struct ImFontAtlas // Input ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) - ImTextureRef TexRef; // User data to refer to the latest texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. - int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. ImTextureFormat TexDesiredFormat; // Desired texture format (default to ImTextureFormat_RGBA32 but may be changed to ImTextureFormat_Alpha8). int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false). void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas). // [Internal] + ImTextureRef TexRef; // User data to refer to the latest texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. ImTextureData* TexData; // Current texture ImVector TexList; // Texture list (most often TexList.Size == 1). TexData is always == TexList.back(). DO NOT USE DIRECTLY, USE GetPlatformIO().Textures[] instead! bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert. @@ -3618,6 +3618,7 @@ struct ImFontAtlas const char* FontLoaderName; // Font loader name (for display e.g. in About box) == FontLoader->Name void* FontLoaderData; // Font backend opaque storage unsigned int FontBuilderFlags; // [FIXME: Should be called FontLoaderFlags] Shared flags (for all fonts) for font loader. THIS IS BUILD IMPLEMENTATION DEPENDENT (e.g. . Per-font override is also available in ImFontConfig. + int RefCount; // Number of contexts using this atlas int _PackedSurface; // Number of packed pixels. Used when compacting to heuristically find the ideal texture size. int _PackedRects; // Number of packed rectangles. float _PackNodesFactor = 1.0f;