DirectWrite infinitely long strings performance

123 Views Asked by At

In the DirectWrite guides and examples I only found solutions for creating layout and rendering relatively small strings, i.e. with not a big number of characters.

Currently I understand that the method with the best performance is to create and cache IDWriteTextLayout and draw it using ID2D1DeviceContext::DrawTextLayout. Layout is needed to be recreated only when display text is need to be updated: when changing font size, family, text string itself, etc.

This method works fine for less then about 50 000 characters string, but starting from here, fps significantly drops. But I want more than 50K chars, I want 50M chars, for example. At my pc ID2D1DeviceContext::DrawTextLayout takes about 23ms to draw 55 000 character string, which means that the result fps (there are another ui elements) will be already less then 1000/23 = 43 fps.

How, for example in classic notepad.exe there is no delay when I input some character in 10 000 000 characters text and all is rendering at 60fps? Maybe there I need to separate strings on chunks and draw individual but display as one string? I currently barely can imaging how to deal with ending position of one string and starting of another.

1

There are 1 best solutions below

4
bunglehead On

I don't think layout object was particularly designed for that. I'd think about it as a DrawText() replacement with much fancier configuration options. If you want a text editor level of complexity, you'll have to implement layout logic yourself. You would use lower level shaping functionality for that (GetGlyphs/GetGlyphPlacements), applying line breaking, bidi logic, etc. Then you can optimizing and render only visible parts, without updating everything.

Notepad example while valid is also much simpler, it only supports a single font and no formatting options. Still I'm sure it's not that naive and doesn't e.g. reshape when it does not have to.