Quellcode durchsuchen

LibWeb: Remove glyph run allocation in RecordingPainter::draw_text_run

Instead of allocating a new glyph run solely to shift each glyph by the
painter's offset, this offset could be encoded in a paint command and
applied later during command execution.
Aliaksandr Kalenik vor 1 Jahr
Ursprung
Commit
aeb5a0d9e8

+ 1 - 0
Userland/Libraries/LibWeb/Painting/Command.h

@@ -41,6 +41,7 @@ struct DrawGlyphRun {
     Vector<Gfx::DrawGlyphOrEmoji> glyph_run;
     Color color;
     Gfx::IntRect rect;
+    Gfx::FloatPoint translation;
 
     [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
 

+ 5 - 3
Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp

@@ -24,15 +24,17 @@ CommandExecutorCPU::CommandExecutorCPU(Gfx::Bitmap& bitmap)
         .scaling_mode = {} });
 }
 
-CommandResult CommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
+CommandResult CommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color, Gfx::FloatPoint translation)
 {
     auto& painter = this->painter();
     for (auto& glyph_or_emoji : glyph_run) {
+        auto transformed_glyph = glyph_or_emoji;
+        transformed_glyph.visit([&](auto& glyph) { glyph.position.translate_by(translation); });
         if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
-            auto& glyph = glyph_or_emoji.get<Gfx::DrawGlyph>();
+            auto& glyph = transformed_glyph.get<Gfx::DrawGlyph>();
             painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
         } else {
-            auto& emoji = glyph_or_emoji.get<Gfx::DrawEmoji>();
+            auto& emoji = transformed_glyph.get<Gfx::DrawEmoji>();
             painter.draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
         }
     }

+ 1 - 1
Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h

@@ -13,7 +13,7 @@ namespace Web::Painting {
 
 class CommandExecutorCPU : public CommandExecutor {
 public:
-    CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) override;
+    CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) override;
     CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
     CommandResult fill_rect(Gfx::IntRect const& rect, Color const&) override;
     CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override;

+ 10 - 3
Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp

@@ -31,9 +31,16 @@ CommandExecutorGPU::~CommandExecutorGPU()
     painter().flush(m_target_bitmap);
 }
 
-CommandResult CommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
-{
-    painter().draw_glyph_run(glyph_run, color);
+CommandResult CommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color, Gfx::FloatPoint translation)
+{
+    Vector<Gfx::DrawGlyphOrEmoji> transformed_glyph_run;
+    transformed_glyph_run.ensure_capacity(glyph_run.size());
+    for (auto& glyph : glyph_run) {
+        auto transformed_glyph = glyph;
+        transformed_glyph.visit([&](auto& glyph) { glyph.position.translate_by(translation); });
+        transformed_glyph_run.append(transformed_glyph);
+    }
+    painter().draw_glyph_run(transformed_glyph_run, color);
     return CommandResult::Continue;
 }
 

+ 1 - 1
Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h

@@ -14,7 +14,7 @@ namespace Web::Painting {
 
 class CommandExecutorGPU : public CommandExecutor {
 public:
-    CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) override;
+    CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) override;
     CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
     CommandResult fill_rect(Gfx::IntRect const& rect, Color const&) override;
     CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override;

+ 1 - 1
Userland/Libraries/LibWeb/Painting/CommandList.cpp

@@ -87,7 +87,7 @@ void CommandList::execute(CommandExecutor& executor)
 
         auto result = command.visit(
             [&](DrawGlyphRun const& command) {
-                return executor.draw_glyph_run(command.glyph_run, command.color);
+                return executor.draw_glyph_run(command.glyph_run, command.color, command.translation);
             },
             [&](DrawText const& command) {
                 return executor.draw_text(command.rect, command.raw_text, command.alignment, command.color,

+ 1 - 1
Userland/Libraries/LibWeb/Painting/CommandList.h

@@ -47,7 +47,7 @@ class CommandExecutor {
 public:
     virtual ~CommandExecutor() = default;
 
-    virtual CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) = 0;
+    virtual CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) = 0;
     virtual CommandResult draw_text(Gfx::IntRect const&, String const&, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) = 0;
     virtual CommandResult fill_rect(Gfx::IntRect const&, Color const&) = 0;
     virtual CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) = 0;

+ 2 - 7
Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp

@@ -209,16 +209,11 @@ void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect,
 void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span<Gfx::DrawGlyphOrEmoji const> glyph_run, Color color, Gfx::IntRect const& rect)
 {
     auto transformed_baseline_start = state().translation.map(baseline_start).to_type<float>();
-    Vector<Gfx::DrawGlyphOrEmoji> translated_glyph_run;
-    translated_glyph_run.ensure_capacity(glyph_run.size());
-    for (auto glyph : glyph_run) {
-        glyph.visit([&](auto& glyph) { glyph.position.translate_by(transformed_baseline_start); });
-        translated_glyph_run.append(glyph);
-    }
     append(DrawGlyphRun {
-        .glyph_run = move(translated_glyph_run),
+        .glyph_run = Vector<Gfx::DrawGlyphOrEmoji> { glyph_run },
         .color = color,
         .rect = state().translation.map(rect),
+        .translation = transformed_baseline_start,
     });
 }