jrmuizel / raqote

Rust 2D graphics library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

composite slow?

FloVanGH opened this issue · comments

OrbTk draws slow by dragging a widget. In this case the mouse move will trigger redraw and in this case it is slow. I profiles the application and most time is spent on the composite method of raqote. Have you any idea how it could be improved or any plans?

image

Sorry, I didn't see this earlier. What's the best way for me to reproduce this?

Checkout the develop branch of OrbTk start the widgets example cargo run --example widgets --release. And move the slider widget.

image

There is also a branch memory-fix there it is a little bit faster.

Does OrbTK have an invalidation mechanism that lets it only draw the widgets that have changed or does it redraw everything if anything changes?

At the moment it draws everything new. I was thinking a lot how to handle this. The problem is I can not only check if a widget has changes, if the size position is changed I have to check and redraw all parents and possible widgets in the near and check if they now overlap.

Ok, well I landed 2f5ce26. With that, plus the following change to OrbTK to use fill_rect() when possible reduces the time spent in DrawTarget::fill()/composite quite a bit.

diff --git a/crates/api/src/render_object/rectangle.rs b/crates/api/src/render_object/rectangle.rs
index e787ea15..67a928e3 100644
--- a/crates/api/src/render_object/rectangle.rs
+++ b/crates/api/src/render_object/rectangle.rs
@@ -211,21 +211,20 @@ impl RenderObject for RectangleRenderObject {
             ctx.render_context_2_d().fill();
         } else if has_thickness {
             self.render_bordered_rect_path(
                 ctx.render_context_2_d(),
                 Rectangle::new(*global_position + bounds.position(), bounds.size()),
                 background,
                 border_brush,
                 border_thickness,
             );
         } else {
-            ctx.render_context_2_d().rect(
+            ctx.render_context_2_d().set_fill_style(background);
+            ctx.render_context_2_d().fill_rect(
                 global_position.x() + bounds.x(),
                 global_position.y() + bounds.y(),
                 bounds.width(),
                 bounds.height(),
             );
-            ctx.render_context_2_d().set_fill_style(background);
-            ctx.render_context_2_d().fill();
         }
     }
 }

Thank you 🙂. I will test it. What I really like on raqote is its portability. I was thinking about to use fontkit in raqote for all platforms except of Redox. Could it be faster? Do you have any experience with it?

The fontkit support in raqote is currently not very good. It has some correctness issues and is slow. My current plan is to try to split out the font code from https://github.com/servo/webrender/tree/master/webrender/src/platform into a separate crate and use that for font rendering instead of font-kit. That should give speed, correctness and make it so that text properly matches platform rendering.

Unfortunately, I have no timeline for when I'll get to that.

Also a way to improve the performance further in the case you mentioned above is to use BlendMode::Src when drawing the background instead of BlendMode::SrcOver

Benchmarks of blending operations on various libraries also point to raqote being considerably slower than the alternatives, sometimes as much as 20x: https://github.com/RazrFalcon/tiny-skia/blob/master/benches/README.md

Tested on raqote 0.8.0 and sw-composite 0.7.12 from crates.io