Add a DxRenderer based on a glyph atlas #14271

Closed
opened 2026-01-31 04:05:40 +00:00 by claunia · 33 comments
Owner

Originally created by @lhecker on GitHub (Jun 19, 2021).

Description of the new feature/enhancement

While the initial layouting and rasterization of glyphs is computationally expensive, the composition using a classic texture atlas and glyph-lookup-texture is extremely fast and, unless new glyphs appear on the screen, can be rendered in a single pass. Such an implementation would provide us with a high-framerate, low-latency renderer.

Proposed technical implementation details

The initial implementation to just render pure, colored, single-glyph-per-code-point text is quite trivial obviously. Guidance for this can be obtained from many sources throughout the web (even WikiBooks!). After an initial implementation has been drafted additional features could be added incrementally over time.
The renderer should live as an optional feature, that can be toggled on if the user wants to.

Further experience can be gained from the alacritty project.

Alternative solutions

DirectWrite uses a glyph atlas internally and we could continue to rely on it, but just optimize our render pass instead.
For instance a hybrid-approach would be feasible: Render everything but glyphs using a shader.

Originally created by @lhecker on GitHub (Jun 19, 2021). # Description of the new feature/enhancement While the initial layouting and rasterization of glyphs is computationally expensive, the composition using a classic texture atlas and glyph-lookup-texture is extremely fast and, unless new glyphs appear on the screen, can be rendered in a single pass. Such an implementation would provide us with a high-framerate, low-latency renderer. # Proposed technical implementation details The initial implementation to just render pure, colored, single-glyph-per-code-point text is quite trivial obviously. Guidance for this can be obtained from many sources throughout the web (even WikiBooks!). After an initial implementation has been drafted additional features could be added incrementally over time. The renderer should live as an optional feature, that can be toggled on if the user wants to. Further experience can be gained from the alacritty project. # Alternative solutions DirectWrite uses a glyph atlas internally and we could continue to rely on it, but just optimize our render pass instead. For instance a hybrid-approach would be feasible: Render everything but glyphs using a shader.
Author
Owner

@lhecker commented on GitHub (Jun 19, 2021):

