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

Transparent windows in Wayland are opaque #5779

Closed
Hoverbear opened this issue Aug 24, 2022 · 7 comments
Closed

Transparent windows in Wayland are opaque #5779

Hoverbear opened this issue Aug 24, 2022 · 7 comments
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior O-Linux Specific to the Linux desktop operating system

Comments

@Hoverbear
Copy link

Hoverbear commented Aug 24, 2022

Bevy version

0.7.0, 0.8.1 or 0.9.0-dev

[Optional] Relevant system information

Rust:

❯ rustc --version
rustc 1.63.0 (4b91a6ea7 2022-08-08)

Adapter:

2022-08-23T23:51:13.144078Z  INFO bevy_render::renderer: AdapterInfo { name: "AMD RADV NAVI10", vendor: 4098, device: 29471, device_type: DiscreteGpu, backend: Vulkan }

On Arch Linux, using Gnome (in Wayland mode)

image

What you did

From a freshly cloned repository I ran:

cargo run --example transparent_window --features x11, yielding:

image

cargo run --example transparent_window --features wayland, yielding:

image

I attempted to update winit using the dependabot/cargo/winit-0.27.2 branch (#5701) with this patch, but it did not solve it:

Patch
diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs
index b48dd441..b9512340 100644
--- a/crates/bevy_winit/src/lib.rs
+++ b/crates/bevy_winit/src/lib.rs
@@ -4,6 +4,7 @@ mod web_resize;
mod winit_config;
mod winit_windows;

+use winit::window::CursorGrabMode;
pub use winit_config::*;
pub use winit_windows::*;

@@ -138,7 +139,7 @@ fn change_window(
               bevy_window::WindowCommand::SetCursorLockMode { locked } => {
                   let window = winit_windows.get_window(id).unwrap();
                   window
-                        .set_cursor_grab(locked)
+                        .set_cursor_grab(if locked { CursorGrabMode::Locked } else { CursorGrabMode::None })
                       .unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
               }
               bevy_window::WindowCommand::SetCursorVisibility { visible } => {
diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs
index 91550eef..91375f22 100644
--- a/crates/bevy_winit/src/winit_windows.rs
+++ b/crates/bevy_winit/src/winit_windows.rs
@@ -2,7 +2,7 @@ use bevy_math::IVec2;
use bevy_utils::{tracing::warn, HashMap};
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
use raw_window_handle::HasRawWindowHandle;
-use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
+use winit::{dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, window::CursorGrabMode};

#[derive(Debug, Default)]
pub struct WinitWindows {
@@ -156,7 +156,7 @@ impl WinitWindows {
       let winit_window = winit_window_builder.build(event_loop).unwrap();

       if window_descriptor.cursor_locked {
-            match winit_window.set_cursor_grab(true) {
+            match winit_window.set_cursor_grab(CursorGrabMode::Locked) {
               Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {}
               Err(err) => Err(err).unwrap(),
           }
@@ -238,7 +238,7 @@ pub fn get_fitting_videomode(
       match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) {
           Equal => {
               match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) {
-                    Equal => b.refresh_rate().cmp(&a.refresh_rate()),
+                    Equal => b.refresh_rate_millihertz().cmp(&a.refresh_rate_millihertz()),
                   default => default,
               }
           }
@@ -255,7 +255,7 @@ pub fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::mon
       use std::cmp::Ordering::*;
       match b.size().width.cmp(&a.size().width) {
           Equal => match b.size().height.cmp(&a.size().height) {
-                Equal => b.refresh_rate().cmp(&a.refresh_rate()),
+                Equal => b.refresh_rate_millihertz().cmp(&a.refresh_rate_millihertz()),
               default => default,
           },
           default => default,

I then attempted to replicate the issue in winit using the latest main, however winit won't draw wayland windows (note) so I couldn't replicate.

The example in winit ran but did not produce a visual window:

winit on  master is 📦 v0.27.2 via 🦀 v1.63.0 
❯ cargo run --example transparent --features wayland
    Blocking waiting for file lock on build directory
    Finished dev [unoptimized + debuginfo] target(s) in 3.91s
     Running `target/debug/examples/transparent`
2022-08-24T00:46:14.093Z TRACE [crossfont::ft::fc::font_set] Number of fonts is 175
2022-08-24T00:46:14.094Z TRACE [crossfont::ft] Got font path="/usr/share/fonts/noto/NotoSans-Regular.ttf", index=0
2022-08-24T00:46:14.094Z DEBUG [crossfont::ft] Loaded Face Face { ft_face: Font Face: Regular, load_flags: TARGET_LIGHT, render_mode: "Normal", lcd_filter: 1 }
NewEvents(Init)
Resumed
NewEvents(WaitCancelled { start: Instant { tv_sec: 4824, tv_nsec: 233335504 }, requested_resume: None })
WindowEvent { window_id: WindowId(WindowId(94012884126464)), event: Focused(false) }
MainEventsCleared
RedrawRequested(WindowId(WindowId(94012884126464)))
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4831, tv_nsec: 4778737 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4832, tv_nsec: 36637634 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared

Next I tried glutin as the winit docs recommended instead (note), this seemed to work ok:
image

What went wrong

I was expecting roughly the same output between x11 and Wayland in the example. The wayland feature seems to render the example incorrect, as the window is supposed to be transparent.

Additional information

It's unclear to me what's going on and I'm fairly new to bevy, so I don't really have any idea what's going on!

@benbrittain noted gfx-rs/wgpu#687 (comment) might be relevant, if so that implies gfx-rs/wgpu#2836 may be required to fix this.

@Hoverbear Hoverbear added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Aug 24, 2022
@alice-i-cecile alice-i-cecile added A-Windowing Platform-agnostic interface layer to run your app in O-Linux Specific to the Linux desktop operating system and removed S-Needs-Triage This issue needs to be labelled labels Aug 24, 2022
@alice-i-cecile
Copy link
Member

alice-i-cecile commented Aug 24, 2022

I then attempted to replicate the issue in winit using the latest main, however winit won't draw wayland windows (note) so I couldn't replicate.

That's unfortunate. I expect that whatever special-casing we're doing to work around this is ultimately responsible here.

@Hoverbear
Copy link
Author

I attempted to reproduce, here is the log (adding it above!)

Because winit's scope, its examples aren't functional in wayland: https://github.com/rust-windowing/winit#wayland
image

winit on  master is 📦 v0.27.2 via 🦀 v1.63.0 
❯ cargo run --example transparent --features wayland
    Blocking waiting for file lock on build directory
    Finished dev [unoptimized + debuginfo] target(s) in 3.91s
     Running `target/debug/examples/transparent`
2022-08-24T00:46:14.093Z TRACE [crossfont::ft::fc::font_set] Number of fonts is 175
2022-08-24T00:46:14.094Z TRACE [crossfont::ft] Got font path="/usr/share/fonts/noto/NotoSans-Regular.ttf", index=0
2022-08-24T00:46:14.094Z DEBUG [crossfont::ft] Loaded Face Face { ft_face: Font Face: Regular, load_flags: TARGET_LIGHT, render_mode: "Normal", lcd_filter: 1 }
NewEvents(Init)
Resumed
NewEvents(WaitCancelled { start: Instant { tv_sec: 4824, tv_nsec: 233335504 }, requested_resume: None })
WindowEvent { window_id: WindowId(WindowId(94012884126464)), event: Focused(false) }
MainEventsCleared
RedrawRequested(WindowId(WindowId(94012884126464)))
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4831, tv_nsec: 4778737 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4832, tv_nsec: 36637634 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared

No visual window is created.

@Hoverbear
Copy link
Author

Based on @alice-i-cecile 's comment I attempted to build the example without bevy_winit and was still able to reproduce the issue:

image

@alice-i-cecile
Copy link
Member

Good digging. I strongly suspect that the linked wgpu issue is ultimately responsible then.

@alice-i-cecile alice-i-cecile added the S-Blocked This cannot more forward until something else changes label Aug 24, 2022
@Hoverbear
Copy link
Author

So I rebased gfx-rs/wgpu#2836 over the v0.13.1 tag of wgpu (published https://github.com/Hoverbear-Consulting/wgpu/tree/rebased-alpha_mode-for-bevy-5779) and then patched the Cargo.toml to use that wgpu branch.

diff --git a/Cargo.toml b/Cargo.toml
index b0920d9e..52bccaeb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1555,3 +1555,6 @@ inherits = "release"
 opt-level = "z"
 lto = "fat"
 codegen-units = 1
+
+[patch.crates-io]
+wgpu = { git = "https://github.com/Hoverbear-Consulting/wgpu", branch = "rebased-alpha_mode-for-bevy-5779" }
\ No newline at end of file
diff --git a/crates/bevy_render/src/view/window.rs b/crates/bevy_render/src/view/window.rs
index bba94068..2351a0ea 100644
--- a/crates/bevy_render/src/view/window.rs
+++ b/crates/bevy_render/src/view/window.rs
@@ -172,6 +172,7 @@ pub fn prepare_windows(
                 PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
                 PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
             },
+            alpha_mode: wgpu::CompositeAlphaMode::PreMultiplied,
         };
 
         // Do the initial surface configuration if it hasn't been configured yet

Then running the transparent_window example using wgpu::CompositeAlphaMode::PreMultiplied:

image

Here using wgpu::CompositeAlphaMode::PostMultiplied:

image

I'm not entirely clear what this setting should be, but I can at least confirm that the patch improves the current situation with little effort.

@irate-devil
Copy link
Contributor

irate-devil commented Oct 21, 2022

I can't reproduce this on either 0.7.0, 0.8.1, or 0.9.0-dev.
Manjaro, Plasma wayland
Adapter:

AdapterInfo { name: "NVIDIA GeForce RTX 2070 SUPER", vendor: 4318, device: 7812, device_type: DiscreteGpu, backend: Vulkan }

This could be vendor-specific.
The recently merged version bump of wgpu/winit may have fixed this.

@alice-i-cecile alice-i-cecile removed the S-Blocked This cannot more forward until something else changes label Oct 21, 2022
@mockersf
Copy link
Member

fixed as said above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior O-Linux Specific to the Linux desktop operating system
Projects
None yet
Development

No branches or pull requests

4 participants