Called by NewFrame() for atlases owned by a context. If you manually manage font atlases, you'll need to call this yourself. - 'frame_count' needs to be provided because we can gc/prioritize baked fonts based on their age. - 'frame_count' may not match those of all imgui contexts using this atlas, as contexts may be updated as different frequencies. But generally you can use ImGui::GetFrameCount()
| 2732 | // - 'frame_count' needs to be provided because we can gc/prioritize baked fonts based on their age. |
| 2733 | // - 'frame_count' may not match those of all imgui contexts using this atlas, as contexts may be updated as different frequencies. But generally you can use ImGui::GetFrameCount() on one of your context. |
| 2734 | void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool renderer_has_textures) |
| 2735 | { |
| 2736 | IM_ASSERT(atlas->Builder == NULL || atlas->Builder->FrameCount < frame_count); // Protection against being called twice. |
| 2737 | atlas->RendererHasTextures = renderer_has_textures; |
| 2738 | |
| 2739 | // Check that font atlas was built or backend support texture reload in which case we can build now |
| 2740 | if (atlas->RendererHasTextures) |
| 2741 | { |
| 2742 | atlas->TexIsBuilt = true; |
| 2743 | if (atlas->Builder == NULL) // This will only happen if fonts were not already loaded. |
| 2744 | ImFontAtlasBuildMain(atlas); |
| 2745 | } |
| 2746 | // Legacy backend |
| 2747 | if (!atlas->RendererHasTextures) |
| 2748 | IM_ASSERT_USER_ERROR(atlas->TexIsBuilt, "Backend does not support ImGuiBackendFlags_RendererHasTextures, and font atlas is not built! Update backend OR make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()."); |
| 2749 | if (atlas->TexIsBuilt && atlas->Builder->PreloadedAllGlyphsRanges) |
| 2750 | IM_ASSERT_USER_ERROR(atlas->RendererHasTextures == false, "Called ImFontAtlas::Build() before ImGuiBackendFlags_RendererHasTextures got set! With new backends: you don't need to call Build()."); |
| 2751 | |
| 2752 | // Clear BakedCurrent cache, this is important because it ensure the uncached path gets taken once. |
| 2753 | // We also rely on ImFontBaked* pointers never crossing frames. |
| 2754 | ImFontAtlasBuilder* builder = atlas->Builder; |
| 2755 | builder->FrameCount = frame_count; |
| 2756 | for (ImFont* font : atlas->Fonts) |
| 2757 | font->LastBaked = NULL; |
| 2758 | |
| 2759 | // Garbage collect BakedPool |
| 2760 | if (builder->BakedDiscardedCount > 0) |
| 2761 | { |
| 2762 | int dst_n = 0, src_n = 0; |
| 2763 | for (; src_n < builder->BakedPool.Size; src_n++) |
| 2764 | { |
| 2765 | ImFontBaked* p_src = &builder->BakedPool[src_n]; |
| 2766 | if (p_src->WantDestroy) |
| 2767 | continue; |
| 2768 | ImFontBaked* p_dst = &builder->BakedPool[dst_n++]; |
| 2769 | if (p_dst == p_src) |
| 2770 | continue; |
| 2771 | memcpy(p_dst, p_src, sizeof(ImFontBaked)); |
| 2772 | builder->BakedMap.SetVoidPtr(p_dst->BakedId, p_dst); |
| 2773 | } |
| 2774 | IM_ASSERT(dst_n + builder->BakedDiscardedCount == src_n); |
| 2775 | builder->BakedPool.Size -= builder->BakedDiscardedCount; |
| 2776 | builder->BakedDiscardedCount = 0; |
| 2777 | } |
| 2778 | |
| 2779 | // Update texture status |
| 2780 | for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++) |
| 2781 | { |
| 2782 | ImTextureData* tex = atlas->TexList[tex_n]; |
| 2783 | bool remove_from_list = false; |
| 2784 | if (tex->Status == ImTextureStatus_OK) |
| 2785 | { |
| 2786 | tex->Updates.resize(0); |
| 2787 | tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0; |
| 2788 | tex->UpdateRect.w = tex->UpdateRect.h = 0; |
| 2789 | } |
| 2790 | if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures) |
| 2791 | IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK."); |
no test coverage detected