feat: ui dev window (#29)

* feat: ui dev window

* remove unneeded dep
This commit is contained in:
galister
2024-04-14 07:36:47 +02:00
committed by GitHub
parent 8f9c3f5e3a
commit 5db7524787
10 changed files with 789 additions and 7 deletions

387
Cargo.lock generated
View File

@@ -2,6 +2,22 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ab_glyph"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f90148830dac590fac7ccfe78ec4a8ea404c60f75a24e16407a71f0f40de775"
dependencies = [
"ab_glyph_rasterizer",
"owned_ttf_parser",
]
[[package]]
name = "ab_glyph_rasterizer"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
[[package]]
name = "ahash"
version = "0.8.11"
@@ -45,6 +61,33 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "android-activity"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289"
dependencies = [
"android-properties",
"bitflags 2.5.0",
"cc",
"cesu8",
"jni 0.21.1",
"jni-sys",
"libc",
"log",
"ndk",
"ndk-context",
"ndk-sys",
"num_enum",
"thiserror",
]
[[package]]
name = "android-properties"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
[[package]]
name = "android-tzdata"
version = "0.1.1"
@@ -146,6 +189,24 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "arrayref"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "as-raw-xcb-connection"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
[[package]]
name = "ash"
version = "0.37.3+1.3.251"
@@ -522,6 +583,25 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7"
dependencies = [
"objc-sys",
]
[[package]]
name = "block2"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68"
dependencies = [
"block-sys",
"objc2",
]
[[package]]
name = "blocking"
version = "1.5.1"
@@ -866,6 +946,19 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "core-graphics"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-graphics-types",
"foreign-types",
"libc",
]
[[package]]
name = "core-graphics-types"
version = "0.1.3"
@@ -1112,6 +1205,12 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "dispatch"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "dlib"
version = "0.5.2"
@@ -1318,6 +1417,33 @@ dependencies = [
"yeslogic-fontconfig-sys",
]
[[package]]
name = "foreign-types"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
dependencies = [
"foreign-types-macros",
"foreign-types-shared",
]
[[package]]
name = "foreign-types-macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.58",
]
[[package]]
name = "foreign-types-shared"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@@ -1461,6 +1587,16 @@ dependencies = [
"version_check",
]
[[package]]
name = "gethostname"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
dependencies = [
"libc",
"windows-targets 0.48.5",
]
[[package]]
name = "getrandom"
version = "0.2.14"
@@ -1593,6 +1729,17 @@ dependencies = [
"cc",
]
[[package]]
name = "icrate"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319"
dependencies = [
"block2",
"dispatch",
"objc2",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -1839,6 +1986,17 @@ dependencies = [
"windows-targets 0.52.4",
]
[[package]]
name = "libredox"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
dependencies = [
"bitflags 2.5.0",
"libc",
"redox_syscall 0.4.1",
]
[[package]]
name = "libspa"
version = "0.8.0"
@@ -2013,6 +2171,7 @@ dependencies = [
"log",
"ndk-sys",
"num_enum",
"raw-window-handle",
"thiserror",
]
@@ -2146,6 +2305,28 @@ dependencies = [
"malloc_buf",
]
[[package]]
name = "objc-sys"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459"
[[package]]
name = "objc2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
dependencies = [
"objc-sys",
"objc2-encode",
]
[[package]]
name = "objc2-encode"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
[[package]]
name = "oboe"
version = "0.6.1"
@@ -2197,6 +2378,15 @@ dependencies = [
"libc",
]
[[package]]
name = "orbclient"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
dependencies = [
"libredox",
]
[[package]]
name = "ordered-multimap"
version = "0.6.0"
@@ -2243,6 +2433,15 @@ dependencies = [
"normpath",
]
[[package]]
name = "owned_ttf_parser"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7"
dependencies = [
"ttf-parser",
]
[[package]]
name = "parking"
version = "2.2.0"
@@ -2267,7 +2466,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"redox_syscall 0.4.1",
"smallvec",
"windows-targets 0.48.5",
]
@@ -2586,6 +2785,15 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
@@ -2745,6 +2953,19 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sctk-adwaita"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550"
dependencies = [
"ab_glyph",
"log",
"memmap2 0.9.4",
"smithay-client-toolkit",
"tiny-skia",
]
[[package]]
name = "semver"
version = "1.0.22"
@@ -2928,12 +3149,27 @@ dependencies = [
"xkeysym",
]
[[package]]
name = "smol_str"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49"
dependencies = [
"serde",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strict-num"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
name = "strsim"
version = "0.11.1"
@@ -3076,6 +3312,31 @@ dependencies = [
"crunchy",
]
[[package]]
name = "tiny-skia"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"log",
"tiny-skia-path",
]
[[package]]
name = "tiny-skia-path"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
dependencies = [
"arrayref",
"bytemuck",
"strict-num",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -3167,6 +3428,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "ttf-parser"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
[[package]]
name = "typenum"
version = "1.17.0"
@@ -3464,6 +3731,19 @@ dependencies = [
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-plasma"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
dependencies = [
"bitflags 2.5.0",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-wlr"
version = "0.2.0"
@@ -3496,6 +3776,7 @@ checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af"
dependencies = [
"dlib",
"log",
"once_cell",
"pkg-config",
]
@@ -3509,6 +3790,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "which"
version = "4.4.2"
@@ -3788,6 +4079,54 @@ version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "winit"
version = "0.29.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca"
dependencies = [
"ahash",
"android-activity",
"atomic-waker",
"bitflags 2.5.0",
"bytemuck",
"calloop",
"cfg_aliases",
"core-foundation",
"core-graphics",
"cursor-icon",
"icrate",
"js-sys",
"libc",
"log",
"memmap2 0.9.4",
"ndk",
"ndk-sys",
"objc2",
"once_cell",
"orbclient",
"percent-encoding",
"raw-window-handle",
"redox_syscall 0.3.5",
"rustix",
"sctk-adwaita",
"smithay-client-toolkit",
"smol_str",
"unicode-segmentation",
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-protocols-plasma",
"web-sys",
"web-time",
"windows-sys 0.48.0",
"x11-dl",
"x11rb",
"xkbcommon-dl",
]
[[package]]
name = "winnow"
version = "0.5.40"
@@ -3855,10 +4194,43 @@ dependencies = [
"thiserror",
"vulkano",
"vulkano-shaders",
"winit",
"wlx-capture",
"xdg",
]
[[package]]
name = "x11-dl"
version = "2.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
dependencies = [
"libc",
"once_cell",
"pkg-config",
]
[[package]]
name = "x11rb"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a"
dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
"libloading 0.8.3",
"once_cell",
"rustix",
"x11rb-protocol",
]
[[package]]
name = "x11rb-protocol"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34"
[[package]]
name = "xcb"
version = "1.3.0"
@@ -3903,6 +4275,19 @@ dependencies = [
"xkeysym",
]
[[package]]
name = "xkbcommon-dl"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5"
dependencies = [
"bitflags 2.5.0",
"dlib",
"log",
"once_cell",
"xkeysym",
]
[[package]]
name = "xkeysym"
version = "0.2.0"

View File

@@ -52,6 +52,7 @@ thiserror = "1.0.56"
vulkano = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" }
vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" }
wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.3.8", default-features = false }
winit = { version = "0.29.15", optional = true }
xdg = "2.5.2"
[features]
@@ -61,3 +62,4 @@ openxr = ["dep:openxr"]
osc = ["dep:rosc"]
x11 = ["wlx-capture/xshm"]
wayland = ["wlx-capture/pipewire", "wlx-capture/wlr"]
uidev = ["dep:winit"]

View File

@@ -8,6 +8,9 @@ pub mod openvr;
#[cfg(feature = "openxr")]
pub mod openxr;
#[cfg(feature = "uidev")]
pub mod uidev;
#[cfg(feature = "osc")]
pub mod osc;

241
src/backend/uidev/mod.rs Normal file
View File

@@ -0,0 +1,241 @@
use std::sync::Arc;
use vulkano::{
command_buffer::CommandBufferUsage,
image::{sampler::Filter, view::ImageView, ImageUsage},
swapchain::{
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::GpuFuture,
Validated, VulkanError,
};
use winit::{
dpi::LogicalSize,
event::{Event, WindowEvent},
event_loop::ControlFlow,
window::Window,
};
use crate::{
config::load_custom_ui,
config_io,
graphics::{DynamicPass, DynamicPipeline, WlxGraphics, BLEND_ALPHA},
gui::{
modular::{modular_canvas, ModularData},
Canvas,
},
hid::USE_UINPUT,
state::AppState,
};
use super::overlay::OverlayRenderer;
struct PreviewState {
canvas: Canvas<(), ModularData>,
pipeline: Arc<DynamicPipeline>,
pass: DynamicPass,
swapchain: Arc<Swapchain>,
images: Vec<Arc<ImageView>>,
}
impl PreviewState {
fn new(
state: &mut AppState,
surface: Arc<Surface>,
window: Arc<Window>,
panel_name: &str,
) -> anyhow::Result<Self> {
let config = load_custom_ui(panel_name)?;
let (swapchain, images) = create_swapchain(&state.graphics, surface.clone(), config.size)?;
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);
window.set_min_inner_size(Some(logical_size));
window.set_max_inner_size(Some(logical_size));
window.set_resizable(false);
window.set_title("WlxOverlay UI Preview");
let mut canvas = modular_canvas(&config.size, &config.elements, state)?;
canvas.init(state)?;
canvas.render(state).unwrap();
let view = canvas.view().unwrap();
let extent = view.image().extent();
let pipeline = {
let shaders = state.graphics.shared_shaders.read().unwrap();
state.graphics.create_pipeline_dynamic(
shaders.get("vert_common").unwrap().clone(), // want panic
shaders.get("frag_sprite").unwrap().clone(), // want panic
state.graphics.native_format,
Some(BLEND_ALPHA),
)
}?;
let set0 = pipeline
.uniform_sampler(0, view.clone(), Filter::Linear)
.unwrap();
let pass = pipeline
.create_pass(
[extent[0] as f32, extent[1] as f32],
state.graphics.quad_verts.clone(),
state.graphics.quad_indices.clone(),
vec![set0],
)
.unwrap();
Ok(PreviewState {
canvas,
pipeline,
pass,
swapchain,
images,
})
}
}
pub fn uidev_run(panel_name: &str) -> anyhow::Result<()> {
let (graphics, event_loop, window, surface) = WlxGraphics::new_window()?;
USE_UINPUT.store(false, std::sync::atomic::Ordering::Relaxed);
let mut state = AppState::from_graphics(graphics.clone())?;
let mut preview = Some(PreviewState::new(
&mut state,
surface.clone(),
window.clone(),
panel_name,
)?);
let mut previous_frame_end = Some(vulkano::sync::now(graphics.device.clone()).boxed());
let watch_path = config_io::CONFIG_ROOT_PATH.join(format!("{}.yaml", panel_name));
let mut path_last_modified = watch_path.metadata()?.modified()?;
event_loop.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Poll);
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
elwt.exit();
}
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
previous_frame_end.as_mut().unwrap().cleanup_finished();
let new_modified = watch_path.metadata().unwrap().modified().unwrap();
if new_modified > path_last_modified {
{
let _ = preview.take(); // free swapchain
}
preview = Some(
PreviewState::new(&mut state, surface.clone(), window.clone(), panel_name)
.unwrap(),
);
path_last_modified = new_modified;
}
{
let preview = preview.as_ref().unwrap();
let (image_index, _, acquire_future) =
match acquire_next_image(preview.swapchain.clone(), None)
.map_err(Validated::unwrap)
{
Ok(r) => r,
Err(VulkanError::OutOfDate) => {
elwt.exit();
return;
}
Err(e) => panic!("failed to acquire next image: {e}"),
};
let target = preview.images[image_index as usize].clone();
let mut cmd_buf = state
.graphics
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
.unwrap();
cmd_buf.begin_rendering(target).unwrap();
let _ = cmd_buf.run_ref(&preview.pass);
cmd_buf.end_rendering().unwrap();
let command_buffer = cmd_buf.build().unwrap();
let future = previous_frame_end
.take()
.unwrap()
.join(acquire_future)
.then_execute(graphics.queue.clone(), command_buffer)
.unwrap()
.then_swapchain_present(
graphics.queue.clone(),
SwapchainPresentInfo::swapchain_image_index(
preview.swapchain.clone(),
image_index,
),
)
.then_signal_fence_and_flush();
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(VulkanError::OutOfDate) => {
previous_frame_end =
Some(vulkano::sync::now(state.graphics.device.clone()).boxed());
}
Err(e) => {
println!("failed to flush future: {e}");
previous_frame_end =
Some(vulkano::sync::now(state.graphics.device.clone()).boxed());
}
}
}
}
Event::AboutToWait => window.request_redraw(),
_ => (),
}
})?;
Ok(())
}
fn create_swapchain(
graphics: &WlxGraphics,
surface: Arc<Surface>,
extent: [u32; 2],
) -> anyhow::Result<(Arc<Swapchain>, Vec<Arc<ImageView>>)> {
let surface_capabilities = graphics
.device
.physical_device()
.surface_capabilities(&surface, Default::default())
.unwrap();
let (swapchain, images) = Swapchain::new(
graphics.device.clone(),
surface.clone(),
SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count.max(2),
image_format: graphics.native_format,
image_extent: extent,
image_usage: ImageUsage::COLOR_ATTACHMENT,
composite_alpha: surface_capabilities
.supported_composite_alpha
.into_iter()
.next()
.unwrap(),
..Default::default()
},
)?;
let image_views = images
.into_iter()
.map(|image| ImageView::new_default(image).unwrap())
.collect::<Vec<_>>();
Ok((swapchain, image_views))
}

