130 lines
2.7 KiB
Rust
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))
|
|
}
|