Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental rendering #1811

Merged
merged 30 commits into from
Apr 27, 2023
Merged

Incremental rendering #1811

merged 30 commits into from
Apr 27, 2023

Conversation

hecrj
Copy link
Member

@hecrj hecrj commented Apr 26, 2023

This PR implements basic incremental rendering for the upcoming software renderer powered by tiny-skia.

Basically, we compare the graphical primitives of the last drawn frame with the current primitives and produce a list of rectangles representing the damaged regions of the frame. Then, this list is reduced by grouping rectangles in a certain distance threshold together. Finally, when drawing, we simply skip any primitive that does not intersect with any damaged region.

The following video shows the tour example but old primitives fade with time and the red rectangles are the grouped damage regions:

2023-04-05.06-31-02.mp4

The diffing logic of graphical primitives is generic enough and could be eventually reused in iced_wgpu.

@hecrj hecrj added feature New feature or request performance rendering labels Apr 26, 2023
@hecrj hecrj added this to the 0.10.0 milestone Apr 26, 2023
@@ -31,57 +34,127 @@ impl Backend {

#[cfg(feature = "svg")]
vector_pipeline: crate::vector::Pipeline::new(),

last_primitives: Vec::new(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a single Backend were able to be used multiple times (for multiple windows if that was intended) you would end up with a situation where the second window is fully redrawn because the primitives may be completely different on that other window.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly! This is a hint that damage tracking should actually happen at the compositor level. Fixed in af0303f.

@ids1024
Copy link
Contributor

ids1024 commented Apr 26, 2023

rust-windowing/softbuffer#99 now has APIs for buffer age and damage (where supported), so incremental rendering can be done with no-copy presentation. On some platforms, anyway.

On Wayland this uses double-buffering, so age can be None, 1, or 2, and you need to be able to update the parts of the surface that have changed in the past two frames. On MacOS currently there's a new buffer time so age is always None. (rust-windowing/softbuffer#95 or rust-windowing/softbuffer#96 would fix that). Other platforms currently use a single buffer so age is None or 1.

For Wgpu, it looks like there's no API for damage or anything that exposes the buffer age, or a way to update only part of it? gfx-rs/wgpu#2869 discusses damage, I don't see any mention of a feature like EGL_EXT_buffer_age.

@hecrj
Copy link
Member Author

hecrj commented Apr 27, 2023

@ids1024 Cool! It looks like all of those features are still being worked on. Let's wait a bit until everything settles!

@hecrj hecrj merged commit c31ab8e into advanced-text Apr 27, 2023
@hecrj hecrj deleted the incremental-rendering branch April 27, 2023 14:09
@ids1024
Copy link
Contributor

ids1024 commented Apr 27, 2023

rust-windowing/softbuffer#99 should work, though I've left it as a draft since it's still entirely untested. That presumably should help with incremental rendering performance on Windows and Linux.

@hecrj hecrj mentioned this pull request May 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants