Skip to content

(WIP) Dynamic glyph rasterization and unlimited number of font textures #3471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 30 commits into from

Conversation

georgegerdin
Copy link

@georgegerdin georgegerdin commented Sep 14, 2020

This PR is my attempt at bringing dynamic glyph rasterization and unlimited number of font textures to Dear ImGui. This is my proposal to fix #3365 #3406 #797 and all issues related to chinese glyphs, japanese glyphs etc...

Only the glfw_opengl2 and glfw_opengl3 backends are currently supported. The directx backends where changed to let me compile the example but do not work. I intend to fix them but wanted to show you my results before I get time for that. Tested on windows. Freetype, baked anti-aliased lines, software rendered mouse cursor and custom rects are not yet supported. The white pixel is located at (0, 0) on all generated font textures.

ImFontAtlas and ImFont has been completely revamped to generate glyphs upon use and packed in the same manner as fontstash. The rendering of the final text is the same as normal Dear ImGui. Instead of each font atlas having a personal FontSize the ImFontAtlas has a FontSize common to all loaded fonts.

Future plans is adding the missing features from normal Dear ImGui font code and unloading glyphs that have not been used for a certain amount of time.

x1flzgpcz3

Texture baked anti-aliasing and freetype is not yet supported.
Only GLFW-OpenGL2 and GLFW-OpenGL3 backends supported.
@ocornut
Copy link
Owner

ocornut commented Sep 16, 2020

Great work, thanks for posting this!
It's great to see a working proof of concept for that.

