Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: a21ec7df273fd4e5118dba01cccd5dbeb84d8af4
https://github.com/WebKit/WebKit/commit/a21ec7df273fd4e5118dba01cccd5dbeb84d8af4
Author: Vitor Roriz <[email protected]>
Date: 2026-02-13 (Fri, 13 Feb 2026)
Changed paths:
M Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
M Source/WebCore/platform/graphics/FontCascade.cpp
M Source/WebCore/platform/graphics/FontCascade.h
M Source/WebCore/platform/graphics/FontCascadeFonts.cpp
M Source/WebCore/platform/graphics/FontCascadeFonts.h
M Source/WebCore/platform/graphics/GlyphBuffer.h
M Source/WebCore/platform/graphics/TextMeasurementCache.h
Log Message:
-----------
Introduce caching for shaped text in canvas fillText/strokeText operations
https://bugs.webkit.org/show_bug.cgi?id=307203
rdar://164044082
Reviewed by Simon Fraser.
Currently, canvas text rendering operations like fillText() and strokeText()
repeatedly
shape the same text strings for drawing. This patch introduces a cache for
shaped text
(CachedShapedText) to avoid redundant text shaping. FontCascade::width()
already interfaces
with a cache (GlyphGeometryCache) but only for width calculation. So, even if
we would hit this
cache, we would have to shape at least once for drawing.
Now, we are caching shaping results in the form of GlyphBuffers. While we build
the glyph buffer,
we can directly calculate width from the text engine iterators (WidthIterator /
ComplexTextController),
so both CachedShapedText can store both GlyphBuffer and width values.
Therefore, now, in case of a hit
we don't have to shape at all.
In order to do that we need to make TextMeasurementCache configurable via
template parameters
for cache behavior (sampling intervals, max size, max text length). This allows
different cache
instances to use different policies: ShapedTextCache uses aggressive immediate
caching with
128 character limit, while the existing GlyphGeometryCache maintains
conservative sampling with
64-character limit.
We will just try to hit the cache for the simple path. The simple path is
defined by content
without strong directionality. This is because, for such content, we don't have
to invoke the
BidiResolver (all content is guaranteed to compose a single bidi run) and we
don't have to introduce
directionality into our key. This could be extended in the future.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawTextUnchecked):
* Source/WebCore/platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::layoutText const):
(WebCore::FontCascade::layoutSimpleText const):
(WebCore::FontCascade::layoutComplexText const):
* Source/WebCore/platform/graphics/FontCascade.h:
* Source/WebCore/platform/graphics/FontCascadeFonts.cpp:
(WebCore::FontCascadeFonts::getOrCreateCachedShapedText):
* Source/WebCore/platform/graphics/FontCascadeFonts.h:
(WebCore::FontCascadeFonts::shapedTextCache):
(WebCore::FontCascadeFonts::shapedTextCache const):
* Source/WebCore/platform/graphics/GlyphBuffer.h:
* Source/WebCore/platform/graphics/TextMeasurementCache.h:
(WebCore::TextMeasurementCache::TextMeasurementCache):
(WebCore::TextMeasurementCache::add):
(WebCore::TextMeasurementCache::addSlowCase):
Canonical link: https://commits.webkit.org/307515@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications