-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix shadow rendering for tiny-skia backend #2715
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
base: master
Are you sure you want to change the base?
Conversation
|
I don't think this is an optimal fix. Since now the software renderer would redraw everything every update, leading to much higher CPU usage. |
Agree. |
|
Looking at the issues you linked, I think it might be that the damage regions aren't taking the shadow's blur radius + offset into consideration. This means that as the damaged areas are redrawn, because the regions aren't including the shadows, they won't get cleared properly. Consequently, the renderer will draw over them (additively) after every update. This repeated stacking might explain why the shadows get darker. |
|
Looking at this, it may make sense to abstract the bounds calculation to "layout bounds" and "render bounds" where one deals with collision/layout, and the other is the bounds that will be modified when rendering, for dirty tracking, etc. |
This approach makes sense to me, but I'm unsure how to implement it, could be great to have at least a PR to demonstrate how it effects on performance. |
|
To reproduce scrollable bug with buttons with shadow: Click to expanduse iced::widget::{button, column, container, scrollable, text};
use iced::{
color,
widget::button::{Status, Style},
window::Settings,
Shadow,
};
use iced::{Length, Theme};
pub trait StyleUtils {
fn with_shadow(self, shadow: impl Into<Shadow>) -> Self;
}
impl StyleUtils for Style {
fn with_shadow(self, shadow: impl Into<Shadow>) -> Self {
Self {
shadow: shadow.into(),
..self
}
}
}
#[derive(Default, Debug, Clone)]
enum Message {
#[default]
Test,
}
fn main() -> iced::Result {
iced::application("shadow", |_: &mut i32, _| {}, view)
.window(Settings {
size: (300.0, 250.0).into(),
resizable: false,
..Default::default()
})
.run()
}
fn view(_state: &i32) -> iced::Element<Message> {
let mut c = column![];
for _ in 0..10 {
let shadow_button = button(text("foo").size(20)).style(|theme: &Theme, status: Status| {
button::primary(theme, status).with_shadow(Shadow {
color: color!(0x000000),
offset: [2.0, 5.0].into(),
blur_radius: 5.0,
})
});
c = c.push(shadow_button.on_press(Message::Test));
}
container(scrollable(c.spacing(20).padding(20)))
.center(Length::Fill)
.padding(50)
.into()
} |
| x: self.bounds.x + shadow.offset.x - shadow.blur_radius, | ||
| y: self.bounds.y + shadow.offset.y - shadow.blur_radius, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This math looks off to me.
What happens when the shadow.offset is high?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to compute the shadow_bounds, not the bounding box of the Quad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This math looks off to me.
What happens when the
shadow.offsetis high?
I just extracted this math from Engine::draw_quad to avoid duplicating usages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when the
shadow.offsetis high?
I actually didn't test that; I need relevant example to investigate about that.
Fixes #2712
After commits bisecting, I found the issued came out from #2382 (commit 1e802e7).
This PR adds
bounds_with_shadowtoQuad.I verified it by running
cargo r -p custom_quad.TODO
wgpuandtiny-skiawith custom theme #2339 (comment)custom_quadexample, after moving shadow down, hovering on sliders shouldn't destroy shadow.