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