WayVR: Add dmabuf (backend_drm) to the compositor. Fixes crash for webkitgtk apps
This commit is contained in:
44
Cargo.lock
generated
44
Cargo.lock
generated
@@ -1380,12 +1380,46 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
|
checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "drm"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"bytemuck",
|
||||||
|
"drm-ffi",
|
||||||
|
"drm-fourcc",
|
||||||
|
"libc",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "drm-ffi"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8e41459d99a9b529845f6d2c909eb9adf3b6d2f82635ae40be8de0601726e8b"
|
||||||
|
dependencies = [
|
||||||
|
"drm-sys",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drm-fourcc"
|
name = "drm-fourcc"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
|
checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "drm-sys"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bafb66c8dbc944d69e15cfcc661df7e703beffbaec8bd63151368b06c5f9858c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys 0.6.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@@ -2401,6 +2435,12 @@ version = "0.4.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@@ -3546,7 +3586,7 @@ dependencies = [
|
|||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys 0.4.14",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3772,6 +3812,8 @@ dependencies = [
|
|||||||
"cgmath",
|
"cgmath",
|
||||||
"cursor-icon",
|
"cursor-icon",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
|
"drm",
|
||||||
|
"drm-ffi",
|
||||||
"drm-fourcc",
|
"drm-fourcc",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"errno",
|
"errno",
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ khronos-egl = { version = "6.0.0", features = ["static"], optional = true }
|
|||||||
smithay = { git = "https://github.com/Smithay/smithay.git", default-features = false, features = [
|
smithay = { git = "https://github.com/Smithay/smithay.git", default-features = false, features = [
|
||||||
"renderer_gl",
|
"renderer_gl",
|
||||||
"backend_egl",
|
"backend_egl",
|
||||||
|
"backend_drm",
|
||||||
"xwayland",
|
"xwayland",
|
||||||
"wayland_frontend",
|
"wayland_frontend",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
|
use smithay::backend::allocator::dmabuf::Dmabuf;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
use smithay::backend::renderer::utils::on_commit_buffer_handler;
|
use smithay::backend::renderer::utils::on_commit_buffer_handler;
|
||||||
|
use smithay::backend::renderer::ImportDma;
|
||||||
use smithay::input::{Seat, SeatHandler, SeatState};
|
use smithay::input::{Seat, SeatHandler, SeatState};
|
||||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||||
use smithay::reexports::wayland_server;
|
use smithay::reexports::wayland_server;
|
||||||
use smithay::reexports::wayland_server::protocol::{wl_buffer, wl_seat, wl_surface};
|
use smithay::reexports::wayland_server::protocol::{wl_buffer, wl_seat, wl_surface};
|
||||||
use smithay::reexports::wayland_server::Resource;
|
use smithay::reexports::wayland_server::Resource;
|
||||||
use smithay::wayland::buffer::BufferHandler;
|
use smithay::wayland::buffer::BufferHandler;
|
||||||
|
use smithay::wayland::dmabuf::{
|
||||||
|
DmabufFeedback, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier,
|
||||||
|
};
|
||||||
use smithay::wayland::output::OutputHandler;
|
use smithay::wayland::output::OutputHandler;
|
||||||
use smithay::wayland::shm::{ShmHandler, ShmState};
|
use smithay::wayland::shm::{ShmHandler, ShmState};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_compositor, delegate_data_device, delegate_output, delegate_seat, delegate_shm,
|
delegate_compositor, delegate_data_device, delegate_dmabuf, delegate_output, delegate_seat,
|
||||||
delegate_xdg_shell,
|
delegate_shm, delegate_xdg_shell,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
@@ -34,6 +40,8 @@ use super::event_queue::SyncEventQueue;
|
|||||||
use super::WayVRTask;
|
use super::WayVRTask;
|
||||||
|
|
||||||
pub struct Application {
|
pub struct Application {
|
||||||
|
pub gles_renderer: GlesRenderer,
|
||||||
|
pub dmabuf_state: (DmabufState, DmabufGlobal, Option<DmabufFeedback>),
|
||||||
pub compositor: compositor::CompositorState,
|
pub compositor: compositor::CompositorState,
|
||||||
pub xdg_shell: XdgShellState,
|
pub xdg_shell: XdgShellState,
|
||||||
pub seat_state: SeatState<Application>,
|
pub seat_state: SeatState<Application>,
|
||||||
@@ -172,6 +180,26 @@ impl ShmHandler for Application {
|
|||||||
|
|
||||||
impl OutputHandler for Application {}
|
impl OutputHandler for Application {}
|
||||||
|
|
||||||
|
impl DmabufHandler for Application {
|
||||||
|
fn dmabuf_state(&mut self) -> &mut DmabufState {
|
||||||
|
&mut self.dmabuf_state.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dmabuf_imported(
|
||||||
|
&mut self,
|
||||||
|
_global: &DmabufGlobal,
|
||||||
|
dmabuf: Dmabuf,
|
||||||
|
notifier: ImportNotifier,
|
||||||
|
) {
|
||||||
|
if self.gles_renderer.import_dmabuf(&dmabuf, None).is_ok() {
|
||||||
|
let _ = notifier.successful::<Application>();
|
||||||
|
} else {
|
||||||
|
notifier.failed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate_dmabuf!(Application);
|
||||||
delegate_xdg_shell!(Application);
|
delegate_xdg_shell!(Application);
|
||||||
delegate_compositor!(Application);
|
delegate_compositor!(Application);
|
||||||
delegate_shm!(Application);
|
delegate_shm!(Application);
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ use process::ProcessVec;
|
|||||||
use server_ipc::WayVRServer;
|
use server_ipc::WayVRServer;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::gles::GlesRenderer,
|
backend::{
|
||||||
|
egl,
|
||||||
|
renderer::{gles::GlesRenderer, ImportDma},
|
||||||
|
},
|
||||||
input::SeatState,
|
input::SeatState,
|
||||||
output::{Mode, Output},
|
output::{Mode, Output},
|
||||||
reexports::wayland_server::{self, backend::ClientId},
|
reexports::wayland_server::{self, backend::ClientId},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor,
|
compositor,
|
||||||
|
dmabuf::{DmabufFeedbackBuilder, DmabufState},
|
||||||
selection::data_device::DataDeviceState,
|
selection::data_device::DataDeviceState,
|
||||||
shell::xdg::{ToplevelSurface, XdgShellState},
|
shell::xdg::{ToplevelSurface, XdgShellState},
|
||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
@@ -81,7 +85,6 @@ pub struct Config {
|
|||||||
|
|
||||||
pub struct WayVRState {
|
pub struct WayVRState {
|
||||||
time_start: u64,
|
time_start: u64,
|
||||||
gles_renderer: GlesRenderer,
|
|
||||||
pub displays: display::DisplayVec,
|
pub displays: display::DisplayVec,
|
||||||
pub manager: client::WayVRCompositor,
|
pub manager: client::WayVRCompositor,
|
||||||
wm: Rc<RefCell<window::WindowManager>>,
|
wm: Rc<RefCell<window::WindowManager>>,
|
||||||
@@ -143,9 +146,55 @@ impl WayVR {
|
|||||||
size: (dummy_width, dummy_height).into(),
|
size: (dummy_width, dummy_height).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let _global = output.create_global::<Application>(&dh);
|
||||||
output.change_current_state(Some(mode), None, None, None);
|
output.change_current_state(Some(mode), None, None, None);
|
||||||
output.set_preferred(mode);
|
output.set_preferred(mode);
|
||||||
let _global = output.create_global::<Application>(&dh);
|
|
||||||
|
let egl_data = egl_data::EGLData::new()?;
|
||||||
|
|
||||||
|
let smithay_display = smithay_wrapper::get_egl_display(&egl_data)?;
|
||||||
|
let smithay_context = smithay_wrapper::get_egl_context(&egl_data, &smithay_display)?;
|
||||||
|
|
||||||
|
let render_node = egl::EGLDevice::device_for_display(&smithay_display)
|
||||||
|
.and_then(|device| device.try_get_render_node());
|
||||||
|
|
||||||
|
let gles_renderer = unsafe { GlesRenderer::new(smithay_context)? };
|
||||||
|
|
||||||
|
let dmabuf_default_feedback = match render_node {
|
||||||
|
Ok(Some(node)) => {
|
||||||
|
let dmabuf_formats = gles_renderer.dmabuf_formats();
|
||||||
|
let dmabuf_default_feedback =
|
||||||
|
DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
Some(dmabuf_default_feedback)
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
log::warn!("dmabuf: Failed to query render node");
|
||||||
|
debug_assert!(false);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("dmabuf: Failed to get egl device for display: {}", err);
|
||||||
|
debug_assert!(false);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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::<Application>(
|
||||||
|
&display.handle(),
|
||||||
|
&default_feedback,
|
||||||
|
);
|
||||||
|
(dmabuf_state, dmabuf_global, Some(default_feedback))
|
||||||
|
} else {
|
||||||
|
let dmabuf_formats = gles_renderer.dmabuf_formats();
|
||||||
|
let mut dmabuf_state = DmabufState::new();
|
||||||
|
let dmabuf_global =
|
||||||
|
dmabuf_state.create_global::<Application>(&display.handle(), dmabuf_formats);
|
||||||
|
(dmabuf_state, dmabuf_global, None)
|
||||||
|
};
|
||||||
|
|
||||||
let seat_keyboard = seat.add_keyboard(
|
let seat_keyboard = seat.add_keyboard(
|
||||||
Default::default(),
|
Default::default(),
|
||||||
@@ -164,18 +213,15 @@ impl WayVR {
|
|||||||
data_device,
|
data_device,
|
||||||
wayvr_tasks: tasks.clone(),
|
wayvr_tasks: tasks.clone(),
|
||||||
redraw_requests: HashSet::new(),
|
redraw_requests: HashSet::new(),
|
||||||
|
dmabuf_state,
|
||||||
|
gles_renderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
let time_start = get_millis();
|
let time_start = get_millis();
|
||||||
let egl_data = egl_data::EGLData::new()?;
|
|
||||||
let smithay_display = smithay_wrapper::get_egl_display(&egl_data)?;
|
|
||||||
let smithay_context = smithay_wrapper::get_egl_context(&egl_data, &smithay_display)?;
|
|
||||||
let gles_renderer = unsafe { GlesRenderer::new(smithay_context)? };
|
|
||||||
|
|
||||||
let ipc_server = WayVRServer::new()?;
|
let ipc_server = WayVRServer::new()?;
|
||||||
|
|
||||||
let state = WayVRState {
|
let state = WayVRState {
|
||||||
gles_renderer,
|
|
||||||
time_start,
|
time_start,
|
||||||
manager: client::WayVRCompositor::new(state, display, seat_keyboard, seat_pointer)?,
|
manager: client::WayVRCompositor::new(state, display, seat_keyboard, seat_pointer)?,
|
||||||
displays: DisplayVec::new(),
|
displays: DisplayVec::new(),
|
||||||
@@ -214,7 +260,7 @@ impl WayVR {
|
|||||||
|
|
||||||
let time_ms = get_millis() - self.state.time_start;
|
let time_ms = get_millis() - self.state.time_start;
|
||||||
|
|
||||||
display.tick_render(&mut self.state.gles_renderer, time_ms)?;
|
display.tick_render(&mut self.state.manager.state.gles_renderer, time_ms)?;
|
||||||
display.wants_redraw = false;
|
display.wants_redraw = false;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -316,10 +362,14 @@ impl WayVR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_finish(&mut self) -> anyhow::Result<()> {
|
pub fn tick_finish(&mut self) -> anyhow::Result<()> {
|
||||||
self.state.gles_renderer.with_context(|gl| unsafe {
|
self.state
|
||||||
gl.Flush();
|
.manager
|
||||||
gl.Finish();
|
.state
|
||||||
})?;
|
.gles_renderer
|
||||||
|
.with_context(|gl| unsafe {
|
||||||
|
gl.Flush();
|
||||||
|
gl.Finish();
|
||||||
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +454,7 @@ impl WayVRState {
|
|||||||
) -> anyhow::Result<display::DisplayHandle> {
|
) -> anyhow::Result<display::DisplayHandle> {
|
||||||
let display = display::Display::new(
|
let display = display::Display::new(
|
||||||
self.wm.clone(),
|
self.wm.clone(),
|
||||||
&mut self.gles_renderer,
|
&mut self.manager.state.gles_renderer,
|
||||||
self.egl_data.clone(),
|
self.egl_data.clone(),
|
||||||
self.manager.wayland_env.clone(),
|
self.manager.wayland_env.clone(),
|
||||||
width,
|
width,
|
||||||
|
|||||||
Reference in New Issue
Block a user