RazrFalcon / tiny-skia

A tiny Skia subset ported to Rust
BSD 3-Clause "New" or "Revised" License
1.05k stars 67 forks source link

Optimize rectangular clipping #10

Open RazrFalcon opened 3 years ago

RazrFalcon commented 3 years ago

Omit alpha mask generation for a simple rectangle.

hecrj commented 1 year ago

Hey! I'm relying on rectangular clipping quite a bit in the upcoming software renderer for iced and noticed that creating clip masks is quite expensive.

I'd be willing to take a stab at this. Is it something you'd prefer to implement yourself? If not, any specific pointers?

RazrFalcon commented 1 year ago

Well... it's an extremely hard thing to do even for myself. You have to have a very deep understanding of how Skia/tiny-skia works to do so.

Not to mention that clipping in Skia and tiny-skia are completely different. Skia's implementation is miles more complicated (it's like 3000 LOC), but way faster. And tiny-skia's one is basically an afterthought.

I don't have a good answer here. tiny-skia, de-facto, is the best CPU 2D library for Rust, sure, but it still sucks! There are months of work left and I have zero time now and in the future.

If you want to dive into this - go ahead. But I don't really have any guidance for you. And there is no point into looking how Skia works, because clipping in tiny-skia is completely different, at least right now.

The only hint I can give you is that Skia/tiny-skia works in two steps. First, it crates a horizontal "run", a line of pixels that should be blittered/rendered. And then it passes it to the rendering pipeline. Line-by-line. Currently, the rendering pipeline immediately applies the clipping mask. Which is slow and requires a rasterized alpha mask. What Skia does, is that its able to check/clip the "run" before even passing it to the rendering pipeline. This is waaaay faster. And this is what you should do/implement. Also, testing would be a nightmare.

Honestly, I think you would be better off using smaller Pixmaps instead of masks. This would give you rectangular masks for free. Basically, instead of having a large Pixmap + clip rect, you can just create a smaller Pixmap, render on top of it (make sure to translate/transform your "layers" accordingly) and then blend it back to the main Pixmap. It would probably be even faster then masks.

PS: I really hope someone would write a brand new 2D CPU library instead of tiny-skia, but I highly double of that. It's a really hard task. And in the mean time, tiny-skia is basically an abandonware.