From 1d9fa95ea08e8b1fd75c5b95bb3bd983dc35a6a7 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Mon, 19 Feb 2024 01:05:50 +0100 Subject: [PATCH] more error handling --- Cargo.lock | 9 ++-- src/backend/common.rs | 8 ++-- src/backend/openvr/mod.rs | 2 +- src/backend/openxr/lines.rs | 18 +++++--- src/backend/openxr/mod.rs | 78 ++++++++++++++------------------- src/backend/openxr/overlay.rs | 11 ++--- src/backend/openxr/swapchain.rs | 51 ++++++++++----------- src/overlays/keyboard.rs | 4 +- src/overlays/screen.rs | 47 ++++++++++++-------- src/overlays/watch.rs | 13 ++++-- 10 files changed, 125 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fce8386..4ff08e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2987,8 +2987,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rxscreen" -version = "0.1.6" -source = "git+https://github.com/galister/rxscreen.git#bb045fbe830d7ff4d2d5ffc408f3df8944e7d90f" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbab13f83503a8272b7150d487494992cf6c59c299dcaf5d8ffac75bad9fc96" dependencies = [ "libc", ] @@ -4291,8 +4292,8 @@ dependencies = [ [[package]] name = "wlx-capture" -version = "0.1.0" -source = "git+https://github.com/galister/wlx-capture#332dd363357a845e4107aaada9a67899e7398839" +version = "0.1.1" +source = "git+https://github.com/galister/wlx-capture#06a6ff48464fdda0f563a3b5858fcb69ea0f5980" dependencies = [ "ashpd", "drm-fourcc", diff --git a/src/backend/common.rs b/src/backend/common.rs index 5584496..9985a85 100644 --- a/src/backend/common.rs +++ b/src/backend/common.rs @@ -47,12 +47,12 @@ impl OverlayContainer where T: Default, { - pub fn new(app: &mut AppState) -> Self { + pub fn new(app: &mut AppState) -> anyhow::Result { let mut overlays = IdMap::new(); let (screens, extent) = if std::env::var("WAYLAND_DISPLAY").is_ok() { - crate::overlays::screen::get_screens_wayland(&app.session) + crate::overlays::screen::get_screens_wayland(&app.session)? } else { - crate::overlays::screen::get_screens_x11(&app.session) + crate::overlays::screen::get_screens_x11(&app.session)? }; let mut watch = create_watch::(&app, &screens); @@ -79,7 +79,7 @@ where } overlays.insert(screen.state.id, screen); } - Self { overlays, extent } + Ok(Self { overlays, extent }) } pub fn mut_by_selector(&mut self, selector: &OverlaySelector) -> Option<&mut OverlayData> { diff --git a/src/backend/openvr/mod.rs b/src/backend/openvr/mod.rs index 50ceee7..adcd5af 100644 --- a/src/backend/openvr/mod.rs +++ b/src/backend/openvr/mod.rs @@ -89,7 +89,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { install_manifest(&mut app_mgr); - let mut overlays = OverlayContainer::::new(&mut state); + let mut overlays = OverlayContainer::::new(&mut state)?; let mut space_mover = playspace::PlayspaceMover::new(); #[cfg(feature = "osc")] diff --git a/src/backend/openxr/lines.rs b/src/backend/openxr/lines.rs index 907f56b..c457882 100644 --- a/src/backend/openxr/lines.rs +++ b/src/backend/openxr/lines.rs @@ -49,7 +49,7 @@ impl LinePool { let tex = command_buffer.texture2d(1, 1, Format::R8G8B8A8_UNORM, &color); ImageView::new_default(tex).unwrap() }) - .collect::>(); + .collect(); command_buffer.build_and_execute_now(); @@ -59,10 +59,14 @@ impl LinePool { } } - pub(super) fn allocate(&mut self, xr: &XrState, graphics: Arc) -> usize { + pub(super) fn allocate( + &mut self, + xr: &XrState, + graphics: Arc, + ) -> anyhow::Result { let id = AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed); - let srd = create_swapchain_render_data(xr, graphics, [1, 1, 1]); + let srd = create_swapchain_render_data(xr, graphics, [1, 1, 1])?; self.lines.insert( id, LineContainer { @@ -70,7 +74,7 @@ impl LinePool { maybe_line: None, }, ); - id + Ok(id) } pub(super) fn draw_from( @@ -128,7 +132,7 @@ impl LinePool { &'a mut self, xr: &'a XrState, command_buffer: &mut WlxCommandBuffer, - ) -> Vec> { + ) -> Result>, xr::sys::Result> { let mut quads = Vec::new(); for line in self.lines.values_mut() { @@ -139,7 +143,7 @@ impl LinePool { command_buffer, inner.view, 1.0, - )) + )?) .eye_visibility(xr::EyeVisibility::BOTH) .layer_flags(xr::CompositionLayerFlags::CORRECT_CHROMATIC_ABERRATION) .space(&xr.stage) @@ -152,7 +156,7 @@ impl LinePool { } } - quads + Ok(quads) } /// the number of lines that are waiting to be drawn diff --git a/src/backend/openxr/mod.rs b/src/backend/openxr/mod.rs index a2aa7a4..b3d846d 100644 --- a/src/backend/openxr/mod.rs +++ b/src/backend/openxr/mod.rs @@ -50,9 +50,8 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { } }; - let environment_blend_mode = xr_instance - .enumerate_environment_blend_modes(system, VIEW_TYPE) - .unwrap()[0]; + let environment_blend_mode = + xr_instance.enumerate_environment_blend_modes(system, VIEW_TYPE)?[0]; log::info!("Using environment blend mode: {:?}", environment_blend_mode); let mut app_state = { @@ -60,7 +59,7 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { AppState::from_graphics(graphics)? }; - let mut overlays = OverlayContainer::::new(&mut app_state); + let mut overlays = OverlayContainer::::new(&mut app_state)?; let mut lines = LinePool::new(app_state.graphics.clone()); #[cfg(feature = "osc")] @@ -85,14 +84,12 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { queue_family_index: app_state.graphics.queue.queue_family_index(), queue_index: 0, }, - ) - .unwrap(); + )?; xr::Session::from_raw(xr_instance.clone(), raw_session, Box::new(())) }; - let stage = session - .create_reference_space(xr::ReferenceSpaceType::STAGE, xr::Posef::IDENTITY) - .unwrap(); + let stage = + session.create_reference_space(xr::ReferenceSpaceType::STAGE, xr::Posef::IDENTITY)?; let mut xr_state = XrState { instance: xr_instance, @@ -103,11 +100,11 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { }; let pointer_lines = [ - lines.allocate(&xr_state, app_state.graphics.clone()), - lines.allocate(&xr_state, app_state.graphics.clone()), + lines.allocate(&xr_state, app_state.graphics.clone())?, + lines.allocate(&xr_state, app_state.graphics.clone())?, ]; - let watch_id = overlays.get_by_name(WATCH_NAME).unwrap().state.id; + let watch_id = overlays.get_by_name(WATCH_NAME).unwrap().state.id; // want panic let input_source = input::OpenXrInputSource::new(&xr_state)?; @@ -130,7 +127,7 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { } } - while let Some(event) = xr_state.instance.poll_event(&mut event_storage).unwrap() { + while let Some(event) = xr_state.instance.poll_event(&mut event_storage)? { use xr::Event::*; match event { SessionStateChanged(e) => { @@ -139,11 +136,11 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { log::info!("entered state {:?}", e.state()); match e.state() { xr::SessionState::READY => { - xr_state.session.begin(VIEW_TYPE).unwrap(); + xr_state.session.begin(VIEW_TYPE)?; session_running = true; } xr::SessionState::STOPPING => { - xr_state.session.end().unwrap(); + xr_state.session.end()?; session_running = false; } xr::SessionState::EXITING | xr::SessionState::LOSS_PENDING => { @@ -167,19 +164,17 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { continue 'main_loop; } - let xr_frame_state = frame_wait.wait().unwrap(); - frame_stream.begin().unwrap(); + let xr_frame_state = frame_wait.wait()?; + frame_stream.begin()?; xr_state.predicted_display_time = xr_frame_state.predicted_display_time; if !xr_frame_state.should_render { - frame_stream - .end( - xr_frame_state.predicted_display_time, - environment_blend_mode, - &[], - ) - .unwrap(); + frame_stream.end( + xr_frame_state.predicted_display_time, + environment_blend_mode, + &[], + )?; continue 'main_loop; } @@ -214,7 +209,7 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { } } - watch_fade(&mut app_state, overlays.mut_by_id(watch_id).unwrap()); + watch_fade(&mut app_state, overlays.mut_by_id(watch_id).unwrap()); // want panic overlays .iter_mut() @@ -225,14 +220,11 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { let _ = sender.send_params(&overlays); }; - let (_, views) = xr_state - .session - .locate_views( - VIEW_TYPE, - xr_frame_state.predicted_display_time, - &xr_state.stage, - ) - .unwrap(); + let (_, views) = xr_state.session.locate_views( + VIEW_TYPE, + xr_frame_state.predicted_display_time, + &xr_state.stage, + )?; app_state.input_state.hmd = helpers::hmd_pose_from_views(&views); @@ -254,7 +246,7 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { } } - let watch = overlays.mut_by_id(watch_id).unwrap(); + let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic let watch_transform = watch.state.transform; if !watch.state.want_visible { watch.state.want_visible = true; @@ -289,12 +281,12 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { continue; } - if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer) { + if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer)? { layers.push((dist_sq, quad)); }; } - for quad in lines.present_xr(&xr_state, &mut command_buffer) { + for quad in lines.present_xr(&xr_state, &mut command_buffer)? { layers.push((0.0, quad)); } @@ -307,17 +299,15 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { .map(|f| &f.1 as &xr::CompositionLayerBase) .collect::>(); - frame_stream - .end( - xr_state.predicted_display_time, - environment_blend_mode, - &frame_ref, - ) - .unwrap(); + frame_stream.end( + xr_state.predicted_display_time, + environment_blend_mode, + &frame_ref, + )?; app_state.hid_provider.on_new_frame(); - let watch = overlays.mut_by_id(watch_id).unwrap(); + let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic watch.state.transform = watch_transform; } diff --git a/src/backend/openxr/overlay.rs b/src/backend/openxr/overlay.rs index 6006fe4..043ded0 100644 --- a/src/backend/openxr/overlay.rs +++ b/src/backend/openxr/overlay.rs @@ -23,7 +23,7 @@ impl OverlayData { &'a mut self, xr: &'a XrState, command_buffer: &mut WlxCommandBuffer, - ) -> Option> { + ) -> anyhow::Result>> { if let Some(new_view) = self.view() { self.data.last_view = Some(new_view); } @@ -32,12 +32,13 @@ impl OverlayData { view.clone() } else { log::warn!("{}: Will not show - image not ready", self.state.name); - return None; + return Ok(None); }; let extent = my_view.image().extent(); let data = self.data.swapchain.get_or_insert_with(|| { - let srd = create_swapchain_render_data(xr, command_buffer.graphics.clone(), extent); + let srd = + create_swapchain_render_data(xr, command_buffer.graphics.clone(), extent).unwrap(); //TODO log::info!( "{}: Created swapchain {}x{}, {} images, {} MB", @@ -50,7 +51,7 @@ impl OverlayData { srd }); - let sub_image = data.acquire_present_release(command_buffer, my_view, self.state.alpha); + let sub_image = data.acquire_present_release(command_buffer, my_view, self.state.alpha)?; let posef = helpers::transform_to_posef(&self.state.transform); let aspect_ratio = extent[1] as f32 / extent[0] as f32; @@ -73,7 +74,7 @@ impl OverlayData { width: scale_x, height: scale_y, }); - Some(quad) + Ok(Some(quad)) } pub(super) fn after_input(&mut self, app: &mut AppState) { diff --git a/src/backend/openxr/swapchain.rs b/src/backend/openxr/swapchain.rs index c87161a..c6ea1ab 100644 --- a/src/backend/openxr/swapchain.rs +++ b/src/backend/openxr/swapchain.rs @@ -17,22 +17,18 @@ pub(super) fn create_swapchain_render_data( xr: &XrState, graphics: Arc, extent: [u32; 3], -) -> SwapchainRenderData { - let swapchain = xr - .session - .create_swapchain(&xr::SwapchainCreateInfo { - create_flags: xr::SwapchainCreateFlags::EMPTY, - usage_flags: xr::SwapchainUsageFlags::COLOR_ATTACHMENT - | xr::SwapchainUsageFlags::SAMPLED, - format: graphics.native_format as _, - sample_count: 1, - width: extent[0], - height: extent[1], - face_count: 1, - array_size: 1, - mip_count: 1, - }) - .unwrap(); +) -> anyhow::Result { + let swapchain = xr.session.create_swapchain(&xr::SwapchainCreateInfo { + create_flags: xr::SwapchainCreateFlags::EMPTY, + usage_flags: xr::SwapchainUsageFlags::COLOR_ATTACHMENT | xr::SwapchainUsageFlags::SAMPLED, + format: graphics.native_format as _, + sample_count: 1, + width: extent[0], + height: extent[1], + face_count: 1, + array_size: 1, + mip_count: 1, + })?; let shaders = graphics.shared_shaders.read().unwrap(); let pipeline = graphics.create_pipeline_dynamic( @@ -58,21 +54,20 @@ pub(super) fn create_swapchain_render_data( usage: ImageUsage::COLOR_ATTACHMENT, ..Default::default() }, - ) - .unwrap() + )? }; // SAFETY: OpenXR guarantees that the image is a swapchain image, thus has memory backing it. let image = Arc::new(unsafe { raw_image.assume_bound() }); - ImageView::new_default(image).unwrap() + Ok(ImageView::new_default(image)?) }) - .collect(); + .collect::; 4]>>>()?; - SwapchainRenderData { + Ok(SwapchainRenderData { swapchain, pipeline, images, extent, - } + }) } pub(super) struct SwapchainRenderData { @@ -88,9 +83,9 @@ impl SwapchainRenderData { command_buffer: &mut WlxCommandBuffer, view: Arc, alpha: f32, - ) -> xr::SwapchainSubImage { - let idx = self.swapchain.acquire_image().unwrap() as usize; - self.swapchain.wait_image(xr::Duration::INFINITE).unwrap(); + ) -> Result, xr::sys::Result> { + let idx = self.swapchain.acquire_image()? as usize; + self.swapchain.wait_image(xr::Duration::INFINITE)?; let render_target = &mut self.images[idx]; command_buffer.begin_rendering(render_target.clone()); @@ -112,9 +107,9 @@ impl SwapchainRenderData { command_buffer.run_ref(&pass); command_buffer.end_rendering(); - self.swapchain.release_image().unwrap(); + self.swapchain.release_image()?; - xr::SwapchainSubImage::new() + Ok(xr::SwapchainSubImage::new() .swapchain(&self.swapchain) .image_rect(xr::Rect2Di { offset: xr::Offset2Di { x: 0, y: 0 }, @@ -123,6 +118,6 @@ impl SwapchainRenderData { height: target_extent[1] as _, }, }) - .image_array_index(0) + .image_array_index(0)) } } diff --git a/src/overlays/keyboard.rs b/src/overlays/keyboard.rs index 22efc28..6967190 100644 --- a/src/overlays/keyboard.rs +++ b/src/overlays/keyboard.rs @@ -52,11 +52,11 @@ where data, ); - canvas.bg_color = color_parse("#101010").unwrap(); + canvas.bg_color = color_parse("#101010").unwrap(); //safe canvas.panel(0., 0., size.x, size.y); canvas.font_size = 18; - canvas.bg_color = color_parse("#202020").unwrap(); + canvas.bg_color = color_parse("#202020").unwrap(); //safe let unit_size = size.x / LAYOUT.row_size; let h = unit_size - 2. * BUTTON_PADDING; diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index c749277..7146e18 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -128,30 +128,32 @@ struct ScreenPipeline { } impl ScreenPipeline { - fn new(extent: &[u32; 3], app: &mut AppState) -> ScreenPipeline { + fn new(extent: &[u32; 3], app: &mut AppState) -> anyhow::Result { let texture = app .graphics .render_texture(extent[0], extent[1], app.graphics.native_format); - let view = ImageView::new_default(texture).unwrap(); + let view = ImageView::new_default(texture)?; - let shaders = app.graphics.shared_shaders.read().unwrap(); + let Ok(shaders) = app.graphics.shared_shaders.read() else { + return Err(anyhow::anyhow!("Could not lock shared shaders for reading")); + }; let pipeline = app.graphics.create_pipeline( view.clone(), - shaders.get("vert_common").unwrap().clone(), - shaders.get("frag_sprite").unwrap().clone(), + shaders.get("vert_common").unwrap().clone(), // want panic + shaders.get("frag_sprite").unwrap().clone(), // want panic app.graphics.native_format, ); let extentf = [extent[0] as f32, extent[1] as f32]; - ScreenPipeline { + Ok(ScreenPipeline { view, mouse: None, pipeline, extentf, - } + }) } fn ensure_mouse_initialized(&mut self, uploads: &mut WlxCommandBuffer) { @@ -272,17 +274,17 @@ impl ScreenRenderer { } #[cfg(feature = "x11")] - pub fn new_xshm(screen: Arc) -> Option { + pub fn new_xshm(screen: Arc) -> ScreenRenderer { let capture = XshmCapture::new(screen.clone()); - Some(ScreenRenderer { + ScreenRenderer { name: screen.name.clone(), capture: Box::new(capture), pipeline: None, receiver: None, last_view: None, extent: extent_from_res((screen.monitor.width(), screen.monitor.height())), - }) + } } } @@ -406,7 +408,7 @@ impl OverlayRenderer for ScreenRenderer { let mut pipeline = None; if mouse.is_some() { let new_pipeline = self.pipeline.get_or_insert_with(|| { - let mut pipeline = ScreenPipeline::new(&self.extent, app); + let mut pipeline = ScreenPipeline::new(&self.extent, app).unwrap(); self.last_view = Some(pipeline.view.clone()); pipeline.ensure_mouse_initialized(&mut upload); pipeline @@ -622,12 +624,12 @@ where } #[cfg(feature = "wayland")] -pub fn get_screens_wayland(session: &AppSession) -> (Vec>, Vec2) +pub fn get_screens_wayland(session: &AppSession) -> anyhow::Result<(Vec>, Vec2)> where O: Default, { let mut overlays = vec![]; - let wl = WlxClient::new().unwrap(); + let wl = WlxClient::new().ok_or_else(|| anyhow::anyhow!("Failed to connect to Wayland"))?; // Load existing Pipewire tokens from file let mut pw_tokens: HashMap = if let Ok(conf) = load_pw_token_config() { @@ -652,7 +654,7 @@ where } let extent = wl.get_desktop_extent(); - (overlays, Vec2::new(extent.0 as f32, extent.1 as f32)) + Ok((overlays, Vec2::new(extent.0 as f32, extent.1 as f32))) } #[cfg(not(feature = "x11"))] @@ -664,13 +666,22 @@ where } #[cfg(feature = "x11")] -pub fn get_screens_x11(session: &AppSession) -> (Vec>, Vec2) +pub fn get_screens_x11(session: &AppSession) -> anyhow::Result<(Vec>, Vec2)> where O: Default, { + use anyhow::bail; + let mut extent = vec2(0., 0.); - let overlays = XshmCapture::get_monitors() + let monitors = match XshmCapture::get_monitors() { + Ok(m) => m, + Err(e) => { + bail!(e.to_string()); + } + }; + + let overlays = monitors .into_iter() .map(|s| { log::info!( @@ -682,7 +693,7 @@ where s.monitor.y() ); let size = (s.monitor.width(), s.monitor.height()); - let capture: ScreenRenderer = ScreenRenderer::new_xshm(s.clone()).unwrap(); + let capture: ScreenRenderer = ScreenRenderer::new_xshm(s.clone()); let backend = Box::new(SplitOverlayBackend { renderer: Box::new(capture), @@ -725,7 +736,7 @@ where }) .collect(); - (overlays, extent) + Ok((overlays, extent)) } fn extent_from_res(res: (i32, i32)) -> [u32; 3] { diff --git a/src/overlays/watch.rs b/src/overlays/watch.rs index ddf4e6d..b8ea3ed 100644 --- a/src/overlays/watch.rs +++ b/src/overlays/watch.rs @@ -338,6 +338,7 @@ fn btn_func_dn( func_right, func_middle, } = control.state.as_ref().unwrap() + // want to panic if state not found else { log::error!("FuncButton state not found"); return; @@ -399,6 +400,7 @@ fn battery_update(control: &mut Control<(), ElemState>, _: &mut (), app: &mut Ap fg_color_low, fg_color_charging, } = control.state.as_ref().unwrap() + // want to panic if state not found else { return; }; @@ -444,6 +446,7 @@ fn exec_button( ref mut child, .. } = control.state.as_mut().unwrap() + // want to panic if state not found else { log::error!("ExecButton state not found"); return; @@ -484,6 +487,7 @@ fn exec_label_update(control: &mut Control<(), ElemState>, _: &mut (), _: &mut A exec, ref mut child, } = control.state.as_mut().unwrap() + // want to panic if state not found else { log::error!("AutoExec state not found"); return; @@ -504,10 +508,9 @@ fn exec_label_update(control: &mut Control<(), ElemState>, _: &mut (), _: &mut A return; } return; - } else { - log::error!("No stdout for child process"); - return; } + log::error!("No stdout for child process"); + return; } } Ok(None) => { @@ -547,6 +550,7 @@ fn exec_label_update(control: &mut Control<(), ElemState>, _: &mut (), _: &mut A } fn clock_update(control: &mut Control<(), ElemState>, _: &mut (), _: &mut AppState) { + // want to panic if state not found let ElemState::Clock { timezone, format } = control.state.as_ref().unwrap() else { log::error!("Clock state not found"); return; @@ -567,6 +571,7 @@ fn overlay_button_scroll( app: &mut AppState, delta: f32, ) { + // want to panic if state not found let ElemState::OverlayButton { overlay, .. } = control.state.as_mut().unwrap() else { log::error!("OverlayButton state not found"); return; @@ -604,6 +609,7 @@ fn overlay_button_dn( ref mut mode, .. } = control.state.as_mut().unwrap() + // want to panic if state not found else { log::error!("OverlayButton state not found"); return; @@ -618,6 +624,7 @@ fn overlay_button_up(control: &mut Control<(), ElemState>, _: &mut (), app: &mut mode, overlay, } = control.state.as_ref().unwrap() + // want to panic if state not found else { log::error!("OverlayButton state not found"); return;