LibWeb: Save unscaled glyph run in PaintTextShadow command

Implements the same optimization we already have for DrawGlyphRun by
saving unscaled glyph run and scale factor in a painting command, which
allows to avoid copying of glyphs vector to apply scaling during
recording.
This commit is contained in:
Aliaksandr Kalenik 2024-06-28 16:25:06 +02:00 committed by Andreas Kling
parent 6369737676
commit ebc282207b
Notes: sideshowbarker 2024-07-16 16:23:32 +09:00
6 changed files with 17 additions and 19 deletions

View file

@ -142,7 +142,8 @@ struct PaintTextShadow {
int blur_radius;
Gfx::IntRect shadow_bounding_rect;
Gfx::IntRect text_rect;
Vector<Gfx::DrawGlyphOrEmoji> glyph_run;
NonnullRefPtr<Gfx::GlyphRun> glyph_run;
double glyph_run_scale { 1 };
Color color;
int fragment_baseline;
Gfx::IntPoint draw_location;

View file

@ -272,12 +272,18 @@ CommandResult DisplayListPlayerCPU::paint_text_shadow(PaintTextShadow const& com
// FIXME: "Spread" the shadow somehow.
Gfx::IntPoint const baseline_start(command.text_rect.x(), command.text_rect.y() + command.fragment_baseline);
shadow_painter.translate(baseline_start);
for (auto const& glyph_or_emoji : command.glyph_run) {
auto const& glyphs = command.glyph_run->glyphs();
for (auto const& glyph_or_emoji : glyphs) {
auto transformed_glyph = glyph_or_emoji;
transformed_glyph.visit([&](auto& glyph) {
glyph.position = glyph.position.scaled(command.glyph_run_scale);
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(command.glyph_run_scale));
});
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
auto const& glyph = glyph_or_emoji.get<Gfx::DrawGlyph>();
auto& glyph = transformed_glyph.get<Gfx::DrawGlyph>();
shadow_painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, command.color);
} else {
auto const& emoji = glyph_or_emoji.get<Gfx::DrawEmoji>();
auto& emoji = transformed_glyph.get<Gfx::DrawEmoji>();
shadow_painter.draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
}
}

View file

@ -192,7 +192,7 @@ CommandResult DisplayListPlayerGPU::paint_text_shadow(PaintTextShadow const& com
Gfx::FloatRect const shadow_location { command.draw_location, command.shadow_bounding_rect.size() };
Gfx::IntPoint const baseline_start(command.text_rect.x(), command.text_rect.y() + command.fragment_baseline);
text_shadow_painter->translate(baseline_start.to_type<float>());
text_shadow_painter->draw_glyph_run(command.glyph_run, command.color);
text_shadow_painter->draw_glyph_run(command.glyph_run->glyphs(), command.color);
if (command.blur_radius == 0) {
painter().blit_canvas(shadow_location, *text_shadow_canvas);
return CommandResult::Continue;

View file

@ -344,13 +344,14 @@ void DisplayListRecorder::paint_inner_box_shadow_params(PaintBoxShadowParams par
append(PaintInnerBoxShadow { .box_shadow_params = params });
}
void DisplayListRecorder::paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Span<Gfx::DrawGlyphOrEmoji const> glyph_run, Color color, int fragment_baseline, Gfx::IntPoint draw_location)
void DisplayListRecorder::paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Gfx::GlyphRun const& glyph_run, double glyph_run_scale, Color color, int fragment_baseline, Gfx::IntPoint draw_location)
{
append(PaintTextShadow {
.blur_radius = blur_radius,
.shadow_bounding_rect = bounding_rect,
.text_rect = text_rect,
.glyph_run = Vector<Gfx::DrawGlyphOrEmoji> { glyph_run },
.glyph_run = glyph_run,
.glyph_run_scale = glyph_run_scale,
.color = color,
.fragment_baseline = fragment_baseline,
.draw_location = state().translation.map(draw_location) });

View file

@ -127,7 +127,7 @@ public:
void paint_outer_box_shadow_params(PaintBoxShadowParams params);
void paint_inner_box_shadow_params(PaintBoxShadowParams params);
void paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Span<Gfx::DrawGlyphOrEmoji const> glyph_run, Color color, int fragment_baseline, Gfx::IntPoint draw_location);
void paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Gfx::GlyphRun const&, double glyph_run_scale, Color color, int fragment_baseline, Gfx::IntPoint draw_location);
void fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius, Vector<Gfx::Path> const& clip_paths = {});
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius, Vector<Gfx::Path> const& clip_paths = {});

View file

@ -587,16 +587,6 @@ void paint_text_shadow(PaintContext& context, PaintableFragment const& fragment,
auto draw_rect = context.enclosing_device_rect(fragment.absolute_rect()).to_type<int>();
auto fragment_baseline = context.rounded_device_pixels(fragment.baseline()).value();
Vector<Gfx::DrawGlyphOrEmoji> scaled_glyph_run;
scaled_glyph_run.ensure_capacity(fragment.glyph_run().glyphs().size());
for (auto glyph : fragment.glyph_run().glyphs()) {
glyph.visit([&](auto& glyph) {
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(context.device_pixels_per_css_pixel()));
glyph.position = glyph.position.scaled(context.device_pixels_per_css_pixel());
});
scaled_glyph_run.append(move(glyph));
}
// Note: Box-shadow layers are ordered front-to-back, so we paint them in reverse
for (auto& layer : shadow_layers.in_reverse()) {
int offset_x = context.rounded_device_pixels(layer.offset_x).value();
@ -620,7 +610,7 @@ void paint_text_shadow(PaintContext& context, PaintableFragment const& fragment,
draw_rect.y() + offset_y - margin
};
context.display_list_recorder().paint_text_shadow(blur_radius, bounding_rect, text_rect, scaled_glyph_run, layer.color, fragment_baseline, draw_location);
context.display_list_recorder().paint_text_shadow(blur_radius, bounding_rect, text_rect, fragment.glyph_run(), context.device_pixels_per_css_pixel(), layer.color, fragment_baseline, draw_location);
}
}