WayVR: Minor refactoring, fix panic after dropping an overlay
This commit is contained in:
@@ -60,6 +60,7 @@ pub struct Display {
|
|||||||
pub layout: packet_server::WvrDisplayWindowLayout,
|
pub layout: packet_server::WvrDisplayWindowLayout,
|
||||||
pub overlay_id: Option<OverlayID>,
|
pub overlay_id: Option<OverlayID>,
|
||||||
pub wants_redraw: bool,
|
pub wants_redraw: bool,
|
||||||
|
pub rendered_frame_count: u32,
|
||||||
pub primary: bool,
|
pub primary: bool,
|
||||||
pub wm: Rc<RefCell<window::WindowManager>>,
|
pub wm: Rc<RefCell<window::WindowManager>>,
|
||||||
pub displayed_windows: Vec<DisplayWindow>,
|
pub displayed_windows: Vec<DisplayWindow>,
|
||||||
@@ -166,6 +167,7 @@ impl Display {
|
|||||||
tasks: SyncEventQueue::new(),
|
tasks: SyncEventQueue::new(),
|
||||||
visible: true,
|
visible: true,
|
||||||
wants_redraw: true,
|
wants_redraw: true,
|
||||||
|
rendered_frame_count: 0,
|
||||||
layout: packet_server::WvrDisplayWindowLayout::Tiling,
|
layout: packet_server::WvrDisplayWindowLayout::Tiling,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -381,6 +383,8 @@ impl Display {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.rendered_frame_count += 1;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,7 @@ pub enum WayVRTask {
|
|||||||
NewToplevel(ClientId, ToplevelSurface),
|
NewToplevel(ClientId, ToplevelSurface),
|
||||||
DropToplevel(ClientId, ToplevelSurface),
|
DropToplevel(ClientId, ToplevelSurface),
|
||||||
NewExternalProcess(ExternalProcessRequest),
|
NewExternalProcess(ExternalProcessRequest),
|
||||||
DropOverlay(super::overlay::OverlayID),
|
|
||||||
ProcessTerminationRequest(process::ProcessHandle),
|
ProcessTerminationRequest(process::ProcessHandle),
|
||||||
Haptics(super::input::Haptics),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -87,6 +85,8 @@ pub enum WayVRSignal {
|
|||||||
packet_server::WvrDisplayWindowLayout,
|
packet_server::WvrDisplayWindowLayout,
|
||||||
),
|
),
|
||||||
BroadcastStateChanged(packet_server::WvrStateChanged),
|
BroadcastStateChanged(packet_server::WvrStateChanged),
|
||||||
|
DropOverlay(super::overlay::OverlayID),
|
||||||
|
Haptics(super::input::Haptics),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BlitMethod {
|
pub enum BlitMethod {
|
||||||
@@ -124,7 +124,6 @@ pub struct WayVRState {
|
|||||||
pub tasks: SyncEventQueue<WayVRTask>,
|
pub tasks: SyncEventQueue<WayVRTask>,
|
||||||
pub signals: SyncEventQueue<WayVRSignal>,
|
pub signals: SyncEventQueue<WayVRSignal>,
|
||||||
ticks: u64,
|
ticks: u64,
|
||||||
pub pending_haptic: Option<super::input::Haptics>,
|
|
||||||
cur_modifiers: u8,
|
cur_modifiers: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +144,6 @@ pub enum TickTask {
|
|||||||
packet_client::WvrDisplayCreateParams,
|
packet_client::WvrDisplayCreateParams,
|
||||||
Option<display::DisplayHandle>, /* existing handle? */
|
Option<display::DisplayHandle>, /* existing handle? */
|
||||||
),
|
),
|
||||||
DropOverlay(super::overlay::OverlayID),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WayVR {
|
impl WayVR {
|
||||||
@@ -268,7 +266,6 @@ impl WayVR {
|
|||||||
dashboard_display: None,
|
dashboard_display: None,
|
||||||
ticks: 0,
|
ticks: 0,
|
||||||
tasks,
|
tasks,
|
||||||
pending_haptic: None,
|
|
||||||
signals: SyncEventQueue::new(),
|
signals: SyncEventQueue::new(),
|
||||||
cur_modifiers: 0,
|
cur_modifiers: 0,
|
||||||
};
|
};
|
||||||
@@ -276,15 +273,15 @@ impl WayVR {
|
|||||||
Ok(Self { state, ipc_server })
|
Ok(Self { state, ipc_server })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_display(&mut self, display: display::DisplayHandle) -> anyhow::Result<bool> {
|
pub fn render_display(&mut self, display: display::DisplayHandle) -> anyhow::Result<bool> {
|
||||||
// millis since the start of wayvr
|
|
||||||
let display = self
|
let display = self
|
||||||
.state
|
.state
|
||||||
.displays
|
.displays
|
||||||
.get_mut(&display)
|
.get_mut(&display)
|
||||||
.ok_or_else(|| anyhow::anyhow!(STR_INVALID_HANDLE_DISP))?;
|
.ok_or_else(|| anyhow::anyhow!(STR_INVALID_HANDLE_DISP))?;
|
||||||
|
|
||||||
if !display.wants_redraw {
|
/* Buffer warm-up is required, always two first calls of this function are always rendered */
|
||||||
|
if !display.wants_redraw && display.rendered_frame_count >= 2 {
|
||||||
// Nothing changed, do not render
|
// Nothing changed, do not render
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
@@ -294,6 +291,7 @@ impl WayVR {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// millis since the start of 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.manager.state.gles_renderer, time_ms)?;
|
display.tick_render(&mut self.state.manager.state.gles_renderer, time_ms)?;
|
||||||
@@ -362,9 +360,6 @@ impl WayVR {
|
|||||||
WayVRTask::NewExternalProcess(req) => {
|
WayVRTask::NewExternalProcess(req) => {
|
||||||
tasks.push(TickTask::NewExternalProcess(req));
|
tasks.push(TickTask::NewExternalProcess(req));
|
||||||
}
|
}
|
||||||
WayVRTask::DropOverlay(overlay_id) => {
|
|
||||||
tasks.push(TickTask::DropOverlay(overlay_id));
|
|
||||||
}
|
|
||||||
WayVRTask::NewToplevel(client_id, toplevel) => {
|
WayVRTask::NewToplevel(client_id, toplevel) => {
|
||||||
// Attach newly created toplevel surfaces to displays
|
// Attach newly created toplevel surfaces to displays
|
||||||
for client in &self.state.manager.clients {
|
for client in &self.state.manager.clients {
|
||||||
@@ -432,9 +427,6 @@ impl WayVR {
|
|||||||
process.terminate();
|
process.terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WayVRTask::Haptics(haptics) => {
|
|
||||||
self.state.pending_haptic = Some(haptics);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +584,7 @@ impl WayVRState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(overlay_id) = display.overlay_id {
|
if let Some(overlay_id) = display.overlay_id {
|
||||||
self.tasks.send(WayVRTask::DropOverlay(overlay_id));
|
self.signals.send(WayVRSignal::DropOverlay(overlay_id));
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Destroying display without OverlayID set"); // This shouldn't happen, but log it anyways.
|
log::warn!("Destroying display without OverlayID set"); // This shouldn't happen, but log it anyways.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -470,14 +470,13 @@ impl Connection {
|
|||||||
params: &mut TickParams,
|
params: &mut TickParams,
|
||||||
haptics_params: packet_client::WlxHapticsParams,
|
haptics_params: packet_client::WlxHapticsParams,
|
||||||
) {
|
) {
|
||||||
params
|
params.state.signals.send(super::WayVRSignal::Haptics(
|
||||||
.state
|
crate::backend::input::Haptics {
|
||||||
.tasks
|
|
||||||
.send(super::WayVRTask::Haptics(crate::backend::input::Haptics {
|
|
||||||
duration: haptics_params.duration,
|
duration: haptics_params.duration,
|
||||||
frequency: haptics_params.frequency,
|
frequency: haptics_params.frequency,
|
||||||
intensity: haptics_params.intensity,
|
intensity: haptics_params.intensity,
|
||||||
}));
|
},
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_payload(&mut self, params: &mut TickParams, payload: Payload) -> anyhow::Result<()> {
|
fn process_payload(&mut self, params: &mut TickParams, payload: Payload) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ pub struct WayVRData {
|
|||||||
overlays_to_create: Vec<OverlayToCreate>,
|
overlays_to_create: Vec<OverlayToCreate>,
|
||||||
dashboard_executed: bool,
|
dashboard_executed: bool,
|
||||||
pub data: WayVR,
|
pub data: WayVR,
|
||||||
|
pending_haptics: Option<input::Haptics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WayVRData {
|
impl WayVRData {
|
||||||
@@ -68,6 +69,7 @@ impl WayVRData {
|
|||||||
data: WayVR::new(config)?,
|
data: WayVR::new(config)?,
|
||||||
overlays_to_create: Vec::new(),
|
overlays_to_create: Vec::new(),
|
||||||
dashboard_executed: false,
|
dashboard_executed: false,
|
||||||
|
pending_haptics: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,18 +117,21 @@ impl InteractionHandler for WayVRInteractionHandler {
|
|||||||
) -> Option<input::Haptics> {
|
) -> Option<input::Haptics> {
|
||||||
let ctx = self.context.borrow();
|
let ctx = self.context.borrow();
|
||||||
|
|
||||||
let wayvr = &mut ctx.wayvr.borrow_mut().data;
|
let wayvr = &mut ctx.wayvr.borrow_mut();
|
||||||
|
|
||||||
if let Some(disp) = wayvr.state.displays.get(&ctx.display) {
|
if let Some(disp) = wayvr.data.state.displays.get(&ctx.display) {
|
||||||
let pos = self.mouse_transform.transform_point2(hit.uv);
|
let pos = self.mouse_transform.transform_point2(hit.uv);
|
||||||
let x = ((pos.x * f32::from(disp.width)) as i32).max(0);
|
let x = ((pos.x * f32::from(disp.width)) as i32).max(0);
|
||||||
let y = ((pos.y * f32::from(disp.height)) as i32).max(0);
|
let y = ((pos.y * f32::from(disp.height)) as i32).max(0);
|
||||||
|
|
||||||
let ctx = self.context.borrow();
|
let ctx = self.context.borrow();
|
||||||
wayvr.state.send_mouse_move(ctx.display, x as u32, y as u32);
|
wayvr
|
||||||
|
.data
|
||||||
|
.state
|
||||||
|
.send_mouse_move(ctx.display, x as u32, y as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
wayvr.state.pending_haptic.take()
|
wayvr.pending_haptics.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_left(&mut self, _app: &mut state::AppState, _pointer: usize) {
|
fn on_left(&mut self, _app: &mut state::AppState, _pointer: usize) {
|
||||||
@@ -169,12 +174,17 @@ impl InteractionHandler for WayVRInteractionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ImageData {
|
||||||
|
vk_image: Arc<vulkano::image::Image>,
|
||||||
|
vk_image_view: Arc<vulkano::image::view::ImageView>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WayVRRenderer {
|
pub struct WayVRRenderer {
|
||||||
pipeline: Arc<WlxPipeline>,
|
pipeline: Arc<WlxPipeline>,
|
||||||
vk_image: Option<Arc<vulkano::image::Image>>,
|
image: Option<ImageData>,
|
||||||
vk_image_view: Option<Arc<vulkano::image::view::ImageView>>,
|
|
||||||
context: Rc<RefCell<WayVRContext>>,
|
context: Rc<RefCell<WayVRContext>>,
|
||||||
graphics: Arc<WlxGraphics>,
|
graphics: Arc<WlxGraphics>,
|
||||||
|
resolution: [u16; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WayVRRenderer {
|
impl WayVRRenderer {
|
||||||
@@ -182,6 +192,7 @@ impl WayVRRenderer {
|
|||||||
app: &state::AppState,
|
app: &state::AppState,
|
||||||
wvr: Rc<RefCell<WayVRData>>,
|
wvr: Rc<RefCell<WayVRData>>,
|
||||||
display: wayvr::display::DisplayHandle,
|
display: wayvr::display::DisplayHandle,
|
||||||
|
resolution: [u16; 2],
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let Ok(shaders) = app.graphics.shared_shaders.read() else {
|
let Ok(shaders) = app.graphics.shared_shaders.read() else {
|
||||||
anyhow::bail!("Failed to lock shared shaders for reading");
|
anyhow::bail!("Failed to lock shared shaders for reading");
|
||||||
@@ -197,9 +208,9 @@ impl WayVRRenderer {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
pipeline,
|
pipeline,
|
||||||
context: Rc::new(RefCell::new(WayVRContext::new(wvr, display))),
|
context: Rc::new(RefCell::new(WayVRContext::new(wvr, display))),
|
||||||
vk_image: None,
|
|
||||||
vk_image_view: None,
|
|
||||||
graphics: app.graphics.clone(),
|
graphics: app.graphics.clone(),
|
||||||
|
image: None,
|
||||||
|
resolution,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -470,6 +481,13 @@ where
|
|||||||
.ipc_server
|
.ipc_server
|
||||||
.broadcast(packet_server::PacketServer::WvrStateChanged(packet));
|
.broadcast(packet_server::PacketServer::WvrStateChanged(packet));
|
||||||
}
|
}
|
||||||
|
wayvr::WayVRSignal::DropOverlay(overlay_id) => {
|
||||||
|
app.tasks
|
||||||
|
.enqueue(TaskType::DropOverlay(OverlaySelector::Id(overlay_id)));
|
||||||
|
}
|
||||||
|
wayvr::WayVRSignal::Haptics(haptics) => {
|
||||||
|
wayvr.pending_haptics = Some(haptics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,10 +565,6 @@ where
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
wayvr::TickTask::DropOverlay(overlay_id) => {
|
|
||||||
app.tasks
|
|
||||||
.enqueue(TaskType::DropOverlay(OverlaySelector::Id(overlay_id)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,10 +595,10 @@ impl WayVRRenderer {
|
|||||||
upload.build_and_execute_now()?;
|
upload.build_and_execute_now()?;
|
||||||
|
|
||||||
//buffers.push(upload.build()?);
|
//buffers.push(upload.build()?);
|
||||||
|
self.image = Some(ImageData {
|
||||||
self.vk_image = Some(tex.clone());
|
vk_image: tex.clone(),
|
||||||
self.vk_image_view = Some(ImageView::new_default(tex).unwrap());
|
vk_image_view: ImageView::new_default(tex).unwrap(),
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +606,7 @@ impl WayVRRenderer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
data: &wayvr::egl_data::RenderDMAbufData,
|
data: &wayvr::egl_data::RenderDMAbufData,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if self.vk_image.is_some() {
|
if self.image.is_some() {
|
||||||
return Ok(()); // already initialized and automatically updated due to direct zero-copy textue access
|
return Ok(()); // already initialized and automatically updated due to direct zero-copy textue access
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,8 +654,10 @@ impl WayVRRenderer {
|
|||||||
&data.mod_info.modifiers,
|
&data.mod_info.modifiers,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.vk_image = Some(tex.clone());
|
self.image = Some(ImageData {
|
||||||
self.vk_image_view = Some(vulkano::image::view::ImageView::new_default(tex).unwrap());
|
vk_image: tex.clone(),
|
||||||
|
vk_image_view: ImageView::new_default(tex).unwrap(),
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -668,10 +684,10 @@ impl OverlayRenderer for WayVRRenderer {
|
|||||||
fn should_render(&mut self, _app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
fn should_render(&mut self, _app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||||
let ctx = self.context.borrow();
|
let ctx = self.context.borrow();
|
||||||
let mut wayvr = ctx.wayvr.borrow_mut();
|
let mut wayvr = ctx.wayvr.borrow_mut();
|
||||||
let redrawn = match wayvr.data.tick_display(ctx.display) {
|
let redrawn = match wayvr.data.render_display(ctx.display) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("tick_display failed: {e}");
|
log::error!("render_display failed: {e}");
|
||||||
return Ok(ShouldRender::Unable);
|
return Ok(ShouldRender::Unable);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -714,13 +730,15 @@ impl OverlayRenderer for WayVRRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(view) = self.vk_image_view.as_ref() else {
|
let Some(image) = self.image.as_ref() else {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
let set0 =
|
let set0 = self.pipeline.uniform_sampler(
|
||||||
self.pipeline
|
0,
|
||||||
.uniform_sampler(0, view.clone(), app.graphics.texture_filtering)?;
|
image.vk_image_view.clone(),
|
||||||
|
app.graphics.texture_filtering,
|
||||||
|
)?;
|
||||||
|
|
||||||
let set1 = self.pipeline.uniform_buffer(1, vec![alpha])?;
|
let set1 = self.pipeline.uniform_buffer(1, vec![alpha])?;
|
||||||
|
|
||||||
@@ -740,17 +758,10 @@ impl OverlayRenderer for WayVRRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
||||||
let ctx = self.context.borrow();
|
Some(FrameMeta {
|
||||||
let wayvr = ctx.wayvr.borrow_mut();
|
extent: [self.resolution[0] as u32, self.resolution[1] as u32, 1],
|
||||||
wayvr
|
..Default::default()
|
||||||
.data
|
})
|
||||||
.state
|
|
||||||
.displays
|
|
||||||
.get(&ctx.display)
|
|
||||||
.map(|disp| FrameMeta {
|
|
||||||
extent: [disp.width as _, disp.height as _, 1],
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,7 +793,7 @@ where
|
|||||||
|
|
||||||
let wayvr = app.get_wayvr()?;
|
let wayvr = app.get_wayvr()?;
|
||||||
|
|
||||||
let renderer = WayVRRenderer::new(app, wayvr, display_handle)?;
|
let renderer = WayVRRenderer::new(app, wayvr, display_handle, [display_width, display_height])?;
|
||||||
let context = renderer.context.clone();
|
let context = renderer.context.clone();
|
||||||
|
|
||||||
let backend = Box::new(SplitOverlayBackend {
|
let backend = Box::new(SplitOverlayBackend {
|
||||||
|
|||||||
Reference in New Issue
Block a user