qt-wgpu-skel/ui/src/lib.rs
2026-10-25 14:28:37 +03:00

130 lines
2.7 KiB
Rust

use PROJECT_NAME::{Core, init_gpu_inner};
use glam::UVec2;
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use crate::core::ICoreImpl;
pub use factory::ICoreFactoryImpl;
mod core {
use std::ops::{Deref, DerefMut};
use PROJECT_NAME::{Core, RedrawArgs};
use glam::uvec2;
#[repr(C)]
struct ICoreVTable {
destroy: unsafe extern "C" fn(this: Box<ICoreImpl>),
configure: unsafe extern "C" fn(this: &mut ICoreImpl, width: u32, height: u32),
redraw: unsafe extern "C" fn(this: &mut ICoreImpl, args: &RedrawArgs),
}
unsafe extern "C" fn destroy(this: Box<ICoreImpl>) {
drop(this);
}
unsafe extern "C" fn configure(this: &mut ICoreImpl, width: u32, height: u32) {
this.core.configure(uvec2(width, height));
}
unsafe extern "C" fn redraw(this: &mut ICoreImpl, args: &RedrawArgs) {
this.core.redraw(args);
}
static VTABLE: ICoreVTable = ICoreVTable {
destroy,
configure,
redraw,
};
#[repr(C)]
pub(crate) struct ICoreImpl {
vtable: &'static ICoreVTable,
core: Core,
}
impl ICoreImpl {
pub(crate) fn new(core: Core) -> Box<Self> {
Box::new(ICoreImpl {
vtable: &VTABLE,
core,
})
}
}
impl DerefMut for ICoreImpl {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.core
}
}
impl Deref for ICoreImpl {
type Target = Core;
fn deref(&self) -> &Self::Target {
&self.core
}
}
}
mod factory {
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
use glam::uvec2;
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
use crate::core::ICoreImpl;
#[repr(C)]
struct ICoreFactoryVTable {
new_xcb: unsafe extern "C" fn(
this: &mut ICoreFactoryImpl,
connection: NonNull<c_void>,
window: NonZero<u32>,
width: u32,
height: u32,
) -> Box<ICoreImpl>,
}
unsafe extern "C" fn new_xcb(
_this: &mut ICoreFactoryImpl,
connection: NonNull<c_void>,
window: NonZero<u32>,
width: u32,
height: u32,
) -> Box<ICoreImpl> {
let display = XcbDisplayHandle::new(Some(connection), 0);
let window = XcbWindowHandle::new(window);
unsafe { crate::create_viewport(display, window, uvec2(width, height)) }
}
static VTABLE: ICoreFactoryVTable = ICoreFactoryVTable { new_xcb };
#[repr(C)]
pub struct ICoreFactoryImpl {
vtable: &'static ICoreFactoryVTable,
}
impl ICoreFactoryImpl {
pub fn new() -> Self {
ICoreFactoryImpl { vtable: &VTABLE }
}
}
}
unsafe fn create_viewport(
display: impl Into<RawDisplayHandle>,
window: impl Into<RawWindowHandle>,
size: UVec2,
) -> Box<ICoreImpl> {
let target = wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: display.into(),
raw_window_handle: window.into(),
};
let gpu = pollster::block_on(init_gpu_inner(|instance| unsafe {
instance.create_surface_unsafe(target)
}))
.unwrap();
ICoreImpl::new(Core::new(gpu, size))
}