I haven't dug in this, but some early suggestions:

  • Try to use standardized greppable markers for known issues (e.g. FIXME-DYNAMICFONT). It seem to have lots of commented code/features feature and we'd need some work of tracking to figure out all the whys and what-to-do. This generally makes a PR less overwhelming to review and parse through.
  • I think we can separate and abstract the work on back-ends. For shadows we started working on (unpushed) api to have a standardized way of requesting back-end to reload the texture or part of it. It should be fairly simple at a first glance but in practice when (rarely) need to rewrite already written pixels (e.g. for compacting/garbage collecting) we have an issue with in-flight frames, which separately impact the interface with back-ends. That's a whole separate topic we could work on separately, so I suggest for now not worrying too much about the back-ends aspect. Hopefully once we have that protocol the font system can only say "here are some dirty rectangles, let the back-end figure it out". Having this PR along with the work on shadows is a great combination to test that feature.
  • We would need to allow resizing textures. Since this would be a very rare event, my plan to was to "simply" scale the UV of all submitted vertices (for which the TextureID is matching) so it become possible to do it mid-frame without impacting the frame.
  • GIF has visible glitches with missing/flickering characters during rescale (haven't investigated).
  • GIving you access to imgui_dev repo if you want to run some perf tests/comparaison. I need to stress that in all of this the performance requirement are quite paramount, since CalcTextSize() can be bit of a bottleneck in extremely large (clipped) ui.

@georgegerdin
Copy link
Author

Thank you for the feedback Omar. I have added FIXME-DYNAMICFONT comments in the places where I soon intend to fix features. The remaining commented blocks are for CustomRect and baked antialiased lines which is not yet supported. I think the flickering is because I am currently generating glyphs in one frame and uploading to the graphics card in the next frame but this should be easy to fix by uploading at the end of the current frame instead.

@ocornut
Copy link
Owner

ocornut commented Sep 26, 2020

I noticed in a gif you posted that it fallbacks to many textures, but then how are drawcalls handled? Wouldn’t this lead to drawcalls explosion very fast?

@georgegerdin
Copy link
Author

There is only one draw call per font texture used. I have not implemented resizing font textures yet since I thought multiple font textures would still be a prerequisite to make it scalable since there is a limit how large a texture can be but no limit on how many textures there can be.

ImFont::RenderText works like this: (lines correspond to latest commit 986738c)

  1. Loop through font characters and FindGlyph for each character like in master ImFont::RenderText
  2. The first glyph decides the primary font texture (line 3030-3035)

PrimReserve data for vertices and indices(line 3038 in latest push) just like in master ImFont::RenderText (line 3037-3044). This needs wait until here because we need to know which is the primary font texture.

  1. If the glyph is located on another font texture than the primary one:
  1. If this is the first time this font texture is used create a FontRenderList job for this font texture (line 3061 - 3068)
  2. Store the glyph data for later rendering (line 3125-3157) (same logic as master but this data will be merged to the draw list at the end of the function
  1. If the glyph is on the primary font texture render it to the draw list like in master (line 3219-3228)

  2. When all characters have been iterated clean up the vertex and index buffers (line 3238-3248)

  3. memcpy the characters on other font textures(collected in step 2) from the FontRenderList jobs to the end of the draw list (line 3255-3276).

In summary:

  1. In the worst case scenario the number of drawcalls equal the number of font textures.
  2. The number of draw calls equal the number of font textures the RenderText call needs to use depending on which font texture the glyph lives.
  3. If all glyphs are located on the first font texture there should be no difference from before.

My latest push fixes the flicker issues.

@ocornut
Copy link
Owner

ocornut commented Sep 27, 2020

My latest push fixes the flicker issues.

Great!

multiple font textures would still be a prerequisite

I think the the draw call explosion would be so problematic it is saner to focus on a system when we either

    1. never ever expect multiple font textures.
    1. very rarely expect multiple font textures and recover from it.
      So focusing on e.g. eviction/gc.

In the worst case scenario the number of drawcalls equal the number of font textures

But to be z-order preserving that's per call to RenderText()? And we want to support thousands of calls to RenderText() every frame, interleaved with shapes. To minimize it guess we could have a scheme were:

  • Texture data to support shape rendering could be present in every texture.
  • Garbage collection would reassign/move glyphs to reassemble fonts together in same texture.

I've added you the imgui_dev/ repository btw, when you run test_app under "Perfs" you can run perf tests (and probably add new ones) to compare branches, a critical part of this feature is and has always been performance of CalcTextSize() and RenderText() in the normal idle rendering case, for both Debug and Optimized builds, so it would be good to have early metrics of how the current version fare and see if we are within an acceptable ballpark for perfs.

Thanks!

imgui_draw.cpp Outdated
result = &this->Glyphs[i]; // Save the result
if(!backup_glyph) break; //Caller didn't want a backup glyph
if((this->Glyphs[i].FontTexture && this->Glyphs[i].FontTexture->TexID != NULL) && this->Glyphs[i].FrameCountCreation != ImGui::GetFrameCount()) {
*backup_glyph = NULL; // This glyph has already been rendered and uploeaded to the graphics card. No backup glyph needed.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*backup_glyph = NULL; // This glyph has already been rendered and uploeaded to the graphics card. No backup glyph needed.
*backup_glyph = NULL; // This glyph has already been rendered and uploaded to the graphics card. No backup glyph needed.

@georgegerdin
Copy link
Author

I think the the draw call explosion would be so problematic it is saner to focus on a system when we either

* 1. never ever expect multiple font textures.

* 1. very rarely expect multiple font textures and recover from it.
     So focusing on e.g. eviction/gc.

In the worst case scenario the number of drawcalls equal the number of font textures

But to be z-order preserving that's per call to RenderText()? And we want to support thousands of calls to RenderText() every frame, interleaved with shapes. To minimize it guess we could have a scheme were:

* Texture data to support shape rendering could be present in every texture.

* Garbage collection would reassign/move glyphs to reassemble fonts together in same texture.

I've added you the imgui_dev/ repository btw, when you run test_app under "Perfs" you can run perf tests (and probably add new ones) to compare branches, a critical part of this feature is and has always been performance of CalcTextSize() and RenderText() in the normal idle rendering case, for both Debug and Optimized builds, so it would be good to have early metrics of how the current version fare and see if we are within an acceptable ballpark for perfs.

Thanks!

I will focus on garbage collection and rearranging the glyphs to allow them to remain on the first font texture.

These are the results I get when comparing to vanilla imgui. Am I reading it right that my version in -O3 is about a millisecond slower per frame? Since the tests results are similar when displaying proggy-clean on texture 1 and roboto-medium on texture 2 in release mode I think it is an indication that most of the disparity compared to master are optimizations I have not yet implemented.

With master imgui -O0 (Debug):

perf,perf_draw_text_too_long,1.674,x5,master,Release,X64,Linux,GCC,2020-09-28
perf,perf_draw_text_too_long_clipped,0.764,x5,master,Release,X64,Linux,GCC,2020-09-28
perf,perf_draw_text_too_long_wrapped,2.382,x5,master,Release,X64,Linux,GCC,2020-09-28
perf,perf_draw_text_too_long_wrapped_clipped,1.123,x5,master,Release,X64,Linux,GCC,2020-09-28

With master imgui -O3 (Release):

perf,perf_draw_text_too_long,0.894,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_clipped,0.372,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped,1.348,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped_clipped,0.554,x5,master,Release,X64,Linux,GCC,2020-09-30

With dynamic fonts -O0 (Debug): (Proggy-Clean on font texture 1)

perf,perf_draw_text_too_long,4.230,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_clipped,2.148,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped,6.402,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped_clipped,3.508,x5,master,Release,X64,Linux,GCC,2020-09-30

With dynamic fonts -O3 (Release): (Proggy-Clean on font texture 1)

perf,perf_draw_text_too_long,2.035,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_clipped,0.980,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped,2.871,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped_clipped,1.407,x5,master,Release,X64,Linux,GCC,2020-09-30

With dynamic fonts -O0 (Debug): (Roboto-Medium on font texture 2)

perf,perf_draw_text_too_long,4.228,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_clipped,2.123,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped,6.337,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped_clipped,3.357,x5,master,Release,X64,Linux,GCC,2020-09-30

With dynamic fonts -O3 (Release): (Roboto-Medium on font texture 2)

perf,perf_draw_text_too_long,2.099,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_clipped,1.058,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped,2.991,x5,master,Release,X64,Linux,GCC,2020-09-30
perf,perf_draw_text_too_long_wrapped_clipped,1.420,x5,master,Release,X64,Linux,GCC,2020-09-30

@ocornut
Copy link
Owner

ocornut commented Sep 30, 2020

Am I reading it right that my version in -O3 is about a millisecond slower per frame?

Thanks for the update! Yes that's correct. Another way to read it is to state it is currently about 2-2.5 slower in both -O0 and -O3.

For info, the Perf function measure the base dt before starting the test, so the time display is the added difference from that baseline (actual app may be e.g. an extra 1 ms to do the swap etc.).

Those specific four tests are stressing one specific aspect - hammering text functions only. Since this is not really what a real app does, maybe we'd get more real-world representative number by running the perf_demo_all test which opens everything in the demo (and fix their pos/size to ensure comparable clipping across sessions). For large amount of clipped content there also will be more calls to CalcTextSize without the DrawText part (since rendering tends to be limited to visible stuff). There the ratio should comparatively be smaller as more time will be spent in other ImGui code, layout, clipping etc.

Later on, another test which will be worth pursuing will be with lots of glyphs (e.g. rendering a typical of Chinese text) as with the new algorithm the hashing will be stressed a little more. Depending on how it far we can adjust the hashing, or perhaps even have specialization for ascii ranges of if find it is worth it.

(hope we can later work on systems to turn that CSV data into easy to visualize stuff)
(do you happen know which ifdef we could tap into to automatically set build_info.Type to "Debug" in ImBuildGetCompilationInfo() with GCC? i'm not using GCC much here)

@frink
Copy link
Contributor

frink commented Oct 2, 2020

FWIW: I just found this header-only font library tonight that seems amazingly close to the overall architectural methodology of Dear Imgui. It's quite different from what you're doing in this PR but might still be an interesting read...

https://github.com/kv01/ttf-parser - Seems like a mature abandon'ed project...

I really don't know much about how the font stuff works. Might be a complete waste of time. But anyway. Just trying to be friendly and pass something interesting along. It's about a thousand lines, comments and all, so should be a quick read. License is identical too so you are free to "borrow code" if it does end up being useful.

If it helps ,great. If it's a distraction, sorry about that...

In any case, keep up the good work. Looking forward to dynamically re-sizable fonts!!

@georgegerdin
Copy link
Author

I left a PR on how to change the makefile to detect debug mode on Linux. I don't think you can do it only using a #define.

frink: Thank you, but that looks like a parser of .ttf-files and I am still using STB or optionally Freetype for rendering those like vanilla imgui. This branch is about how imgui could handle the generated glyphs on the font texture to display them in different sizes while remaining fast. So it is a step after the library you are linking to. Freetype is a heavier dependency but more visually pleasing and the industry standard.

@frink
Copy link
Contributor

frink commented Oct 5, 2020

Yes it is a parse that parses straight to GL triangles if I understand correctly. Not sure if it's better. Just different. First time I've seen GPU engaged to rasterize fonts. My thought is that if we're using GL for everything already why rasterize fonts as an intermediary step? You've probably got a better but it seemed like an interesting idea...

@Khodyn
Copy link

Khodyn commented Nov 10, 2020

Any news on when this will be merged? This is exactly what I need.

@frink
Copy link
Contributor

frink commented Nov 17, 2020

Any news on when this will be merged? This is exactly what I need.

Could be a while. Good code takes time and this one is no picnic.

Right now the best thing you can do is oversample your font atlas in the init stage and then use font scaling.
This PR will be better than that method but should not require a large refactoring of code once this is release.
I've found that oversampling is tolerable in most situations...

time. When the primary font texture is full overflow font textures are
used to render the remaining glyphs. On the next frame all glyphs are
cached and a new primary font texture is assembled with the glyphs from
the cache.

 Changes to be committed:
	modified:   examples/imgui_impl_opengl2.cpp
	modified:   examples/imgui_impl_opengl3.cpp
	modified:   imgui.h
	modified:   imgui_demo.cpp
	modified:   imgui_draw.cpp
@georgegerdin
Copy link
Author

In the latest update only one font texture is used 99% of the time. When the primary font texture is full glyphs spill over to overflow texture(s). On the next frame all glyphs are moved to a cache and the font atlas re-assembled with the custom rects and the currently visible glyphs.

This is ocornut:master on my machine:
1624793551148158,perf,perf_demo_all,0.858,x5,master,Release,X64,Linux,GCC,2021-06-27

This is the dynamic font branch on my machine (no glyph overflows triggered):
perf,perf_demo_all,0.860,x5,master,Release,X64,Linux,GCC,2021-06-27
perf,perf_demo_all,0.798,x5,master,Release,X64,Linux,GCC,2021-06-27

@ocornut
Copy link
Owner

ocornut commented Oct 15, 2024

I'll be resuming work on a similar feature in the upcoming few months. The truth is that we've accumulated 3-4 solid chunks of work related to this (incl this PR and e.g. #3761 which is one back-bone of this + various private bits of work). But there are hundreds of important decisions I need to nail right and very precisely. So I'm basically starting from scratch again but I will be referring to all past work whenever I wonder how something was approached or solved. Thanks for this!

@Stifler9000
Copy link

I'm trying to make use of this pull request until official support for this is added. It works just fine except for one really annoying and probably easy to fix bug:
a

Rounded frames always have a blackish hue to them and sometimes even parts of the non-rounded frame completely disappear. Tried glfw opengl3 and opengl2 renderers, both have the same issue. Everything else seems to work perfectly fine so I'm very confused. This is a minimal example just using Begin()/Button("test")/End()

Thanks for the work @georgegerdin by the way, this would be a godsend for me if it weren't for that small bug. Unfortunately I'm not that well versed with deep imgui internals yet but I'll continue to try and find the cause for a little while. I'll let you know should I find anything

@Stifler9000
Copy link

While I haven't found the cause yet, here is some more information. Dx9 renderer has the same behavior, and here's some reproduction code (ploppoed right into the imgui examples):

ImGui::Begin("test window");
const ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRect(pos, { pos.x + 50.f, pos.y + 50.f }, IM_COL32(200, 200, 200, 255), 4);
ImGui::End();

Which results in this:
a

@Stifler9000
Copy link

Found a workaround, io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines; seems to fix it. It's not ideal but it works, hopefully someone can come up with a proper fix for this PR sooner or later :)

@ocornut
Copy link
Owner

ocornut commented Oct 30, 2024

I have pushed a fix 6c8b46e for the issue your reported.
(I wanted to take the occasion to fix some of the warnings I got, but I wasn't sure if the float>int>float round-trips in FindGlyph() where intended or accidental.)

@ocornut
Copy link
Owner

ocornut commented Oct 30, 2024

Any news on when this will be merged? This is exactly what I need.

FYI for clarity I ran basic performance tests on this:

ImVec2 p = ImGui::GetCursorScreenPos();
for (int n = 0; n < 5000; n++)
{
    ImGui::SetCursorScreenPos(p);
    ImGui::Text("This is some useful text.\nhfds3714u24i2orwrjijIJ@I!IJ!J#!#J!");
}
master: debug x64: ~28 ms / frame
master: release x64: ~7.3 ms / frame
pr 3471: debug x64: ~136 ms / frame
pr 3471: release x64: ~12.7 ms / frame

I am unfortunately unable to consider a PR with those performances characteristics.
This is one of the reason I will be rewriting this from the ground up. As mentioned it may be useful as a reference for when I stumble on questions, to see how it was solved here. I do wholly appreciate the work put here, it's not a simple problem to solve correctly. But performance requirement is the number 1 requirement of Dear ImGui, and I don't need to run the code to see that the current implementation of ::RenderText() is going to far poorer in term of CPU. We'll need find a solution that has acceptable performances characteristics.

(I am also unfortunately unable to thoroughly review PR not following the coding style. I sincerely wish I had the mind and brain to overlook this but I am unable to, my brains gives up easily)

@georgegerdin
Copy link
Author

georgegerdin commented Nov 3, 2024

It's disappointing it is still too slow. Here are the latest perflogs on my machine if they are of any use - looks like it is a lot slower than when I last tested it in the test engine:

master:

1730593875041375,perf,perf_demo_all,2.194,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_stroke,0.296,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_stroke_thick,0.316,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_filled,0.090,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_rounded_stroke,1.056,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_rounded_stroke_thick,1.047,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_rect_rounded_filled,1.064,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_circle_stroke,2.477,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_circle_stroke_thick,2.469,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_circle_filled,2.596,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_triangle_stroke,0.294,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_triangle_stroke_thick,0.264,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_long_stroke,0.699,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_long_stroke_thick,0.775,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_long_jagged_stroke,0.320,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_long_jagged_stroke_thick,0.347,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line,0.133,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line_antialiased,0.237,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line_antialiased_no_tex,0.232,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line_thick,0.153,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line_thick_antialiased,0.258,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_prim_line_thick_antialiased_no_tex,0.330,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_split_1,0.913,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_split_10,0.954,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_button,2.439,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_button_disabled,1.263,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_checkbox,1.288,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_rows_1a,0.224,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_rows_1b,0.282,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_columns_1,0.464,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_columns_2,0.828,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_columns_3_selectable,0.814,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_tables_basic_tables_lo_cols_lo_rows_hi,0.405,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_tables_basic_tables_hi_cols_lo_rows_lo,0.682,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_tables_basic_tables_hi_cols_hi_rows_lo,2.875,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_tables_basic_tables_lo_cols_hi_rows_hi,0.493,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_coloredit4,1.577,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_input_text,1.501,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_input_text_multiline,2.108,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_hash,6.264,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_list_box,1.357,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_slider,1.421,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_slider2,3.701,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_text_unformatted_1,4.357,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_text_unformatted_2,4.278,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_stress_window,6.843,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_circle_segment_counts,0.338,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_misc_lines,0.085,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_short,2.640,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_short_clipped,0.875,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_short_wrapped,3.173,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_short_wrapped_clipped,1.151,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_long,2.505,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_long_clipped,0.791,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_long_wrapped,3.136,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_long_wrapped_clipped,1.165,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_too_long,1.993,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_too_long_clipped,0.781,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_too_long_wrapped,2.524,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593875041375,perf,perf_draw_text_too_long_wrapped_clipped,0.987,x5,unknown,Release,X64,Linux,GCC,2024-11-03

Dynamic fonts:

1730593524619052,perf,perf_demo_all,3.348,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_stroke,0.324,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_stroke_thick,0.320,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_filled,0.065,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_rounded_stroke,1.059,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_rounded_stroke_thick,1.064,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_rect_rounded_filled,1.048,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_circle_stroke,2.498,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_circle_stroke_thick,2.471,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_circle_filled,2.617,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_triangle_stroke,0.274,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_triangle_stroke_thick,0.265,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_long_stroke,0.713,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_long_stroke_thick,0.708,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_long_jagged_stroke,0.314,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_long_jagged_stroke_thick,0.315,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line,0.110,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line_antialiased,0.239,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line_antialiased_no_tex,0.261,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line_thick,0.128,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line_thick_antialiased,0.232,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_prim_line_thick_antialiased_no_tex,0.314,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_split_1,0.903,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_split_10,0.963,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_button,3.675,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_button_disabled,2.435,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_checkbox,2.425,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_rows_1a,0.430,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_rows_1b,0.487,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_columns_1,0.681,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_columns_2,1.112,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_columns_3_selectable,1.013,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_tables_basic_tables_lo_cols_lo_rows_hi,0.625,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_tables_basic_tables_hi_cols_lo_rows_lo,0.899,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_tables_basic_tables_hi_cols_hi_rows_lo,3.133,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_tables_basic_tables_lo_cols_hi_rows_hi,0.583,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_coloredit4,1.891,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_input_text,2.362,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_input_text_multiline,2.943,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_hash,6.297,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_list_box,2.040,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_slider,2.448,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_slider2,4.982,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_text_unformatted_1,20.507,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_text_unformatted_2,4.394,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_stress_window,8.485,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_circle_segment_counts,0.334,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_misc_lines,0.107,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_short,4.090,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_short_clipped,1.618,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_short_wrapped,5.732,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_short_wrapped_clipped,2.467,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_long,3.935,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_long_clipped,1.598,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_long_wrapped,5.936,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_long_wrapped_clipped,2.602,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_too_long,3.203,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_too_long_clipped,1.544,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_too_long_wrapped,4.833,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730593524619052,perf,perf_draw_text_too_long_wrapped_clipped,2.166,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_demo_all,3.094,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_stroke,0.324,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_stroke_thick,0.261,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_filled,0.038,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_rounded_stroke,1.000,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_rounded_stroke_thick,1.039,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_rect_rounded_filled,1.036,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_circle_stroke,2.406,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_circle_stroke_thick,2.465,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_circle_filled,2.603,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_triangle_stroke,0.235,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_triangle_stroke_thick,0.259,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_long_stroke,0.661,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_long_stroke_thick,0.663,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_long_jagged_stroke,0.286,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_long_jagged_stroke_thick,0.275,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line,0.119,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line_antialiased,0.192,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line_antialiased_no_tex,0.229,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line_thick,0.109,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line_thick_antialiased,0.200,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_prim_line_thick_antialiased_no_tex,0.280,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_split_1,0.917,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_split_10,0.916,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_button,3.591,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_button_disabled,2.370,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_checkbox,2.387,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_rows_1a,0.411,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_rows_1b,0.446,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_columns_1,0.664,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_columns_2,1.082,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_columns_3_selectable,0.988,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_tables_basic_tables_lo_cols_lo_rows_hi,0.625,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_tables_basic_tables_hi_cols_lo_rows_lo,0.894,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_tables_basic_tables_hi_cols_hi_rows_lo,3.132,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_tables_basic_tables_lo_cols_hi_rows_hi,0.573,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_coloredit4,1.854,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_input_text,2.377,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_input_text_multiline,2.931,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_hash,6.252,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_list_box,2.042,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_slider,2.448,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_slider2,5.036,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_text_unformatted_1,20.566,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_text_unformatted_2,4.342,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_stress_window,8.416,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_circle_segment_counts,0.344,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_misc_lines,0.087,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_short,4.057,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_short_clipped,1.609,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_short_wrapped,5.777,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_short_wrapped_clipped,2.451,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_long,3.910,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_long_clipped,1.598,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_long_wrapped,5.882,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_long_wrapped_clipped,2.603,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_too_long,3.170,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_too_long_clipped,1.518,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_too_long_wrapped,4.844,x5,unknown,Release,X64,Linux,GCC,2024-11-03
1730594416270176,perf,perf_draw_text_too_long_wrapped_clipped,2.149,x5,unknown,Release,X64,Linux,GCC,2024-11-03

@Stifler9000
Copy link

One question: Freetype support was supposedly added in commit 58b51b1. Yet, including imgui_freetype.cpp results in an error in ImFontAtlasBuildWithFreeTypeEx because ImFont::AddGlyph was removed/doesn't exist. Am I being stupid here?

@ocornut ocornut added this to the v1.92 milestone Dec 5, 2024
@ocornut
Copy link
Owner

ocornut commented Dec 5, 2024

FYI i've been working on a reimplemention of this and expect a public beta branch to be avail before end of the month.

@db48x
Copy link

db48x commented Dec 6, 2024

Am I being stupid here?

No, but perhaps unobservant. This branch is somewhat out of date.

It sounds like we have much to look forward to in the new year, perhaps even a wonderful Christmas present. I feel that I can hardly wait.

BTW, for my project I decided to use the Unicode CLDR database to inform the font atlas I build. This database has a list of characters used by each locale’s script(s), so I add the characters from the locale corresponding to the selected translation to the atlas, along with the default characters and a selection of arrows, superscripts, and a few other things. Even once dynamic glyph rasterization is available we’ll probably still build the default atlas the same way. Dynamic glyphs will just be used when the user happens to type in something unexpected.

@Stifler9000
Copy link

ImFontAtlasBuildWithFreeTypeEx

On the offchance that anyone wants to use FreeType with this... The ImFontAtlasBuildWithFreeTypeEx and related functions can simply be deleted as they're not called anymore.
On another note, very excited for the official beta branch for this :)

@Stifler9000
Copy link

Stifler9000 commented Feb 13, 2025

I've noticed a fairly deal-breaking bug about this branch.
The annoying part is, that... it's not really reproducible.
One day, text rendering is completely fine. The next day, it looks like this:
1

Those are supposed to be some numbers. Mind you, this happens without any change in the executable.
This happens with both opengl3 and directx9.
Further, the same application crashes for some people while it does not crash others. I've narrowed the crash down to a ImFont::CalcTextSizeA call (and in there, ImFont::FindGlyph). Strangely enough, the crash doesn't occur on many other characters in the same font, just some characters.
I'm only loading one font, namely Noto Sans SC (with FreeType enabled)

Not sure if this is really worth looking into considering @ocornut mentioned an eventual official implementation of this.
Speaking of.... don't want to be that guy, but any ETA on when that beta branch might happen?
Thanks for everything you're doing, both @georgegerdin and @ocornut!

@Stifler9000
Copy link

Well, as an update, the aforementioned issues only occur with the FreeType implementation (IMGUI_ENABLE_FREETYPE). I'll invest some time to try and get to the bottom of it

@Stifler9000
Copy link

With the power of more hindsight, I can conclude that the crashing issues are fixed without FreeType but not the mangled text.
Wasn't able to find the cause for either of those unfortunately :(

@ocornut
Copy link
Owner

ocornut commented Mar 5, 2025

Closing this as we'll be moving into #8465, current WIP dynamic_fonts branch is aimed to be merged for 1.92 after we get enough feedback. Feedback greatly welcome!

2025-01-27.font.resize.mp4

The general performance characteristics are that for a typical idle-frame with no new glyphs, things are expected to be about 1-2% slower.

Actual glyph baking, packing, atlas compacting/repacking/copying etc operations are of course slower but they tend to be amortized really quickly. The worst-case-ish scenario of continuously zooming a bunch of Chinese text can still run at interactive framerate but is not expected to be super fast if large sizes are not in cache. Typical EFIGS languages or even Japanese are likely to not encounter meaningful performances issues.

@ocornut ocornut closed this Mar 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Separating text capabilities from Dear ImGui
7 participants