fix: ui-dev on xorg (#30)
* fix: ui-dev on xorg * recreate swapchain on resize * only request window size after canvas size change * only redraw after canvas changed * redraw if run_ref failed * redraw at 1s interval
This commit is contained in:
@@ -30,6 +30,8 @@ use crate::{
|
|||||||
|
|
||||||
use super::overlay::OverlayRenderer;
|
use super::overlay::OverlayRenderer;
|
||||||
|
|
||||||
|
static LAST_SIZE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||||
|
|
||||||
struct PreviewState {
|
struct PreviewState {
|
||||||
canvas: Canvas<(), ModularData>,
|
canvas: Canvas<(), ModularData>,
|
||||||
pipeline: Arc<DynamicPipeline>,
|
pipeline: Arc<DynamicPipeline>,
|
||||||
@@ -46,21 +48,32 @@ impl PreviewState {
|
|||||||
panel_name: &str,
|
panel_name: &str,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let config = load_custom_ui(panel_name)?;
|
let config = load_custom_ui(panel_name)?;
|
||||||
let (swapchain, images) = create_swapchain(&state.graphics, surface.clone(), config.size)?;
|
|
||||||
|
|
||||||
|
let last_size = {
|
||||||
|
let size_u64 = LAST_SIZE.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
|
[size_u64 as u32, (size_u64 >> 32) as u32]
|
||||||
|
};
|
||||||
|
|
||||||
|
if last_size != config.size {
|
||||||
let logical_size = LogicalSize::new(config.size[0], config.size[1]);
|
let logical_size = LogicalSize::new(config.size[0], config.size[1]);
|
||||||
log::info!("Setting window size to {:?}", logical_size);
|
|
||||||
let _ = window.request_inner_size(logical_size);
|
let _ = window.request_inner_size(logical_size);
|
||||||
window.set_min_inner_size(Some(logical_size));
|
window.set_min_inner_size(Some(logical_size));
|
||||||
window.set_max_inner_size(Some(logical_size));
|
window.set_max_inner_size(Some(logical_size));
|
||||||
window.set_resizable(false);
|
LAST_SIZE.store(
|
||||||
window.set_title("WlxOverlay UI Preview");
|
(config.size[1] as u64) << 32 | config.size[0] as u64,
|
||||||
|
std::sync::atomic::Ordering::Relaxed,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let inner_size = window.inner_size();
|
||||||
|
let swapchain_size = [inner_size.width, inner_size.height];
|
||||||
|
let (swapchain, images) =
|
||||||
|
create_swapchain(&state.graphics, surface.clone(), swapchain_size)?;
|
||||||
|
|
||||||
let mut canvas = modular_canvas(&config.size, &config.elements, state)?;
|
let mut canvas = modular_canvas(&config.size, &config.elements, state)?;
|
||||||
canvas.init(state)?;
|
canvas.init(state)?;
|
||||||
canvas.render(state).unwrap();
|
canvas.render(state).unwrap();
|
||||||
let view = canvas.view().unwrap();
|
let view = canvas.view().unwrap();
|
||||||
let extent = view.image().extent();
|
|
||||||
|
|
||||||
let pipeline = {
|
let pipeline = {
|
||||||
let shaders = state.graphics.shared_shaders.read().unwrap();
|
let shaders = state.graphics.shared_shaders.read().unwrap();
|
||||||
@@ -77,7 +90,7 @@ impl PreviewState {
|
|||||||
|
|
||||||
let pass = pipeline
|
let pass = pipeline
|
||||||
.create_pass(
|
.create_pass(
|
||||||
[extent[0] as f32, extent[1] as f32],
|
[swapchain_size[0] as f32, swapchain_size[1] as f32],
|
||||||
state.graphics.quad_verts.clone(),
|
state.graphics.quad_verts.clone(),
|
||||||
state.graphics.quad_indices.clone(),
|
state.graphics.quad_indices.clone(),
|
||||||
vec![set0],
|
vec![set0],
|
||||||
@@ -96,6 +109,8 @@ impl PreviewState {
|
|||||||
|
|
||||||
pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
||||||
let (graphics, event_loop, window, surface) = WlxGraphics::new_window()?;
|
let (graphics, event_loop, window, surface) = WlxGraphics::new_window()?;
|
||||||
|
window.set_resizable(false);
|
||||||
|
window.set_title("WlxOverlay UI Preview");
|
||||||
|
|
||||||
USE_UINPUT.store(false, std::sync::atomic::Ordering::Relaxed);
|
USE_UINPUT.store(false, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
|
||||||
@@ -110,6 +125,8 @@ pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let watch_path = config_io::CONFIG_ROOT_PATH.join(format!("{}.yaml", panel_name));
|
let watch_path = config_io::CONFIG_ROOT_PATH.join(format!("{}.yaml", panel_name));
|
||||||
let mut path_last_modified = watch_path.metadata()?.modified()?;
|
let mut path_last_modified = watch_path.metadata()?.modified()?;
|
||||||
|
let mut recreate = false;
|
||||||
|
let mut last_draw = std::time::Instant::now();
|
||||||
|
|
||||||
event_loop.run(move |event, elwt| {
|
event_loop.run(move |event, elwt| {
|
||||||
elwt.set_control_flow(ControlFlow::Poll);
|
elwt.set_control_flow(ControlFlow::Poll);
|
||||||
@@ -121,6 +138,12 @@ pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
|||||||
} => {
|
} => {
|
||||||
elwt.exit();
|
elwt.exit();
|
||||||
}
|
}
|
||||||
|
Event::WindowEvent {
|
||||||
|
event: WindowEvent::Resized(_),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
recreate = true;
|
||||||
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::RedrawRequested,
|
event: WindowEvent::RedrawRequested,
|
||||||
..
|
..
|
||||||
@@ -129,26 +152,29 @@ pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let new_modified = watch_path.metadata().unwrap().modified().unwrap();
|
let new_modified = watch_path.metadata().unwrap().modified().unwrap();
|
||||||
if new_modified > path_last_modified {
|
if new_modified > path_last_modified {
|
||||||
{
|
recreate = true;
|
||||||
let _ = preview.take(); // free swapchain
|
path_last_modified = new_modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if recreate {
|
||||||
|
drop(preview.take());
|
||||||
preview = Some(
|
preview = Some(
|
||||||
PreviewState::new(&mut state, surface.clone(), window.clone(), panel_name)
|
PreviewState::new(&mut state, surface.clone(), window.clone(), panel_name)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
path_last_modified = new_modified;
|
recreate = false;
|
||||||
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let preview = preview.as_ref().unwrap();
|
let preview = preview.as_ref().unwrap();
|
||||||
|
|
||||||
let (image_index, _, acquire_future) =
|
let (image_index, _, acquire_future) =
|
||||||
match acquire_next_image(preview.swapchain.clone(), None)
|
match acquire_next_image(preview.swapchain.clone(), None)
|
||||||
.map_err(Validated::unwrap)
|
.map_err(Validated::unwrap)
|
||||||
{
|
{
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(VulkanError::OutOfDate) => {
|
Err(VulkanError::OutOfDate) => {
|
||||||
elwt.exit();
|
recreate = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(e) => panic!("failed to acquire next image: {e}"),
|
Err(e) => panic!("failed to acquire next image: {e}"),
|
||||||
@@ -161,8 +187,11 @@ pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
|||||||
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
cmd_buf.begin_rendering(target).unwrap();
|
cmd_buf.begin_rendering(target).unwrap();
|
||||||
let _ = cmd_buf.run_ref(&preview.pass);
|
if cmd_buf.run_ref(&preview.pass).is_err() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
cmd_buf.end_rendering().unwrap();
|
cmd_buf.end_rendering().unwrap();
|
||||||
|
last_draw = std::time::Instant::now();
|
||||||
|
|
||||||
let command_buffer = cmd_buf.build().unwrap();
|
let command_buffer = cmd_buf.build().unwrap();
|
||||||
let future = previous_frame_end
|
let future = previous_frame_end
|
||||||
@@ -196,7 +225,11 @@ pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::AboutToWait => window.request_redraw(),
|
Event::AboutToWait => {
|
||||||
|
if last_draw.elapsed().as_secs() > 1 {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
Reference in New Issue
Block a user