Fonts: clarify ClearTexData() as not supported with dynamic atlases.

This commit is contained in:
ocornut
2025-01-30 16:32:25 +01:00
parent 093d01269a
commit 80404fae30
3 changed files with 30 additions and 22 deletions
+4 -2
View File
@@ -5785,7 +5785,8 @@ void ImGui::EndFrame()
UpdateTexturesEndFrame(); UpdateTexturesEndFrame();
// Unlock font atlas // Unlock font atlas
g.IO.Fonts->Locked = false; ImFontAtlas* atlas = g.IO.Fonts;
atlas->Locked = false;
// Clear Input data for next frame // Clear Input data for next frame
g.IO.MousePosPrev = g.IO.MousePos; g.IO.MousePosPrev = g.IO.MousePos;
@@ -8575,8 +8576,9 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
void ImGui::UpdateFontsNewFrame() void ImGui::UpdateFontsNewFrame()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImFontAtlas* atlas = g.IO.Fonts;
if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0) if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0)
g.IO.Fonts->Locked = true; atlas->Locked = true;
SetCurrentFont(GetDefaultFont(), GetDefaultFont()->Sources[0].SizePixels); SetCurrentFont(GetDefaultFont(), GetDefaultFont()->Sources[0].SizePixels);
IM_ASSERT(g.Font->IsLoaded()); IM_ASSERT(g.Font->IsLoaded());
} }
+2 -2
View File
@@ -3517,7 +3517,7 @@ struct ImFontAtlas
// As we are transitioning toward a new font system, we expect to obsolete those soon: // As we are transitioning toward a new font system, we expect to obsolete those soon:
IMGUI_API void ClearInputData(); // [OBSOLETE] Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts. IMGUI_API void ClearInputData(); // [OBSOLETE] Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
IMGUI_API void ClearFonts(); // [OBSOLETE] Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates). IMGUI_API void ClearFonts(); // [OBSOLETE] Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
IMGUI_API void ClearTexData(); // [OBSOLETE] Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory. IMGUI_API void ClearTexData(); // [OBSOLETE] Clear CPU-side copy of the texture data. Saves RAM once the texture has been copied to graphics memory.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy path for build atlas + retrieving pixel data. // Legacy path for build atlas + retrieving pixel data.
@@ -3592,7 +3592,7 @@ struct ImFontAtlas
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. 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 ImTextureData* TexData; // Current texture
ImVector<ImTextureData*> TexList; // Texture list (most often TexList.Size == 1). TexData is always == TexList.back(). DO NOT USE DIRECTLY, USE GetDrawData().Textures[]/GetPlatformIO().Textures[] instead! ImVector<ImTextureData*> TexList; // Texture list (most often TexList.Size == 1). TexData is always == TexList.back(). DO NOT USE DIRECTLY, USE GetDrawData().Textures[]/GetPlatformIO().Textures[] instead!
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert. bool Locked; // Marked as locked during ImGui::NewFrame()..EndFrame() scope if TexUpdates are not supported. Any attempt to modify the atlas will assert.
bool RendererHasTextures;// Copy of (BackendFlags & ImGuiBackendFlags_RendererHasTextures) from supporting context. bool RendererHasTextures;// Copy of (BackendFlags & ImGuiBackendFlags_RendererHasTextures) from supporting context.
bool TexIsBuilt; // Set when texture was built matching current font input. Mostly useful for legacy IsBuilt() call. bool TexIsBuilt; // Set when texture was built matching current font input. Mostly useful for legacy IsBuilt() call.
bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format or conversion process. bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format or conversion process.
+24 -18
View File
@@ -2607,9 +2607,11 @@ ImFontAtlas::~ImFontAtlas()
void ImFontAtlas::Clear() void ImFontAtlas::Clear()
{ {
ClearInputData();
ClearTexData();
ClearFonts(); ClearFonts();
bool backup_renderer_has_textures = RendererHasTextures;
RendererHasTextures = false; // Full Clear() is supported, but ClearTexData() only isn't.
ClearTexData();
RendererHasTextures = backup_renderer_has_textures;
} }
void ImFontAtlas::ClearCache() void ImFontAtlas::ClearCache()
@@ -2647,12 +2649,14 @@ void ImFontAtlas::ClearInputData()
Sources.clear(); Sources.clear();
} }
// Clear CPU-side copy of the texture data.
void ImFontAtlas::ClearTexData() void ImFontAtlas::ClearTexData()
{ {
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
TexList.clear(); IM_ASSERT(RendererHasTextures == false && "Not supported for dynamic atlases, but you may call Clear().");
IM_DELETE(TexData); for (ImTextureData* tex : TexList)
TexData = NULL; tex->DestroyPixels();
//Locked = true; // Hoped to be able to lock this down but some reload patterns may not be happy with it.
} }
void ImFontAtlas::ClearFonts() void ImFontAtlas::ClearFonts()
@@ -2686,7 +2690,7 @@ static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* at
} }
// Called by NewFrame(). When multiple context own the atlas, only the first one calls this. // Called by NewFrame(). When multiple context own the atlas, only the first one calls this.
// If you are calling this yourself, ensure atlas->RendererHasTexUpdates is et. // If you are calling this yourself, ensure atlas->RendererHasTextures is set.
// 'frame_count' needs to be provided because we can gc/prioritize baked fonts based on their age. // 'frame_count' needs to be provided because we can gc/prioritize baked fonts based on their age.
void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count) void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count)
{ {
@@ -3256,7 +3260,7 @@ bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor curso
return true; return true;
} }
// When atlas->RendererHasTexUpdates == true, this is only called if no font were loaded. // When atlas->RendererHasTextures = true, this is only called if no font were loaded.
void ImFontAtlasBuildMain(ImFontAtlas* atlas) void ImFontAtlasBuildMain(ImFontAtlas* atlas)
{ {
IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
@@ -3481,16 +3485,6 @@ static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas, bool add_and_
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size)
{
struct { ImGuiID FontId; float BakedSize; } hashed_data;
hashed_data.FontId = font_id;
hashed_data.BakedSize = baked_size;
return ImHashData(&hashed_data, sizeof(hashed_data));
}
//-----------------------------------------------------------------------------------------------------------------------------
bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src) bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src)
{ {
ImFont* font = src->DstFont; ImFont* font = src->DstFont;
@@ -4910,6 +4904,14 @@ float ImFontBaked::GetCharAdvance(ImWchar c)
} }
IM_MSVC_RUNTIME_CHECKS_RESTORE IM_MSVC_RUNTIME_CHECKS_RESTORE
ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size)
{
struct { ImGuiID FontId; float BakedSize; } hashed_data;
hashed_data.FontId = font_id;
hashed_data.BakedSize = baked_size;
return ImHashData(&hashed_data, sizeof(hashed_data));
}
// ImFontBaked pointers are valid for the entire frame but shall never be kept between frames. // ImFontBaked pointers are valid for the entire frame but shall never be kept between frames.
ImFontBaked* ImFont::GetFontBaked(float size) ImFontBaked* ImFont::GetFontBaked(float size)
{ {
@@ -4920,18 +4922,22 @@ ImFontBaked* ImFont::GetFontBaked(float size)
ImFontAtlas* atlas = ContainerAtlas; ImFontAtlas* atlas = ContainerAtlas;
ImFontAtlasBuilder* builder = atlas->Builder; ImFontAtlasBuilder* builder = atlas->Builder;
// FIXME-BAKED: Design for picking a nearest size?
ImGuiID baked_id = ImFontAtlasBakedGetId(FontId, size); ImGuiID baked_id = ImFontAtlasBakedGetId(FontId, size);
ImFontBaked** p_baked_in_map = (ImFontBaked**)builder->BakedMap.GetVoidPtrRef(baked_id); ImFontBaked** p_baked_in_map = (ImFontBaked**)builder->BakedMap.GetVoidPtrRef(baked_id);
baked = *p_baked_in_map; baked = *p_baked_in_map;
if (baked != NULL) if (baked != NULL)
{ {
// FIXME-BAKED: Design for picking a nearest size?
IM_ASSERT(baked->Size == size && baked->ContainerFont == this && baked->BakedId == baked_id); IM_ASSERT(baked->Size == size && baked->ContainerFont == this && baked->BakedId == baked_id);
baked->LastUsedFrame = builder->FrameCount; baked->LastUsedFrame = builder->FrameCount;
LastBaked = baked; LastBaked = baked;
return baked; return baked;
} }
// FIXME-BAKED: If atlas is locked, find closest match
if (atlas->Locked)
IM_ASSERT(!atlas->Locked && "Cannot use dynamic font size with a locked ImFontAtlas!"); // Locked because rendering backend does not support ImGuiBackendFlags_RendererHasTextures!
// Create new // Create new
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_UNUSED(g); // for IMGUI_DEBUG_LOG_FONT() IM_UNUSED(g); // for IMGUI_DEBUG_LOG_FONT()