View File

@@ -490,6 +490,142 @@ impl WlxGraphics {
Ok(Arc::new(me))
}
#[cfg(feature = "uidev")]
pub fn new_window() -> anyhow::Result<(
Arc<Self>,
winit::event_loop::EventLoop<()>,
Arc<winit::window::Window>,
Arc<vulkano::swapchain::Surface>,
)> {
use vulkano::swapchain::Surface;
use winit::{event_loop::EventLoop, window::WindowBuilder};
let event_loop = EventLoop::new().unwrap();
let mut vk_instance_extensions = Surface::required_extensions(&event_loop).unwrap();
vk_instance_extensions.khr_get_physical_device_properties2 = true;
log::debug!("Instance exts for runtime: {:?}", &vk_instance_extensions);
let instance = Instance::new(
get_vulkan_library().clone(),
InstanceCreateInfo {
flags: InstanceCreateFlags::ENUMERATE_PORTABILITY,
enabled_extensions: vk_instance_extensions,
..Default::default()
},
)?;
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone())?;
let device_extensions = DeviceExtensions {
khr_swapchain: true,
khr_external_memory: true,
khr_external_memory_fd: true,
ext_external_memory_dma_buf: true,
ext_image_drm_format_modifier: true,
..DeviceExtensions::empty()
};
log::debug!("Device exts for app: {:?}", &device_extensions);
let (physical_device, my_extensions, queue_family_index) = instance
.enumerate_physical_devices()?
.filter_map(|p| {
if p.supported_extensions().contains(&device_extensions) {
Some((p, device_extensions))
} else {
log::debug!(
"Not using {} because it does not implement the following device extensions:",
p.properties().device_name,
);
for (ext, missing) in p.supported_extensions().difference(&device_extensions) {
if missing {
log::debug!(" {}", ext);
}
}
None
}
})
.filter_map(|(p, my_extensions)| {
p.queue_family_properties()
.iter()
.enumerate()
.position(|(i, q)| q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false))
.map(|i| (p, my_extensions, i as u32))
})
.min_by_key(|(p, _, _)| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,
PhysicalDeviceType::VirtualGpu => 2,
PhysicalDeviceType::Cpu => 3,
PhysicalDeviceType::Other => 4,
_ => 5,
})
.expect("no suitable physical device found");
log::info!(
"Using vkPhysicalDevice: {}",
physical_device.properties().device_name,
);
let (device, mut queues) = Device::new(
physical_device,
DeviceCreateInfo {
enabled_extensions: my_extensions,
enabled_features: Features {
dynamic_rendering: true,
..Features::empty()
},
queue_create_infos: vec![QueueCreateInfo {
queue_family_index,
..Default::default()
}],
..Default::default()
},
)?;
let native_format = device
.physical_device()
.surface_formats(&surface, Default::default())
.unwrap()[0]
.0;
log::info!("Using surface format: {:?}", native_format);
let queue = queues
.next()
.ok_or_else(|| anyhow::anyhow!("no GPU queues available"))?;
let memory_allocator = memory_allocator(device.clone());
let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
device.clone(),
StandardCommandBufferAllocatorCreateInfo {
secondary_buffer_count: 32,
..Default::default()
},
));
let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new(
device.clone(),
Default::default(),
));
let (quad_verts, quad_indices) = Self::default_quad(memory_allocator.clone())?;
let me = Self {
instance,
device,
queue,
memory_allocator,
native_format,
command_buffer_allocator,
descriptor_set_allocator,
quad_indices,
quad_verts,
shared_shaders: RwLock::new(HashMap::new()),
};
Ok((Arc::new(me), event_loop, window, surface))
}
fn default_quad(
memory_allocator: Arc<StandardMemoryAllocator>,
) -> anyhow::Result<(Vert2Buf, IndexBuf)> {

View File

@@ -120,7 +120,7 @@ pub fn modular_canvas(
size[0] as _,
size[1] as _,
state.graphics.clone(),
state.format,
state.graphics.native_format,
(),
)?;
let empty_str: Arc<str> = Arc::from("");

View File

@@ -7,11 +7,18 @@ use input_linux::{
};
use libc::{input_event, timeval};
use once_cell::sync::Lazy;
use std::fs::File;
use std::mem::transmute;
use std::{fs::File, sync::atomic::AtomicBool};
use strum::{EnumIter, EnumString, IntoEnumIterator};
pub static USE_UINPUT: AtomicBool = AtomicBool::new(true);
pub fn initialize() -> Box<dyn HidProvider> {
if !USE_UINPUT.load(std::sync::atomic::Ordering::Relaxed) {
log::info!("Uinput disabled by user.");
return Box::new(DummyProvider {});
}
if let Some(uinput) = UInputProvider::try_new() {
log::info!("Initialized uinput.");
return Box::new(uinput);

View File

@@ -41,6 +41,11 @@ struct Args {
/// Path to write logs to
#[arg(short, long, value_name = "FILE_PATH")]
log_to: Option<String>,
#[cfg(feature = "uidev")]
/// Show a desktop window of a UI panel for development
#[arg(short, long, value_name = "UI_NAME")]
uidev: Option<String>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -60,6 +65,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
return Ok(());
}
#[cfg(feature = "uidev")]
if let Some(panel_name) = args.uidev.as_ref() {
crate::backend::uidev::uidev_run(panel_name.as_str())?;
return Ok(());
}
let running = Arc::new(AtomicBool::new(true));
let _ = ctrlc::set_handler({
let running = running.clone();

View File

@@ -43,7 +43,7 @@ where
size.x as _,
size.y as _,
app.graphics.clone(),
app.format,
app.graphics.native_format,
data,
)?;

View File

@@ -6,7 +6,6 @@ use idmap::IdMap;
use rodio::{Decoder, OutputStream, OutputStreamHandle, Source};
use serde::{Deserialize, Serialize};
use smallvec::{smallvec, SmallVec};
use vulkano::format::Format;
use crate::{
backend::{common::TaskContainer, input::InputState},
@@ -24,7 +23,6 @@ pub struct AppState {
pub session: AppSession,
pub tasks: TaskContainer,
pub graphics: Arc<WlxGraphics>,
pub format: vulkano::format::Format,
pub input_state: InputState,
pub hid_provider: Box<dyn HidProvider>,
pub audio: AudioOutput,
@@ -63,7 +61,6 @@ impl AppState {
session: AppSession::load(),
tasks: TaskContainer::new(),
graphics,
format: Format::R8G8B8A8_UNORM,
input_state: InputState::new(),
hid_provider: crate::hid::initialize(),
audio: AudioOutput::new(),