91 lines
2.9 KiB
Rust
91 lines
2.9 KiB
Rust
use openxr as xr;
|
|
use std::sync::Arc;
|
|
use xr::{CompositionLayerFlags, EyeVisibility};
|
|
|
|
use super::{helpers, swapchain::SwapchainRenderData, XrState};
|
|
use crate::{
|
|
backend::{openxr::swapchain::create_swapchain_render_data, overlay::OverlayData},
|
|
graphics::WlxCommandBuffer,
|
|
state::AppState,
|
|
};
|
|
use vulkano::image::view::ImageView;
|
|
|
|
#[derive(Default)]
|
|
pub struct OpenXrOverlayData {
|
|
last_view: Option<Arc<ImageView>>,
|
|
last_visible: bool,
|
|
pub(super) swapchain: Option<SwapchainRenderData>,
|
|
pub(super) init: bool,
|
|
}
|
|
|
|
impl OverlayData<OpenXrOverlayData> {
|
|
pub(super) fn present_xr<'a>(
|
|
&'a mut self,
|
|
xr: &'a XrState,
|
|
command_buffer: &mut WlxCommandBuffer,
|
|
) -> anyhow::Result<Option<xr::CompositionLayerQuad<xr::Vulkan>>> {
|
|
if let Some(new_view) = self.view() {
|
|
self.data.last_view = Some(new_view);
|
|
}
|
|
|
|
let my_view = if let Some(view) = self.data.last_view.as_ref() {
|
|
view.clone()
|
|
} else {
|
|
log::warn!("{}: Will not show - image not ready", self.state.name);
|
|
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).unwrap(); //TODO
|
|
|
|
log::info!(
|
|
"{}: Created swapchain {}x{}, {} images, {} MB",
|
|
self.state.name,
|
|
extent[0],
|
|
extent[1],
|
|
srd.images.len(),
|
|
extent[0] * extent[1] * 4 * srd.images.len() as u32 / 1024 / 1024
|
|
);
|
|
srd
|
|
});
|
|
|
|
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;
|
|
|
|
let (scale_x, scale_y) = if aspect_ratio < 1.0 {
|
|
let major = self.state.transform.matrix3.col(0).length();
|
|
(major, major * aspect_ratio)
|
|
} else {
|
|
let major = self.state.transform.matrix3.col(1).length();
|
|
(major / aspect_ratio, major)
|
|
};
|
|
|
|
let quad = xr::CompositionLayerQuad::new()
|
|
.pose(posef)
|
|
.sub_image(sub_image)
|
|
.eye_visibility(EyeVisibility::BOTH)
|
|
.layer_flags(CompositionLayerFlags::CORRECT_CHROMATIC_ABERRATION)
|
|
.space(&xr.stage)
|
|
.size(xr::Extent2Df {
|
|
width: scale_x,
|
|
height: scale_y,
|
|
});
|
|
Ok(Some(quad))
|
|
}
|
|
|
|
pub(super) fn after_input(&mut self, app: &mut AppState) {
|
|
if self.data.last_visible != self.state.want_visible {
|
|
if self.state.want_visible {
|
|
self.backend.resume(app);
|
|
} else {
|
|
self.backend.pause(app);
|
|
}
|
|
}
|
|
self.data.last_visible = self.state.want_visible;
|
|
}
|
|
}
|