Skip to content

Commit

Permalink
WIP winit git
Browse files Browse the repository at this point in the history
I wanted to see how the changes in Winit git would work here. So of
course this depends on that being released.

Depends on #1514. It doesn't seem
to pose a particular challenge beyond that. Updating compositors for
that change will be needed to test this...
  • Loading branch information
ids1024 committed Aug 26, 2024
1 parent 40066d2 commit d92a9ee
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 108 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ wayland-protocols-misc = { version = "0.3.1", features = ["server"], optional =
wayland-server = { version = "0.31.0", optional = true }
wayland-sys = { version = "0.31", optional = true }
wayland-backend = { version = "0.3.5", optional = true }
winit = { version = "0.30.0", default-features = false, features = ["wayland", "wayland-dlopen", "x11", "rwh_06"], optional = true }
winit = { git = "https://github.com/rust-windowing/winit", default-features = false, features = ["wayland", "wayland-dlopen", "x11", "rwh_06"], optional = true }
x11rb = { version = "0.13.0", optional = true }
xkbcommon = { version = "0.8.0", features = ["wayland"]}
scan_fmt = { version = "0.2.3", default-features = false }
Expand Down
171 changes: 91 additions & 80 deletions anvil/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,92 +98,13 @@ pub fn run_winit() {
let mut display_handle = display.handle();

#[cfg_attr(not(feature = "egl"), allow(unused_mut))]
let (mut backend, mut winit) = match winit::init::<GlesRenderer>() {
let mut winit = match winit::init::<GlesRenderer>() {
Ok(ret) => ret,
Err(err) => {
error!("Failed to initialize Winit backend: {}", err);
return;
}
};
let size = backend.window_size();

let mode = Mode {
size,
refresh: 60_000,
};
let output = Output::new(
OUTPUT_NAME.to_string(),
PhysicalProperties {
size: (0, 0).into(),
subpixel: Subpixel::Unknown,
make: "Smithay".into(),
model: "Winit".into(),
},
);
let _global = output.create_global::<AnvilState<WinitData>>(&display.handle());
output.change_current_state(Some(mode), Some(Transform::Flipped180), None, Some((0, 0).into()));
output.set_preferred(mode);

#[cfg(feature = "debug")]
let fps_image =
image::ImageReader::with_format(std::io::Cursor::new(FPS_NUMBERS_PNG), image::ImageFormat::Png)
.decode()
.unwrap();
#[cfg(feature = "debug")]
let fps_texture = backend
.renderer()
.import_memory(
&fps_image.to_rgba8(),
Fourcc::Abgr8888,
(fps_image.width() as i32, fps_image.height() as i32).into(),
false,
)
.expect("Unable to upload FPS texture");
#[cfg(feature = "debug")]
let mut fps_element = FpsElement::new(fps_texture);

let render_node = EGLDevice::device_for_display(backend.renderer().egl_context().display())
.and_then(|device| device.try_get_render_node());

let dmabuf_default_feedback = match render_node {
Ok(Some(node)) => {
let dmabuf_formats = backend.renderer().dmabuf_formats();
let dmabuf_default_feedback = DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats)
.build()
.unwrap();
Some(dmabuf_default_feedback)
}
Ok(None) => {
warn!("failed to query render node, dmabuf will use v3");
None
}
Err(err) => {
warn!(?err, "failed to egl device for display, dmabuf will use v3");
None
}
};

// if we failed to build dmabuf feedback we fall back to dmabuf v3
// Note: egl on Mesa requires either v4 or wl_drm (initialized with bind_wl_display)
let dmabuf_state = if let Some(default_feedback) = dmabuf_default_feedback {
let mut dmabuf_state = DmabufState::new();
let dmabuf_global = dmabuf_state.create_global_with_default_feedback::<AnvilState<WinitData>>(
&display.handle(),
&default_feedback,
);
(dmabuf_state, dmabuf_global, Some(default_feedback))
} else {
let dmabuf_formats = backend.renderer().dmabuf_formats();
let mut dmabuf_state = DmabufState::new();
let dmabuf_global =
dmabuf_state.create_global::<AnvilState<WinitData>>(&display.handle(), dmabuf_formats);
(dmabuf_state, dmabuf_global, None)
};

#[cfg(feature = "egl")]
if backend.renderer().bind_wl_display(&display.handle()).is_ok() {
info!("EGL hardware-acceleration enabled");
};

let data = {
let damage_tracker = OutputDamageTracker::from_output(&output);
Expand Down Expand Up @@ -212,6 +133,96 @@ pub fn run_winit() {

while state.running.load(Ordering::SeqCst) {
let status = winit.dispatch_new_events(|event| match event {
WinitEvent::WindowCreated(backend) => {
let size = backend.window_size();

let mode = Mode {
size,
refresh: 60_000,
};
let output = Output::new(
OUTPUT_NAME.to_string(),
PhysicalProperties {
size: (0, 0).into(),
subpixel: Subpixel::Unknown,
make: "Smithay".into(),
model: "Winit".into(),
},
);
let _global = output.create_global::<AnvilState<WinitData>>(&display.handle());
output.change_current_state(
Some(mode),
Some(Transform::Flipped180),
None,
Some((0, 0).into()),
);
output.set_preferred(mode);

#[cfg(feature = "debug")]
let fps_image = image::ImageReader::with_format(
std::io::Cursor::new(FPS_NUMBERS_PNG),
image::ImageFormat::Png,
)
.decode()
.unwrap();
#[cfg(feature = "debug")]
let fps_texture = backend
.renderer()
.import_memory(
&fps_image.to_rgba8(),
Fourcc::Abgr8888,
(fps_image.width() as i32, fps_image.height() as i32).into(),
false,
)
.expect("Unable to upload FPS texture");
#[cfg(feature = "debug")]
let mut fps_element = FpsElement::new(fps_texture);

let render_node = EGLDevice::device_for_display(backend.renderer().egl_context().display())
.and_then(|device| device.try_get_render_node());

let dmabuf_default_feedback = match render_node {
Ok(Some(node)) => {
let dmabuf_formats = backend.renderer().dmabuf_formats();
let dmabuf_default_feedback =
DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats)
.build()
.unwrap();
Some(dmabuf_default_feedback)
}
Ok(None) => {
warn!("failed to query render node, dmabuf will use v3");
None
}
Err(err) => {
warn!(?err, "failed to egl device for display, dmabuf will use v3");
None
}
};

// if we failed to build dmabuf feedback we fall back to dmabuf v3
// Note: egl on Mesa requires either v4 or wl_drm (initialized with bind_wl_display)
let dmabuf_state = if let Some(default_feedback) = dmabuf_default_feedback {
let mut dmabuf_state = DmabufState::new();
let dmabuf_global = dmabuf_state
.create_global_with_default_feedback::<AnvilState<WinitData>>(
&display.handle(),
&default_feedback,
);
(dmabuf_state, dmabuf_global, Some(default_feedback))
} else {
let dmabuf_formats = backend.renderer().dmabuf_formats();
let mut dmabuf_state = DmabufState::new();
let dmabuf_global = dmabuf_state
.create_global::<AnvilState<WinitData>>(&display.handle(), dmabuf_formats);
(dmabuf_state, dmabuf_global, None)
};

#[cfg(feature = "egl")]
if backend.renderer().bind_wl_display(&display.handle()).is_ok() {
info!("EGL hardware-acceleration enabled");
};
}
WinitEvent::Resized { size, .. } => {
// We only have one output
let output = state.space.outputs().next().unwrap().clone();
Expand Down
2 changes: 1 addition & 1 deletion src/backend/egl/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<A: AsFd + Send + 'static> EGLNativeDisplay for GbmDevice<A> {
}

#[cfg(feature = "backend_winit")]
impl EGLNativeDisplay for Arc<WinitWindow> {
impl EGLNativeDisplay for Arc<dyn WinitWindow> {
fn supported_platforms(&self) -> Vec<EGLPlatform<'_>> {
use winit::raw_window_handle::{self, HasDisplayHandle};

Expand Down
Loading

0 comments on commit d92a9ee

Please sign in to comment.