Feedback welcome! 🤗
(I'll keep the issue description updated with any feedback.)

@lhecker commented on GitHub (Jun 19, 2021): Feedback welcome! 🤗 (I'll keep the issue description updated with any feedback.)
Author
Owner

@skyline75489 commented on GitHub (Jun 19, 2021):

Sure. Why not?

We have software renderer option for people who face hardware rendering issue. Adding a “performance” renderer for people who want the most of the performance(& use only English & want none of the Unicode features) sounds reasonable. Also alacritty has done this before, if I’m not mistaken. So there’s at least one popular examples.

I humbly ask for basic CJK support for the initial implementation, because, well, I live in a cave where people use CJK as their primary languages.

@skyline75489 commented on GitHub (Jun 19, 2021): Sure. Why not? We have software renderer option for people who face hardware rendering issue. Adding a “performance” renderer for people who want the most of the performance(& use only English & want none of the Unicode features) sounds reasonable. Also alacritty has done this before, if I’m not mistaken. So there’s at least one popular examples. I humbly ask for basic CJK support for the initial implementation, because, well, I live in a cave where people use CJK as their primary languages.
Author
Owner

@cedric-h commented on GitHub (Jun 19, 2021):

I don't think ClearType in particular has been done before.

image

Here's a picture I took of Alacritty in Renderdoc. All of the glyphs are rendered in two draw calls, one for background and one for foreground. I believe this is done to facilitate ClearType.

EDIT: Confirmation from Alacritty contributor that ClearType is in use: https://github.com/alacritty/alacritty/issues/2645#issuecomment-511171344

@cedric-h commented on GitHub (Jun 19, 2021): > I don't think ClearType in particular has been done before. ![image](https://user-images.githubusercontent.com/25539554/122647605-e48c6000-d0f2-11eb-983a-10694bd13a90.png) Here's a picture I took of [Alacritty](https://github.com/alacritty/alacritty) in Renderdoc. All of the glyphs are rendered in two draw calls, one for background and one for foreground. I believe this is done to facilitate ClearType. EDIT: Confirmation from Alacritty contributor that ClearType is in use: https://github.com/alacritty/alacritty/issues/2645#issuecomment-511171344
Author
Owner

@cedric-h commented on GitHub (Jun 19, 2021):

Sure. Why not?

We have software renderer option for people who face hardware rendering issue. Adding a “performance” renderer for people who want the most of the performance(& use only English & want none of the Unicode features) sounds reasonable. Also alacritty has done this before, if I’m not mistaken. So there’s at least one popular examples.

I humbly ask for basic CJK support for the initial implementation, because, well, I live in a cave where people use CJK as their primary languages.

The obvious answer to "Why not?" is because the benchmarking experiments done here and here suggest that the naive string parsing is a bottleneck long before rendering comes into play.

With regards to supporting multiple languages, that should not be a significant limitation, it's simply a matter of adding more glyphs to your atlas; see this example created in response to the controversy in this issue

@cedric-h commented on GitHub (Jun 19, 2021): > Sure. Why not? > > We have software renderer option for people who face hardware rendering issue. Adding a “performance” renderer for people who want the most of the performance(& use only English & want none of the Unicode features) sounds reasonable. Also alacritty has done this before, if I’m not mistaken. So there’s at least one popular examples. > > I humbly ask for basic CJK support for the initial implementation, because, well, I live in a cave where people use CJK as their primary languages. The obvious answer to "Why not?" is because the benchmarking experiments done [here](https://github.com/microsoft/terminal/issues/10362#issuecomment-856589469) and [here](https://github.com/microsoft/terminal/issues/10362#issuecomment-857319441) suggest that the naive string parsing is a bottleneck long before rendering comes into play. With regards to supporting multiple languages, that should not be a significant limitation, it's simply a matter of adding more glyphs to your atlas; see [this example](https://twitter.com/mmozeiko/status/1406001541962555393) created in response to the controversy in [this issue](https://github.com/microsoft/terminal/issues/10362)
Author
Owner

@mdtauk commented on GitHub (Jun 19, 2021):

I may be very simplistic here, but does this mean larger font sizes will have a performance impact?

@mdtauk commented on GitHub (Jun 19, 2021): I may be very simplistic here, but does this mean larger font sizes will have a performance impact?
Author
Owner

@cedric-h commented on GitHub (Jun 19, 2021):

I may be very simplistic here, but does this mean larger font sizes will have a performance impact?

You render your glyph atlas very rarely (whenever a never-before-rendered character is encountered) compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator which uses this technique to render.

@cedric-h commented on GitHub (Jun 19, 2021): > I may be very simplistic here, but does this mean larger font sizes will have a performance impact? You render your glyph atlas very rarely (whenever a never-before-rendered character is encountered) compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator which uses this technique to render.
Author
Owner

@mdtauk commented on GitHub (Jun 19, 2021):

I may be very simplistic here, but does this mean larger font sizes will have a performance impact?

You render your glyph atlas very rarely compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator.

Ah so the Atlas is for the window display itself, not as a texture source off-screen for use when rendering?

@mdtauk commented on GitHub (Jun 19, 2021): > > I may be very simplistic here, but does this mean larger font sizes will have a performance impact? > > You render your glyph atlas very rarely compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator. Ah so the Atlas is for the window display itself, not as a texture source off-screen for use when rendering?
Author
Owner

@cedric-h commented on GitHub (Jun 19, 2021):

I may be very simplistic here, but does this mean larger font sizes will have a performance impact?

You render your glyph atlas very rarely compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator.

Ah so the Atlas is for the window display itself, not as a texture source off-screen for use when rendering?

No, that is the opposite of what I intended to convey.

@cedric-h commented on GitHub (Jun 19, 2021): > > > I may be very simplistic here, but does this mean larger font sizes will have a performance impact? > > > > > > You render your glyph atlas very rarely compared to how often the actual grid of glyphs is rendered (every frame) and larger font sizes mean less cells in your grid, so generally larger font sizes will always be more performant in a terminal emulator. > > Ah so the Atlas is for the window display itself, not as a texture source off-screen for use when rendering? No, that is the opposite of what I intended to convey.
Author
Owner

@lhecker commented on GitHub (Jun 19, 2021):

@skyline75489
I believe most of CJK is exactly the "single-glyph-per-char" case I mentioned and should be simple to render.

@cedric-h
Nice find! As far as I can see they only use ClearType for rendering the alpha texture of the glyph, which we can do as well. That doesn't mean the final composition is proper ClearType though (since that requires knowledge of the background color among others). They draw in two passes because they draw background and text separately. But it'd be absolutely awesome if I'm wrong! Can you point me to a comment explaining how they implement ClearType during the final render? I can't find anything in the code nor issues about it unfortunately.

The obvious answer to "Why not?" is because [...]

Please don't be inflammatory, alright? 🤗
I'm sure you know full well that "Why not?" is an idiom.

@lhecker commented on GitHub (Jun 19, 2021): @skyline75489 I believe most of CJK is exactly the "single-glyph-per-char" case I mentioned and should be simple to render. @cedric-h Nice find! As far as I can see they only use ClearType for rendering the alpha texture of the glyph, which we can do as well. That doesn't mean the final composition is proper ClearType though (since that requires knowledge of the background color among others). They draw in two passes because they draw background and text separately. But it'd be absolutely awesome if I'm wrong! Can you point me to a comment explaining how they implement ClearType during the final render? I can't find anything in the code nor issues about it unfortunately. > The obvious answer to "Why not?" is because [...] Please don't be inflammatory, alright? 🤗 I'm sure you know full well that "Why not?" is an idiom.
Author
Owner

@skyline75489 commented on GitHub (Jun 19, 2021):

@lhecker For Chinese, most characters I believe belong to the “single-glyph-per-char" category. But there’s other issues for Japanese and Hangul demonstrated in #3546, naming IVS (Ideographic Variation Sequence) for Japanese and complex composite in Hangul.

IVS I believe also exists in Traditional Chinese (#8731) but I don’t know that side of the story much, meaning that I don’t know how important IVS is in Traditional Chinese environment.

@skyline75489 commented on GitHub (Jun 19, 2021): @lhecker For Chinese, most characters I believe belong to the “single-glyph-per-char" category. But there’s other issues for Japanese and Hangul demonstrated in #3546, naming IVS (Ideographic Variation Sequence) for Japanese and complex composite in Hangul. IVS I believe also exists in Traditional Chinese (#8731) but I don’t know that side of the story much, meaning that I don’t know how important IVS is in Traditional Chinese environment.
Author
Owner

@skyline75489 commented on GitHub (Jun 19, 2021):

I don’t know Hangul, but it seems to be even harder when it comes to composition, which requires NFKC composition. See https://github.com/microsoft/terminal/pull/3578#issuecomment-554591675

Man, finding those comments bring back memories of the good old days 😅

@skyline75489 commented on GitHub (Jun 19, 2021): I don’t know Hangul, but it seems to be even harder when it comes to composition, which requires NFKC composition. See https://github.com/microsoft/terminal/pull/3578#issuecomment-554591675 Man, finding those comments bring back memories of the good old days 😅
Author
Owner

@mmozeiko commented on GitHub (Jun 19, 2021):

Freetype is dual licenseed - BSD like FTL license and GPL. it is not just GPL license.

Shader from Alacritty does freetype style ClearType rendering using Dual Source Blending that OpenGL or D3D11 both support. Fragment shader outputs three blend factors separately for r/g/b channels. Although I'm not sure if they are doing that in correct colorspace (linear/sRGB), haven't look in their code to understand that completely.

That said - there is no reason to do this kind of blending. As renderer who draws text knows exactly what are both - background and foreground colors. So it can do whatever style blending & colorspace it wants directly in shader, and just output final cleartype color.

@mmozeiko commented on GitHub (Jun 19, 2021): Freetype is dual licenseed - BSD like FTL license and GPL. it is not just GPL license. Shader from Alacritty does freetype style ClearType rendering using Dual Source Blending that OpenGL or D3D11 both support. Fragment shader outputs three blend factors separately for r/g/b channels. Although I'm not sure if they are doing that in correct colorspace (linear/sRGB), haven't look in their code to understand that completely. That said - there is no reason to do this kind of blending. As renderer who draws text knows exactly what are both - background and foreground colors. So it can do whatever style blending & colorspace it wants directly in shader, and just output final cleartype color.
Author
Owner

@lhecker commented on GitHub (Jun 19, 2021):

@mmozeiko I'm currently considering to implement at least the initial version, as mentioned in the issue.
As you probably know, I cannot legally look at your (unlicensed) shader source code and haven't done so far.
If you ever feel like it, you can accelerate the development of the new renderer by contributing any small demo application that contains your shader and optionally its DirectWrite logic. This would help me skip the experimental phase and I could focus on integrating it into the existing render interface. Of course, please don't feel pressured to do so. 🙂

edit: I have been told that this message "sounds so nice it's borderline sarcastic". 😄
But if you look at my other comments on my profile you'll notice that I almost always write like this!
I'm simply considering this a reset from the mood of the very heated previous issue.

@lhecker commented on GitHub (Jun 19, 2021): @mmozeiko I'm currently considering to implement at least the initial version, as mentioned in the issue. As you probably know, I cannot legally look at your (unlicensed) shader source code and haven't done so far. If you ever feel like it, you can accelerate the development of the new renderer by contributing any small demo application that contains your shader and optionally its DirectWrite logic. This would help me skip the experimental phase and I could focus on integrating it into the existing render interface. Of course, please don't feel pressured to do so. 🙂 edit: I have been told that this message "sounds so nice it's borderline sarcastic". 😄 But if you look at my other comments on my profile you'll notice that I almost always write like this! I'm simply considering this a reset from the mood of the very heated previous issue.
Author
Owner

@mmozeiko commented on GitHub (Jun 19, 2021):

No problem.
I donate my shader to public domain, feel free to use it or relicense it however you wish: https://gist.github.com/mmozeiko/c7cd68ba0733a0d9e4f0a97691a50d39

@mmozeiko commented on GitHub (Jun 19, 2021): No problem. I donate my shader to public domain, feel free to use it or relicense it however you wish: https://gist.github.com/mmozeiko/c7cd68ba0733a0d9e4f0a97691a50d39
Author
Owner

@skyline75489 commented on GitHub (Jun 20, 2021):

Thanks @mmozeiko for the kind contribution!

I think for the initial version we can just focus on ASCII characters and forget about complex Unicode composition. To be honest, not many people are complaining that Hangul support is terrible or something. The western text will dominate most of the terminal usage for now and in foreseeable future.

That being said, I think we will continue the pursuit of better Unicode feature as much as we could, since being inclusive is part of the MS culture. A not-complete list of rich Unicode feature can be found at https://github.com/microsoft/terminal/issues/3546#issuecomment-554592064.

@skyline75489 commented on GitHub (Jun 20, 2021): Thanks @mmozeiko for the kind contribution! I think for the initial version we can just focus on ASCII characters and forget about complex Unicode composition. To be honest, not many people are complaining that Hangul support is terrible or something. The western text will dominate most of the terminal usage for now and in foreseeable future. That being said, I think we will continue the pursuit of better Unicode feature as much as we could, since being inclusive is part of the MS culture. A not-complete list of rich Unicode feature can be found at https://github.com/microsoft/terminal/issues/3546#issuecomment-554592064.
Author
Owner

@skyline75489 commented on GitHub (Jun 20, 2021):

I’d like to add more comments regarding overall Unicode support in Windows Terminal.

@mmozeiko I saw your and Casey’s comments on Twitter mentioning that the terminal had bad Unicode support. And that is true as shown in #3546 and other issues. You also mentioned that none of the existing terminals, be it on Windows or not, has correct Unicode composition support. That’s also true. What people may not realize, is that with the help of DWrite the glyph composition part become much easier. However, Windows Terminal, alongside other terminals on other platforms , lacks good algorithm & implementation for width estimation. There’s actually (slow but) ongoing work to improve that (See #8000). I believe when this is done, Windows Terminal might be the pioneer in Unicode support among the terminals. And we may also contribute the algorithm back to the community to help terminals on other platforms.

I honestly understand people’s dissatisfaction about the performance. IMO choosing DWrite over glyph atlas simplifies the problem when it comes to Unicode support, at the cost of slow performance when rendering ASCII characters. With both Windows & the terminal being a product used worldwide by millions of people , I wouldn’t really call this choice “infuriating”. There’s actually a lot of people need to work with Unicode content. I think we all want to empower them, not ignoring them.

I think a common ground is that we need to be correct, then be performant. My previous comments somewhat demonstrated how hard it is to make CJK work correctly. I don’t want to sound offensive and please don’t take this personally, but CJK & Emojis (with ZWJ) are probably the simplest features in Unicode IMO. I’m not even mentioning all the crazy layout rules and various kinds of joiners in all those south-asia and mid-east languages. Some of the composition rules make absolutely no sense for people who do not use that language. And remember we face all kinds of issues with help of DWrite, which is a very powerful layout engine. I can’t honestly imagine what it be like to achieve the same with bare bone glyph atlas implementation. You gonna have to find a way to support most Unicode features before you claim it supports “anything in Unicode”. If fact as we speak, Unicode itself is still evolving with more & more features added. So I doubt there will ever be something that support “anything in Unicode”.

With all the above being said, it doesn’t hurt anyone if we or the enthusiasts from the gaming industry take a shot at this specific project. I don’t want start no flames or nonsense arguments. I really want GitHub to be purely about the code, and only code.

@skyline75489 commented on GitHub (Jun 20, 2021): I’d like to add more comments regarding overall Unicode support in Windows Terminal. @mmozeiko I saw your and Casey’s comments on Twitter mentioning that the terminal had bad Unicode support. And that is true as shown in #3546 and other issues. You also mentioned that none of the existing terminals, be it on Windows or not, has correct Unicode composition support. That’s also true. What people may not realize, is that with the help of DWrite the glyph composition part become much easier. However, Windows Terminal, alongside other terminals on other platforms , lacks good algorithm & implementation for width estimation. There’s actually (slow but) ongoing work to improve that (See #8000). I believe when this is done, Windows Terminal might be the pioneer in Unicode support among the terminals. And we may also contribute the algorithm back to the community to help terminals on other platforms. I honestly understand people’s dissatisfaction about the performance. IMO choosing DWrite over glyph atlas simplifies the problem when it comes to Unicode support, at the cost of slow performance when rendering ASCII characters. With both Windows & the terminal being a product used worldwide by millions of people , I wouldn’t really call this choice “infuriating”. There’s actually a lot of people need to work with Unicode content. I think we all want to empower them, not ignoring them. I think a common ground is that we need to be correct, then be performant. My previous comments somewhat demonstrated how hard it is to make CJK work correctly. I don’t want to sound offensive and please don’t take this personally, but CJK & Emojis (with ZWJ) are probably the simplest features in Unicode IMO. I’m not even mentioning all the crazy layout rules and various kinds of joiners in all those south-asia and mid-east languages. Some of the composition rules make absolutely no sense for people who do not use that language. And remember we face all kinds of issues with help of DWrite, which is a very powerful layout engine. I can’t honestly imagine what it be like to achieve the same with bare bone glyph atlas implementation. You gonna have to find a way to support most Unicode features before you claim it supports “anything in Unicode”. If fact as we speak, Unicode itself is still evolving with more & more features added. So I doubt there will ever be something that support “anything in Unicode”. With all the above being said, it doesn’t hurt anyone if we or the enthusiasts from the gaming industry take a shot at this specific project. I don’t want start no flames or nonsense arguments. I really want GitHub to be purely about the code, and only code.
Author
Owner

@skyline75489 commented on GitHub (Jun 20, 2021):

To answer the question: can we choose to use glyph atlas when we found that the characters are all ASCII? That would be a good solution for both people who work with Unicode content and those who don’t, right?

Sadly no. This is discussed in #9156 & #9202. Turns out it’s not that easy to determine whether all ASCII characters are “simple” when it comes to layout(by simple I mean “does not require full script shaping”. This is done by calling the GetTextComplexity API) because of the existence of “locale based” letter forms(locl), which depends on the font being used and the current locale. This feature is used in languages like Turkish & Polish & etc. Some might think “this is just nonsense. No one really needs this”. But we want to be technically correct, don’t we. And I’m pretty sure such a feature has to be used by a reasonable amount of people on this planet for it to be a real-life feature. The conclusion is that, unless we are confident that with the glyph atlas approach all ASCII characters can all be correctly shaped (I think this should at least include ligature, baseline alignment & all the basic stuff) under various locales and fonts, we can’t just rely on it and call it a day.

I’d love to see anyone with the domain knowledge of Unicode and/or font that can help with my PR, which got reverted because it fails to handle certain cases. Apparently I’m not one of those Unicode experts.

@skyline75489 commented on GitHub (Jun 20, 2021): To answer the question: can we choose to use glyph atlas when we found that the characters are all ASCII? That would be a good solution for both people who work with Unicode content and those who don’t, right? Sadly no. This is discussed in #9156 & #9202. Turns out it’s not that easy to determine whether all ASCII characters are “simple” when it comes to layout(by simple I mean “does not require full script shaping”. This is done by calling the [GetTextComplexity](https://docs.microsoft.com/en-us/windows/win32/api/dwrite_1/nf-dwrite_1-idwritetextanalyzer1-gettextcomplexity) API) because of the existence of “locale based” letter forms(locl), which depends on the font being used and the current locale. This feature is used in languages like Turkish & Polish & etc. Some might think “this is just nonsense. No one really needs this”. But we want to be technically correct, don’t we. And I’m pretty sure such a feature has to be used by a reasonable amount of people on this planet for it to be a real-life feature. The conclusion is that, unless we are confident that with the glyph atlas approach all ASCII characters can all be correctly shaped (I think this should at least include ligature, baseline alignment & all the basic stuff) under various locales and fonts, we can’t just rely on it and call it a day. I’d love to see anyone with the domain knowledge of Unicode and/or font that can help with my PR, which got reverted because it fails to handle certain cases. Apparently I’m not one of those Unicode experts.
Author
Owner

@lhecker commented on GitHub (Jun 20, 2021):

@skyline75489 Yeah I personally agree that it's hard to reason about what's possible and what isn't when unicode comes into play.

But to be fair monospace-only support simplifies most things. For instance our console buffer currently is N characters wide, and should be N glyphs wide (and not just N graphemes either!). Solving this issue seems awfully similar to solving the layout issue for a glyph atlas. If we know what forms entire glyphs I believe there aren't many issues anymore you could possibly have.
In other words: A glyph atlas is entirely capable of drawing almost all of unicode!

Now the nice thing about using DirectWrite for entire runs of glyphs (and not just single glyphs) though is that we know we can trust it to perform entirely correctly no matter what we call it with. Fixing our unicode support in the buffer and non-DirectWrite related rendering code is far more trivial than actually figuring out what forms a glyph and could be done "relatively" soon. This would give us full unicode rendering support, even if the width buffer rows don't match the glyph count (for instance hebrew would look correctly, but you can only have let's say 20 glyphs on an 80-cell wide buffer row). A glyph atlas forces us to solve that prematurely and entirely.

The list of fundamentally unsolved glyph atlas issues that Alacritty has for instance shouldn't be taken lightly.
Many of those issues, again fundamentally, don't exist if you use DirectWrite for entire glyph runs.
Certainly one of the many reasons it was called as hard as a dissertation before. Skia's implementation certainly is...

That said I'm convinced we should make the glyph atlas renderer separate from the current DxRenderer.
While it slightly increases the maintenance burden, both approaches are fundamentally different. Additionally there are some concerns which I'll be mentioning later.


With all the above being said, it doesn’t hurt anyone if we or the enthusiasts from the gaming industry take a shot at this specific project.

Yep! And I'm entirely on it!
It did hurt though, to be an actual human with feelings and stuff, who might get offended if people are rude. 😐
Sarcasm aside: It is on us, for not taking the technical advice at face value, no matter the delivery!
This one of the reasons we've since reopened the gates for @cmuratori et. al. again, after some time of self-reflection.

@lhecker commented on GitHub (Jun 20, 2021): @skyline75489 Yeah I personally agree that it's hard to reason about what's possible and what isn't when unicode comes into play. But to be fair monospace-only support simplifies most things. For instance our console buffer currently is N characters wide, and should be N glyphs wide (and not just N graphemes either!). Solving this issue seems awfully similar to solving the layout issue for a glyph atlas. If we know what forms entire glyphs I believe there aren't many issues anymore you could possibly have. In other words: A glyph atlas is entirely capable of drawing almost all of unicode! Now the nice thing about using DirectWrite for entire runs of glyphs (and not just single glyphs) though is that we know we can trust it to perform entirely correctly no matter what we call it with. Fixing our unicode support in the buffer and non-DirectWrite related rendering code is far more trivial than actually figuring out what forms a glyph and could be done "relatively" soon. This would give us full unicode rendering support, even if the width buffer rows don't match the glyph count (for instance hebrew would look correctly, but you can only have let's say 20 glyphs on an 80-cell wide buffer row). A glyph atlas forces us to solve that prematurely and entirely. The list of fundamentally unsolved glyph atlas issues that Alacritty has for instance shouldn't be taken lightly. Many of those issues, again fundamentally, don't exist if you use DirectWrite for entire glyph runs. Certainly one of the many reasons it was called as hard as a dissertation before. Skia's implementation certainly is... That said I'm convinced we should make the glyph atlas renderer separate from the current DxRenderer. While it slightly increases the maintenance burden, both approaches are fundamentally different. Additionally there are some concerns which I'll be mentioning later. --- > With all the above being said, it doesn’t hurt anyone if we or the enthusiasts from the gaming industry take a shot at this specific project. Yep! And I'm entirely on it! It did hurt though, to be an actual human with feelings and stuff, who might get offended if people are rude. 😐 Sarcasm aside: _It is on us_, for not taking the technical advice at face value, no matter the delivery! This one of the reasons we've since reopened the gates for @cmuratori et. al. again, after some time of self-reflection.
Author
Owner

@skyline75489 commented on GitHub (Jun 20, 2021):

Thanks @lhecker for the explanation. I learned a lot and I guess I still have a lot to learn.

@skyline75489 commented on GitHub (Jun 20, 2021): Thanks @lhecker for the explanation. I learned a lot and I guess I still have a lot to learn.
Author
Owner

@DHowett commented on GitHub (Jun 21, 2021):

I was clearly mistaken as to how hard this work would be. I'm glad, and I appreciate being corrected.

Terminal cannot turn away valuable performance work simply on ideological grounds.

Anyway-
I want to establish some ground rules:

  • This renderer should be behind a til::feature (see src/features.xml); you can decide whether it is compiled-in or compiled-out by default. These are not toggleable at runtime, but it will give us the ability to make sure the code doesn't go out in Stable or even Preview until it's ready for people to turn it on.
    • (I want to use til::feature for more "out in the open" development, rather than having long-running feature branches)
  • We need to determine how to expose this switch to the user, and the cost of parallel development on both renderers.
  • Before we begin in earnest bringing an atlas renderer into the codebase, I'd like to see some progress on reducing the renderer's dependency on the global console lock to be as small as possible. That will help even the venerable GDI renderer.

Fair?

@DHowett commented on GitHub (Jun 21, 2021): I was clearly mistaken as to how hard this work would be. I'm glad, and I appreciate being corrected. Terminal cannot turn away valuable performance work simply on ideological grounds. Anyway- I want to establish some ground rules: * This renderer should be behind a `til::feature` (see src/features.xml); you can decide whether it is compiled-in or compiled-out by default. These are not toggleable at runtime, but it will give us the ability to make sure the code doesn't go out in Stable or even Preview until it's ready for people to turn it on. * (I want to use til::feature for more "out in the open" development, rather than having long-running feature branches) * We need to determine how to expose this switch to the user, and the cost of parallel development on both renderers. * Before we begin in earnest bringing an atlas renderer into the codebase, I'd like to see some progress on reducing the renderer's dependency on the global console lock to be as small as possible. That will help even the venerable GDI renderer. Fair?
Author
Owner

@Tyriar commented on GitHub (Jul 4, 2021):

If you want a reference for this the webgl renderer in xterm.js uses a texture atlas as well. Some thoughts from implementing this:

  • We only use a single 1024x1024 texture currently as it didn't seem worth it to manage multiple based on real world usage. I was brand new to webgl writing this but would be much more comfortable with this now, it would help high-dpi displays the most
  • When the atlas is filled we just clear it and start over instead of trying to evict old glyphs compacting
  • To keep the texture a little more compact we trim white space around the glyphs before we put it into the atlas.
  • On startup we warm up the cache by writing a subset of ascii in the default color 094bcbd81d/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts (L104-L114)
  • Before a render happens we prep the texture by rendering all required glyphs
  • We use string as a key to store combining characters, this is relatively fast in JS 094bcbd81d/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts (L50)
  • Here's our glyph glsl shaders if that's helpful, they're very simple
@Tyriar commented on GitHub (Jul 4, 2021): If you want a reference for this the [webgl renderer in xterm.js](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-webgl) uses a texture atlas as well. Some thoughts from implementing this: - We only use a single 1024x1024 texture currently as it didn't seem worth it to manage multiple based on real world usage. I was brand new to webgl writing this but would be much more comfortable with this now, it would help high-dpi displays the most - When the atlas is filled we just clear it and start over instead of trying to evict old glyphs compacting - To keep the texture a little more compact we trim white space around the glyphs before we put it into the atlas. - On startup we warm up the cache by writing a subset of ascii in the default color https://github.com/xtermjs/xterm.js/blob/094bcbd81d1f080d204331088aa99f4d7173d56c/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts#L104-L114 - Before a render happens we prep the texture by rendering all required glyphs - We use `string` as a key to store combining characters, this is relatively fast in JS https://github.com/xtermjs/xterm.js/blob/094bcbd81d1f080d204331088aa99f4d7173d56c/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts#L50 - [Here's our glyph glsl shaders](https://github.com/xtermjs/xterm.js/blob/094bcbd81d1f080d204331088aa99f4d7173d56c/addons/xterm-addon-webgl/src/GlyphRenderer.ts#L40-L70) if that's helpful, they're very simple
Author
Owner

@lhecker commented on GitHub (Jul 4, 2021):

@Tyriar Thank you for your helpful links. I‘ll try to make the most use out of those. 🙂

I‘ve already finished integrating a fully functional ASCII renderer with glyph atlas backing in this project a while ago. I‘ll probably publish a branch/PR once I‘ve integrated some basic Unicode support.

In general there’s a lot more to do here than just integrating a glyph cache though unfortunately, as there was always a need to rewrite large parts of our render and buffer pipeline to make it faster. For instance it’s not possible at the moment to create a fast snapshot of the viewport from the console buffer to implement double buffering.
Navigating the large, sometimes "convoluted", code base and unraveling everything to create something new that’s entirely compatible with the old is very hard for me and takes a lot of time.
As such I‘m sorry for the delay so far and the delays that are about to come. I‘m certain however that I‘ll be able to provide the first of these much asked for improvements in the not too far future.

@lhecker commented on GitHub (Jul 4, 2021): @Tyriar Thank you for your helpful links. I‘ll try to make the most use out of those. 🙂 I‘ve already finished integrating a fully functional ASCII renderer with glyph atlas backing in this project a while ago. I‘ll probably publish a branch/PR once I‘ve integrated some basic Unicode support. In general there’s a lot more to do here than just integrating a glyph cache though unfortunately, as there was always a need to rewrite large parts of our render and buffer pipeline to make it faster. For instance it’s not possible at the moment to create a fast snapshot of the viewport from the console buffer to implement double buffering. Navigating the large, sometimes "convoluted", code base and unraveling everything to create something new that’s entirely compatible with the old is very hard for me and takes a lot of time. As such I‘m sorry for the delay so far and the delays that are about to come. I‘m certain however that I‘ll be able to provide the first of these much asked for improvements in the not too far future.
Author
Owner

@peter-bertok commented on GitHub (Jul 5, 2021):

One comment I've seen in several forums, and the very first thing the popped into my head is: Why is rendering a bottleneck in the first place? Why is thousands of frames per second a feature, if even gaming displays typically reach only 144Hz?

Simply "render" the incoming conio or ConPTY stream to an array of chars and their associated colours, no "pixel graphics" at all. Meanwhile, on another thread, render the pixel graphics to the GPU as fast as possible with double buffering while waiting for vsync. Pause the pixel rendering loop if the text buffer has not changed.

So if the screen is 144 Hz, the pixel renderer will never run faster than 144 Hz.

If the conio input is overwriting the screen with text at 1 GB/s, then the pixel renderer will never hold that up.

If there's no activity, no cycles are wasted rendering the same text to pixels over and over.

Am I missing anything? This seems like an absolutely trivial optimization that exploits the essential nature of terminals: Typically static, but sometimes too active for human eyes to see, or monitors to physically display. They're not a 3D FPS, where the common case is continuous motion at a more-or-less-constant speed. Terminals have tree common states: a blur of activity, static, or updating one character-at-a-time at human typing speeds. Exploit that.

@peter-bertok commented on GitHub (Jul 5, 2021): One comment I've seen in several forums, and the _very first thing_ the popped into my head is: Why is rendering a bottleneck in the first place? Why is thousands of frames per second a feature, if even gaming displays typically reach only 144Hz? Simply "render" the incoming conio or ConPTY stream to an array of chars and their associated colours, no "pixel graphics" at all. Meanwhile, on another thread, render the pixel graphics to the GPU as fast as possible with double buffering while *waiting* for vsync. Pause the pixel rendering loop if the text buffer has not changed. So if the screen is 144 Hz, the pixel renderer will never run faster than 144 Hz. If the conio input is overwriting the screen with text at 1 GB/s, then the pixel renderer will never hold that up. If there's no activity, no cycles are wasted rendering the same text to pixels over and over. Am I missing anything? This seems like an absolutely trivial optimization that exploits the essential nature of terminals: Typically static, but sometimes *too active* for human eyes to see, or monitors to physically display. They're not a 3D FPS, where the common case is continuous motion at a more-or-less-constant speed. Terminals have tree common states: a blur of activity, static, or updating one character-at-a-time at human typing speeds. Exploit that.
Author
Owner

@lhecker commented on GitHub (Jul 5, 2021):

@peter-bertok Thank you for your suggestions!

First regarding why rendering is a bottleneck: For historical reasons.
Rendering is a bottleneck at the moment, because the renderer currently acquires an exclusive lock on the console buffer. While the buffer is locked, the VT parser can't write into the buffer. And since we use synchronous pipes for input/output, a blocked VT parser in Windows Terminal implicitly also blocks conhost/OpenConsole from progressing.
We're already planning to introduce a mechanic to quickly capture a snapshot of the current viewport along with a glyph atlas renderer, which will drastically reduce the lock time to rival the performance of your suggestion.

Your suggestion to throttle the renderer, when large amounts of text are printed out, is a good one. Personally I'd prefer to draw exactly at display refresh rate at all times though (unless nothing changes on the screen). As the renderer that's being discussed here can draw at thousands of FPS, I don't see yet how going below the display refresh rate will significantly improve performance. But I'll make sure to bring this idea up in the future, and as usual benchmark every change I make.

@lhecker commented on GitHub (Jul 5, 2021): @peter-bertok Thank you for your suggestions! First regarding why rendering is a bottleneck: For historical reasons. Rendering is a bottleneck at the moment, because the renderer currently acquires an exclusive lock on the console buffer. While the buffer is locked, the VT parser can't write into the buffer. And since we use synchronous pipes for input/output, a blocked VT parser in Windows Terminal implicitly also blocks conhost/OpenConsole from progressing. We're already planning to introduce a mechanic to quickly capture a snapshot of the current viewport along with a glyph atlas renderer, which will drastically reduce the lock time to rival the performance of your suggestion. Your suggestion to throttle the renderer, when large amounts of text are printed out, is a good one. Personally I'd prefer to draw exactly at display refresh rate at all times though (unless nothing changes on the screen). As the renderer that's being discussed here can draw at thousands of FPS, I don't see yet how going below the display refresh rate will significantly improve performance. But I'll make sure to bring this idea up in the future, and as usual benchmark every change I make.
Author
Owner

@peter-bertok commented on GitHub (Jul 6, 2021):

@lhecker

I didn't mean throttling the renderer below the display refresh, I was simply saying that if it has literally nothing to do, it can be paused. This is dissimilar to a typical game engine, which always refreshes the screen, albeit at potentially less than 100% CPU/GPU utilization if vsync is enabled.

There are some subtleties with this kind of approach. E.g.: Copying the text buffer and then waiting for vsync will increase latency unnecessarily. The optimal solution is to make the copy of the text buffer immediately before rendering of the next frame commences. This too is somewhat more complex if using double or triple buffering. Imagine a scenario where 100 MB of text is being piped in a full speed. A very fast pixel renderer might quickly render 3 frames ahead, mostly in the first 10 MB of the text stream. At that point the swap chain is 'full', and the pixel rendering will be held up waiting for vsync for ~50ms. During this period, the 100 MB of text can easily finish streaming, so that the next rendered set of pixels might be from the end of it. This could cause stuttering where you see the text from the first 1%, then 2%, then 3%.. then 50%.. and suddenly 100% of the way through the stream.

So there's some real legwork to be done here to optimize the timings to minimize latency and stuttering...

Please have a look at http://danluu.com/term-latency/ for some numbers and background information.

@peter-bertok commented on GitHub (Jul 6, 2021): @lhecker I didn't mean throttling the renderer below the display refresh, I was simply saying that if it has literally nothing to do, it can be paused. This is dissimilar to a typical game engine, which always refreshes the screen, albeit at potentially less than 100% CPU/GPU utilization if vsync is enabled. There are some subtleties with this kind of approach. E.g.: Copying the text buffer *and then* waiting for vsync will increase latency unnecessarily. The optimal solution is to make the copy of the text buffer immediately before rendering of the next frame commences. This too is somewhat more complex if using double or triple buffering. Imagine a scenario where 100 MB of text is being piped in a full speed. A very fast pixel renderer might quickly render 3 frames ahead, mostly in the first 10 MB of the text stream. At that point the swap chain is 'full', and the pixel rendering will be held up waiting for vsync for ~50ms. During this period, the 100 MB of text can easily finish streaming, so that the next rendered set of pixels might be from the end of it. This could cause stuttering where you see the text from the first 1%, then 2%, then 3%.. then 50%.. and suddenly 100% of the way through the stream. So there's some real legwork to be done here to optimize the timings to minimize latency and stuttering... Please have a look at http://danluu.com/term-latency/ for some numbers and background information.
Author
Owner

@jerch commented on GitHub (Jul 6, 2021):

Also was wondering, why rendering is a bottleneck in a piece of software, that could run fully offscreen, well a buffer lock waiting for screen output blocking through all the layers explains that.

I also think that a dedicated render buffer filled from the terminal buffer right before rendering is the easiest way to somewhat decouple that. With this the locking time can be reduced to the copy step, which is rather small. In theory a lock-free implementation would be possible (even without the additional copy step), but is likely to create nasty screen artifacts during mass actions (like clear screen or resizing), thus is not really wanted.

On a sidenote - imho the real throughput barrier is the VT parsing / state handling itself, once you have ruled out the rendering entanglements. Terminal data is still serial data, where a single byte can alter the whole terminal processing of follow-up data. This forces a proper emulator to do "band global" state handling with strict serial processing, which gives only limited abilities for faster code paths (like not doing all char-by-char, but rather in state sub-chunks). I really doubt that this can be made faster than 400MB/s with current CPU models (The magic number is pulled from my own reduced state experiments, most TEs as of now are in the 30 - 100 MB/s range with full state handling, depending on the data presented).

@jerch commented on GitHub (Jul 6, 2021): Also was wondering, why rendering is a bottleneck in a piece of software, that could run fully offscreen, well a buffer lock waiting for screen output blocking through all the layers explains that. I also think that a dedicated render buffer filled from the terminal buffer right before rendering is the easiest way to somewhat decouple that. With this the locking time can be reduced to the copy step, which is rather small. In theory a lock-free implementation would be possible (even without the additional copy step), but is likely to create nasty screen artifacts during mass actions (like clear screen or resizing), thus is not really wanted. On a sidenote - imho the real throughput barrier is the VT parsing / state handling itself, once you have ruled out the rendering entanglements. Terminal data is still serial data, where a single byte can alter the whole terminal processing of follow-up data. This forces a proper emulator to do "band global" state handling with strict serial processing, which gives only limited abilities for faster code paths (like not doing all char-by-char, but rather in state sub-chunks). I really doubt that this can be made faster than 400MB/s with current CPU models (The magic number is pulled from my own reduced state experiments, most TEs as of now are in the 30 - 100 MB/s range with full state handling, depending on the data presented).
Author
Owner

@hfhchan commented on GitHub (Aug 27, 2021):

Addedum: I think the people implementing know the following points already, and there are valid reasons for not supporting the following scenarios in a quick-path implementation. But I have included them here it because I found some of the points mentioned in previous comments being insensitive to requirements for East Asian scripts. East Asian scripts are typically not even considered complex.

This is done by calling the GetTextComplexity API) because of the existence of “locale based” letter forms(locl), which depends on the font being used and the current locale. This feature is used in languages like Turkish & Polish & etc. Some might think “this is just nonsense. No one really needs this”.

locl support is required for correctly rendering CJK characters when using pan-CJK fonts. Windows does not ship with any fonts that support proper glyphs for Chinese Traditional (Hong Kong), only for Chinese Traditional (Taiwan). The currently most popular way to get fonts that adhere to the Hong Kong government reference orthography is by installing Source Han Sans, which relies on the locl tag to deliver the correct glyphs.

But to be fair monospace-only support simplifies most things. For instance our console buffer currently is N characters wide, and should be N glyphs wide (and not just N graphemes either!). Solving this issue seems awfully similar to solving the layout issue for a glyph atlas. If we know what forms entire glyphs I believe there aren't many issues anymore you could possibly have.

CJK characters are supposed to render as full-width characters, i.e. take up double the space used by a single ASCII character. You should never assume that N characters wide will be N glyphs wide. For certain Latin based scripts such as Vietnamese and Chinese pinyin you need to support combining characters which have no pre-composed character equivalents.

Support for IVS characters with CJK characters are also necessary for Chinese locales apart from the Japanese locale. The Macao Special Administrative Region has already registered an IVD collection including glyphs which need to be supported for Chinese (Traditional) use for Macao users. Other regions have IVD collections in the works.

@hfhchan commented on GitHub (Aug 27, 2021): Addedum: I think the people implementing know the following points already, and there are valid reasons for not supporting the following scenarios in a quick-path implementation. But I have included them here it because I found some of the points mentioned in previous comments being insensitive to requirements for East Asian scripts. East Asian scripts are typically not even considered complex. > This is done by calling the GetTextComplexity API) because of the existence of “locale based” letter forms(locl), which depends on the font being used and the current locale. This feature is used in languages like Turkish & Polish & etc. Some might think “this is just nonsense. No one really needs this”. `locl` support is required for correctly rendering CJK characters when using pan-CJK fonts. Windows does not ship with any fonts that support proper glyphs for Chinese Traditional (Hong Kong), only for Chinese Traditional (Taiwan). The currently most popular way to get fonts that adhere to the Hong Kong government reference orthography is by installing Source Han Sans, which relies on the `locl` tag to deliver the correct glyphs. > But to be fair monospace-only support simplifies most things. For instance our console buffer currently is N characters wide, and should be N glyphs wide (and not just N graphemes either!). Solving this issue seems awfully similar to solving the layout issue for a glyph atlas. If we know what forms entire glyphs I believe there aren't many issues anymore you could possibly have. CJK characters are supposed to render as full-width characters, i.e. take up double the space used by a single ASCII character. You should never assume that N characters wide will be N glyphs wide. For certain Latin based scripts such as Vietnamese and Chinese pinyin you need to support combining characters which have no pre-composed character equivalents. Support for IVS characters with CJK characters are also necessary for Chinese locales apart from the Japanese locale. The Macao Special Administrative Region has already registered an IVD collection including glyphs which need to be supported for Chinese (Traditional) use for Macao users. Other regions have IVD collections in the works.
Author
Owner

@ndwork commented on GitHub (Nov 7, 2021):

Any progress here? It’s been four months since the issue was opened and two since the last meaningful comment.

@lhecker

@ndwork commented on GitHub (Nov 7, 2021): Any progress here? It’s been four months since the issue was opened and two since the last meaningful comment. @lhecker
Author
Owner

@lhecker commented on GitHub (Nov 7, 2021):

@ndwork It's something that already exists and is being tested internally... 🙂
image

As I've mentioned in the other issue, I'm aiming for the 1.13 Preview release. I hope you can understand that we had to work on our pre-existing roadmap first over the last few months. But as of about 2 weeks ago I've been working on this most of the time. Once something that's stable, tested and usable has landed in Windows Terminal I'll make sure to let everyone know in this issue.

@lhecker commented on GitHub (Nov 7, 2021): @ndwork It's something that already exists and is being tested internally... 🙂 ![image](https://user-images.githubusercontent.com/2256941/140654394-8bf6da14-0598-45d4-a545-36432e84104e.png) As I've mentioned in the other issue, I'm aiming for the 1.13 Preview release. I hope you can understand that we had to work on our pre-existing roadmap first over the last few months. But as of about 2 weeks ago I've been working on this most of the time. Once something that's stable, tested and usable has landed in Windows Terminal I'll make sure to let everyone know in this issue.
Author
Owner

@rbeesley commented on GitHub (Jan 4, 2022):

I think I'm seeing this problem. I checked and I only have 1.12 Preview, so I can't see if this fixes it for me.

I was running this crt.hlsl experimental pixelShader, and I was looking for anything else I might have missed in the Ansi-Color.cmd tool (hopefully part of a future release, but the attached PR would let you replicate this), and running the plaid.def through this tool, I was seeing a 10% CPU increase. I thought maybe the shader was computationally expensive for some reason, so I also tried grid.hlsl which does nothing more than to render a grid of squares across the terminal, it too showed the same CPU overhead. None of the other definition files were causing this issue, but it is notable that plaid.def uses the block element █ (U+2588), and the shade elements ░ (U+2591), ▒ (U+2592), and ▓ (U+2593), and shows a tight grid of 1024 of these characters (4 each for a 16x16 combination of colors).

So I think what is happening is that rendering these 4 glyphs is very expensive for Terminal and it is costing a lot to render this for each frame of the shader? Is this something I should just wait until 1.13 Preview and file a performance bug if I'm still seeing a CPU hit? It seems like #10362 is the same problem I ran into, but maybe adding the shader just amplifies it the problem for me significantly?

@rbeesley commented on GitHub (Jan 4, 2022): I think I'm seeing this problem. I checked and I only have 1.12 Preview, so I can't see if this fixes it for me. I was running this [crt.hlsl](https://github.com/rbeesley/windows-terminal-shaders/tree/crt.hlsl-with-retro.hlsl-adjustments) experimental pixelShader, and I was looking for anything else I might have missed in the [Ansi-Color.cmd](https://github.com/microsoft/terminal/issues/6470) tool (hopefully part of a future release, but the attached PR would let you replicate this), and running the [plaid.def](https://github.com/microsoft/terminal/pull/11932/files#diff-cbb640b3f1b513a84ec55a7003d404ff9199f1de74a182f51f4d909b772d39cc) through this tool, I was seeing a 10% CPU increase. I thought maybe the shader was computationally expensive for some reason, so I also tried [grid.hlsl](https://github.com/rbeesley/windows-terminal-shaders/blob/crt.hlsl-with-retro.hlsl-adjustments/grid.hlsl) which does nothing more than to render a grid of squares across the terminal, it too showed the same CPU overhead. None of the other definition files were causing this issue, but it is notable that plaid.def uses the block element █ (U+2588), and the shade elements ░ (U+2591), ▒ (U+2592), and ▓ (U+2593), and shows a tight grid of 1024 of these characters (4 each for a 16x16 combination of colors). So I think what is happening is that rendering these 4 glyphs is very expensive for Terminal and it is costing a lot to render this for each frame of the shader? Is this something I should just wait until 1.13 Preview and file a performance bug if I'm still seeing a CPU hit? It seems like #10362 is the same problem I ran into, but maybe adding the shader just amplifies it the problem for me significantly?
Author
Owner

@zadjii-msft commented on GitHub (Jan 4, 2022):

@rbeesley you may be more specifically hitting #6974

@zadjii-msft commented on GitHub (Jan 4, 2022): @rbeesley you may be more _specifically_ hitting #6974
Author
Owner

@rbeesley commented on GitHub (Jan 4, 2022):

@zadjii-msft, reading through that bug report, it does seem like it fits. I'll put more information there.

@rbeesley commented on GitHub (Jan 4, 2022): @zadjii-msft, reading through that bug report, it does seem like it fits. I'll put more information there.
Author
Owner

@lhecker commented on GitHub (Feb 3, 2022):

Windows Terminal Preview v1.13.10336.0 was released today, which features a new rendering engine. While it doesn't solve all of the performance issues reported here yet, it's a significant improvement nonetheless.

You can enable it this way:

  • Open settings
  • Select any profile (including "Defaults")
  • Select "Advanced" at the bottom
  • Select "Enable experimental text rendering engine"

image

The performance should be about the same in the worst case (regular black/white text), but significantly better for highly colored text (text that exceeds 20 distinct colors on a screen). Additionally this engine won't be limited to 60 FPS anymore.
Additionally I'm currently writing a blog post detailing why this issue occurs in Direct2D.

If you find any issues or got any feedback for this new text renderer, please let us know in #9999. 🙂

@lhecker commented on GitHub (Feb 3, 2022): [Windows Terminal Preview v1.13.10336.0](https://github.com/microsoft/terminal/releases/tag/v1.13.10336.0) was released today, which features a new rendering engine. While it doesn't solve all of the performance issues reported here yet, it's a significant improvement nonetheless. You can enable it this way: * Open settings * Select any profile (including "Defaults") * Select "Advanced" at the bottom * Select "Enable experimental text rendering engine" ![image](https://user-images.githubusercontent.com/2256941/152410444-2f831c8a-c777-4c93-a04e-bc5da84cf253.png) The performance should be about the same in the worst case (regular black/white text), but _significantly_ better for highly colored text (text that exceeds 20 distinct colors on a screen). Additionally this engine won't be limited to 60 FPS anymore. Additionally I'm currently writing a blog post detailing why this issue occurs in Direct2D. If you find any issues or got any feedback for this new text renderer, please let us know in #9999. 🙂
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14271