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()
| 2756 | // - 'frame_count' needs to be provided because we can gc/prioritize baked fonts based on their age. |
| 2757 | // - '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. |
| 2758 | void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool renderer_has_textures) |
| 2759 | { |
| 2760 | IM_ASSERT(atlas->Builder == NULL || atlas->Builder->FrameCount < frame_count); // Protection against being called twice. |
| 2761 | atlas->RendererHasTextures = renderer_has_textures; |
| 2762 | |
| 2763 | // Check that font atlas was built or backend support texture reload in which case we can build now |
| 2764 | if (atlas->RendererHasTextures) |
| 2765 | { |
| 2766 | atlas->TexIsBuilt = true; |
| 2767 | if (atlas->Builder == NULL) // This will only happen if fonts were not already loaded. |
| 2768 | ImFontAtlasBuildMain(atlas); |
| 2769 | } |
| 2770 | // Legacy backend |
| 2771 | if (!atlas->RendererHasTextures) |
| 2772 | 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()."); |
| 2773 | if (atlas->TexIsBuilt && atlas->Builder->PreloadedAllGlyphsRanges) |
| 2774 | 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()."); |
| 2775 | |
| 2776 | // Clear BakedCurrent cache, this is important because it ensure the uncached path gets taken once. |
| 2777 | // We also rely on ImFontBaked* pointers never crossing frames. |
| 2778 | ImFontAtlasBuilder* builder = atlas->Builder; |
| 2779 | builder->FrameCount = frame_count; |
| 2780 | for (ImFont* font : atlas->Fonts) |
| 2781 | font->LastBaked = NULL; |
| 2782 | |
| 2783 | // Garbage collect BakedPool |
| 2784 | if (builder->BakedDiscardedCount > 0) |
| 2785 | { |
| 2786 | int dst_n = 0, src_n = 0; |
| 2787 | for (; src_n < builder->BakedPool.Size; src_n++) |
| 2788 | { |
| 2789 | ImFontBaked* p_src = &builder->BakedPool[src_n]; |
| 2790 | if (p_src->WantDestroy) |
| 2791 | continue; |
| 2792 | ImFontBaked* p_dst = &builder->BakedPool[dst_n++]; |
| 2793 | if (p_dst == p_src) |
| 2794 | continue; |
| 2795 | memcpy(p_dst, p_src, sizeof(ImFontBaked)); |
| 2796 | builder->BakedMap.SetVoidPtr(p_dst->BakedId, p_dst); |
| 2797 | } |
| 2798 | IM_ASSERT(dst_n + builder->BakedDiscardedCount == src_n); |
| 2799 | builder->BakedPool.Size -= builder->BakedDiscardedCount; |
| 2800 | builder->BakedDiscardedCount = 0; |
| 2801 | } |
| 2802 | |
| 2803 | // Update texture status |
| 2804 | for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++) |
| 2805 | { |
| 2806 | ImTextureData* tex = atlas->TexList[tex_n]; |
| 2807 | bool remove_from_list = false; |
| 2808 | if (tex->Status == ImTextureStatus_OK) |
| 2809 | { |
| 2810 | tex->Updates.resize(0); |
| 2811 | tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0; |
| 2812 | tex->UpdateRect.w = tex->UpdateRect.h = 0; |
| 2813 | } |
| 2814 | if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures) |
| 2815 | 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