DirectWrite Performance

Introduction

DirectWrite is a high‑performance, native text layout and rendering API designed for Windows applications. This guide covers best‑practice techniques to maximize rendering speed, minimize memory usage, and ensure smooth multithreaded operation.

Key Performance Tips

1. Cache Text Formats

Creating IDWriteTextFormat objects is expensive. Reuse them whenever possible.

static Microsoft::WRL::ComPtr<IDWriteTextFormat> g_pTextFormat;

HRESULT InitTextFormat(IDWriteFactory* pFactory)
{
    return pFactory->CreateTextFormat(
        L"Segoe UI", nullptr, DWRITE_FONT_WEIGHT_NORMAL,
        DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL,
        12.0f, L"", &g_pTextFormat);
}

2. Use Text Layout Caching

Cache IDWriteTextLayout for static strings.

static std::unordered_map<std::wstring, Microsoft::WRL::ComPtr<IDWriteTextLayout>> g_layoutCache;

Microsoft::WRL::ComPtr<IDWriteTextLayout> GetCachedLayout(
    IDWriteFactory* factory, const std::wstring& text)
{
    auto it = g_layoutCache.find(text);
    if (it != g_layoutCache.end())
        return it->second;

    Microsoft::WRL::ComPtr<IDWriteTextFormat> format;
    InitTextFormat(factory); // assume success
    Microsoft::WRL::ComPtr<IDWriteTextLayout> layout;
    factory->CreateTextLayout(text.c_str(), (UINT32)text.size(),
                              g_pTextFormat.Get(), 0.0f, 0.0f, &layout);
    g_layoutCache.emplace(text, layout);
    return layout;
}

Memory Management

ComponentGuideline
Font Face ObjectsReuse IDWriteFontFace across layouts.
Glyph BuffersAllocate once per frame; reuse for multiple draws.
Custom RendererPrefer IDWritePixelSnapping if hardware acceleration is unavailable.

Multithreading Considerations

Sample Rendering Loop

void Render(ID2D1RenderTarget* rt, IDWriteFactory* dwFactory, const std::wstring& text)
{
    auto layout = GetCachedLayout(dwFactory, text);
    rt->BeginDraw();
    rt->DrawTextLayout(D2D1_POINT_2F{10,10}, layout.Get(),
                       D2D1::ColorF(D2D1::ColorF::White));
    rt->EndDraw();
}

Further Reading

DirectWrite OverviewLayout FundamentalsHeader Reference