Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e8521f6

Browse files
author
Jonah Williams
authored
[Impeller] fall back to path rendering on thick paths. (#54822)
For very thin stroked text we switch to skia font rasterization for higher fidelity. However and very large stroke widths, the fidelity loss doesn't matter and may be much slower due to software rasterization. As several users have noticed, there is a maximum size limit of skia stroked text that we hit as well. This only seems to happen on large stroke widths. Fixes flutter/flutter#153784
1 parent 7e73a88 commit e8521f6

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

third_party/txt/src/skia/paragraph_skia.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "fml/logging.h"
2323
#include "impeller/typographer/backends/skia/text_frame_skia.h"
2424
#include "include/core/SkMatrix.h"
25+
#include "third_party/skia/src/core/SkTextBlobPriv.h" // nogncheck
2526

2627
namespace txt {
2728

@@ -85,6 +86,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter {
8586

8687
#ifdef IMPELLER_SUPPORTS_RENDERING
8788
if (impeller_enabled_) {
89+
SkTextBlobRunIterator run(blob.get());
8890
if (ShouldRenderAsPath(dl_paints_[paint_id])) {
8991
auto path = skia::textlayout::Paragraph::GetPath(blob.get());
9092
// If there is no path, this is an emoji and should be drawn as is,
@@ -184,7 +186,14 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter {
184186
// running on Impeller for correctness. These filters rely on having the
185187
// glyph coverage, whereas regular text is drawn as rectangular texture
186188
// samples.
187-
return (paint.getColorSource() && !paint.getColorSource()->asColor());
189+
// If the text is stroked and the stroke width is large enough, use path
190+
// rendering anyway, as the fidelity problems won't be as noticable and
191+
// rendering will be faster as it avoids software rasterization. A stroke
192+
// width of four was chosen by eyeballing the point at which the path
193+
// text looks good enough, with some room for error.
194+
return (paint.getColorSource() && !paint.getColorSource()->asColor()) ||
195+
(paint.getDrawStyle() == DlDrawStyle::kStroke &&
196+
paint.getStrokeWidth() > 4);
188197
}
189198

190199
DlPaint toDlPaint(const DecorationStyle& decor_style,

third_party/txt/tests/paragraph_unittests.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,23 @@ TEST_F(PainterTest, DrawStrokedTextImpeller) {
259259
EXPECT_EQ(recorder.pathCount(), 0);
260260
}
261261

262+
TEST_F(PainterTest, DrawStrokedTextWithLargeWidthImpeller) {
263+
PretendImpellerIsEnabled(true);
264+
265+
auto style = makeStyle();
266+
DlPaint foreground;
267+
foreground.setDrawStyle(DlDrawStyle::kStroke);
268+
foreground.setStrokeWidth(10);
269+
style.foreground = foreground;
270+
271+
auto recorder = DlOpRecorder();
272+
draw(style)->Dispatch(recorder);
273+
274+
EXPECT_EQ(recorder.textFrameCount(), 0);
275+
EXPECT_EQ(recorder.blobCount(), 0);
276+
EXPECT_EQ(recorder.pathCount(), 1);
277+
}
278+
262279
TEST_F(PainterTest, DrawTextWithGradientImpeller) {
263280
PretendImpellerIsEnabled(true);
264281

0 commit comments

Comments
 (0)