Fix alpha mode configuration in iced_wgpu

This commit is contained in:
Daniel Yoon 2024-02-03 17:27:24 +11:00 committed by Héctor Ramón Jiménez
parent 7ee00e751a
commit 712c8e53f2
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
2 changed files with 83 additions and 20 deletions

View file

@ -1,11 +1,20 @@
use iced::gradient; use iced::theme::Palette;
use iced::widget::{column, container, horizontal_space, row, slider, text}; use iced::widget::{
checkbox, column, container, horizontal_space, row, slider, text,
};
use iced::{gradient, window};
use iced::{ use iced::{
Alignment, Background, Color, Element, Length, Radians, Sandbox, Settings, Alignment, Background, Color, Element, Length, Radians, Sandbox, Settings,
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
Gradient::run(Settings::default()) Gradient::run(Settings {
window: window::Settings {
transparent: true,
..Default::default()
},
..Default::default()
})
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -13,6 +22,7 @@ struct Gradient {
start: Color, start: Color,
end: Color, end: Color,
angle: Radians, angle: Radians,
transparent_window: bool,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -20,6 +30,7 @@ enum Message {
StartChanged(Color), StartChanged(Color),
EndChanged(Color), EndChanged(Color),
AngleChanged(Radians), AngleChanged(Radians),
SetTransparent(bool),
} }
impl Sandbox for Gradient { impl Sandbox for Gradient {
@ -30,6 +41,7 @@ impl Sandbox for Gradient {
start: Color::WHITE, start: Color::WHITE,
end: Color::new(0.0, 0.0, 1.0, 1.0), end: Color::new(0.0, 0.0, 1.0, 1.0),
angle: Radians(0.0), angle: Radians(0.0),
transparent_window: false,
} }
} }
@ -42,11 +54,19 @@ impl Sandbox for Gradient {
Message::StartChanged(color) => self.start = color, Message::StartChanged(color) => self.start = color,
Message::EndChanged(color) => self.end = color, Message::EndChanged(color) => self.end = color,
Message::AngleChanged(angle) => self.angle = angle, Message::AngleChanged(angle) => self.angle = angle,
Message::SetTransparent(transparent) => {
self.transparent_window = transparent;
}
} }
} }
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let Self { start, end, angle } = *self; let Self {
start,
end,
angle,
transparent_window,
} = *self;
let gradient_box = container(horizontal_space(Length::Fill)) let gradient_box = container(horizontal_space(Length::Fill))
.width(Length::Fill) .width(Length::Fill)
@ -72,14 +92,35 @@ impl Sandbox for Gradient {
.padding(8) .padding(8)
.align_items(Alignment::Center); .align_items(Alignment::Center);
let transparency_toggle = iced::widget::Container::new(
checkbox("Transparent window", transparent_window)
.on_toggle(Message::SetTransparent),
)
.padding(8);
column![ column![
color_picker("Start", self.start).map(Message::StartChanged), color_picker("Start", self.start).map(Message::StartChanged),
color_picker("End", self.end).map(Message::EndChanged), color_picker("End", self.end).map(Message::EndChanged),
angle_picker, angle_picker,
gradient_box transparency_toggle,
gradient_box,
] ]
.into() .into()
} }
fn theme(&self) -> iced::Theme {
if self.transparent_window {
iced::Theme::custom(
String::new(),
Palette {
background: Color::TRANSPARENT,
..iced::Theme::default().palette()
},
)
} else {
iced::Theme::default()
}
}
} }
fn color_picker(label: &str, color: Color) -> Element<'_, Color> { fn color_picker(label: &str, color: Color) -> Element<'_, Color> {
@ -91,6 +132,8 @@ fn color_picker(label: &str, color: Color) -> Element<'_, Color> {
.step(0.01), .step(0.01),
slider(0.0..=1.0, color.b, move |b| { Color { b, ..color } }) slider(0.0..=1.0, color.b, move |b| { Color { b, ..color } })
.step(0.01), .step(0.01),
slider(0.0..=1.0, color.a, move |a| { Color { a, ..color } })
.step(0.01),
] ]
.spacing(8) .spacing(8)
.padding(8) .padding(8)

View file

@ -15,6 +15,7 @@ pub struct Compositor {
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
format: wgpu::TextureFormat, format: wgpu::TextureFormat,
alpha_mode: wgpu::CompositeAlphaMode,
} }
impl Compositor { impl Compositor {
@ -61,25 +62,43 @@ impl Compositor {
log::info!("Selected: {:#?}", adapter.get_info()); log::info!("Selected: {:#?}", adapter.get_info());
let format = compatible_surface.as_ref().and_then(|surface| { let (format, alpha_mode) =
let capabilities = surface.get_capabilities(&adapter); compatible_surface.as_ref().and_then(|surface| {
let capabilities = surface.get_capabilities(&adapter);
let mut formats = capabilities.formats.iter().copied(); let mut formats = capabilities.formats.iter().copied();
let format = if color::GAMMA_CORRECTION { let format = if color::GAMMA_CORRECTION {
formats.find(wgpu::TextureFormat::is_srgb) formats.find(wgpu::TextureFormat::is_srgb)
} else { } else {
formats.find(|format| !wgpu::TextureFormat::is_srgb(format)) formats.find(|format| !wgpu::TextureFormat::is_srgb(format))
}; };
format.or_else(|| { let format = format.or_else(|| {
log::warn!("No format found!"); log::warn!("No format found!");
capabilities.formats.first().copied() capabilities.formats.first().copied()
}) });
})?;
log::info!("Selected format: {format:?}"); let alphas = capabilities.alpha_modes;
let preferred_alpha = if alphas
.contains(&wgpu::CompositeAlphaMode::PostMultiplied)
{
wgpu::CompositeAlphaMode::PostMultiplied
} else if alphas
.contains(&wgpu::CompositeAlphaMode::PreMultiplied)
{
wgpu::CompositeAlphaMode::PreMultiplied
} else {
wgpu::CompositeAlphaMode::Auto
};
format.zip(Some(preferred_alpha))
})?;
log::info!(
"Selected format: {format:?} with alpha mode: {alpha_mode:?}"
);
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
let limits = [wgpu::Limits::downlevel_webgl2_defaults() let limits = [wgpu::Limits::downlevel_webgl2_defaults()
@ -120,6 +139,7 @@ impl Compositor {
device, device,
queue, queue,
format, format,
alpha_mode,
}) })
} }
@ -249,7 +269,7 @@ impl graphics::Compositor for Compositor {
present_mode: self.settings.present_mode, present_mode: self.settings.present_mode,
width, width,
height, height,
alpha_mode: wgpu::CompositeAlphaMode::Auto, alpha_mode: self.alpha_mode,
view_formats: vec![], view_formats: vec![],
desired_maximum_frame_latency: 2, desired_maximum_frame_latency: 2,
}, },